creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "lib/rain.flow/lib/rain.interpreter/src/concrete/RainterpreterNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity =0.8.19;\n\nimport \"openzeppelin-contracts/contracts/utils/introspection/ERC165.sol\";\n\nimport \"rain.lib.typecast/LibCast.sol\";\nimport {LibDataContract} from \"rain.datacontract/lib/LibDataContract.sol\";\n\nimport \"../interface/unstable/IDebugInterpreterV2.sol\";\n\nimport {LibEvalNP} from \"../lib/eval/LibEvalNP.sol\";\nimport \"../lib/ns/LibNamespace.sol\";\nimport {LibInterpreterStateDataContractNP} from \"../lib/state/LibInterpreterStateDataContractNP.sol\";\nimport \"../lib/caller/LibEncodedDispatch.sol\";\n\nimport {InterpreterStateNP} from \"../lib/state/LibInterpreterStateNP.sol\";\nimport {LibAllStandardOpsNP} from \"../lib/op/LibAllStandardOpsNP.sol\";\nimport {LibPointer, Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {LibStackPointer} from \"rain.solmem/lib/LibStackPointer.sol\";\nimport {LibUint256Array} from \"rain.solmem/lib/LibUint256Array.sol\";\nimport {LibMemoryKV, MemoryKV} from \"rain.lib.memkv/lib/LibMemoryKV.sol\";\n\n/// Thrown when the stack length is negative during eval.\nerror NegativeStackLength(int256 length);\n\n/// Thrown when the source index is invalid during eval. This is a runtime check\n/// for the exposed external eval entrypoint. Internally recursive evals are\n/// expected to preflight check the source index.\nerror InvalidSourceIndex(SourceIndex sourceIndex);\n\n/// @dev Hash of the known interpreter bytecode.\nbytes32 constant INTERPRETER_BYTECODE_HASH = bytes32(0x21785780ab522520aaf1921d5a177b745aa7179c67305ed963c709e79bdfbe0d);\n\n/// @dev The function pointers known to the interpreter for dynamic dispatch.\n/// By setting these as a constant they can be inlined into the interpreter\n/// and loaded at eval time for very low gas (~100) due to the compiler\n/// optimising it to a single `codecopy` to build the in memory bytes array.\nbytes constant OPCODE_FUNCTION_POINTERS =\n    hex\"0d090d550d900da90e470f2b0f65101510b710e6111511151164119311f5127d13241338138e13a213b713d113dc13f01405148214cd14f3150a15211521156c15b716021602164d164d169816e3172e172e17791860189318ea\";\n\n/// @title RainterpreterNP\n/// @notice !!EXPERIMENTAL!! implementation of a Rainlang interpreter that is\n/// compatible with native onchain Rainlang parsing. Initially copied verbatim\n/// from the JS compatible Rainterpreter. This interpreter is deliberately\n/// separate from the JS Rainterpreter to allow for experimentation with the\n/// onchain interpreter without affecting the JS interpreter, up to and including\n/// a complely different execution model and opcodes.\ncontract RainterpreterNP is IInterpreterV1, IDebugInterpreterV2, ERC165 {\n    using LibEvalNP for InterpreterStateNP;\n    using LibNamespace for StateNamespace;\n    using LibInterpreterStateDataContractNP for bytes;\n\n    /// There are MANY ways that eval can be forced into undefined/corrupt\n    /// behaviour by passing in invalid data. This is a deliberate design\n    /// decision to allow for the interpreter to be as gas efficient as\n    /// possible. The interpreter is provably read only, it contains no state\n    /// changing evm opcodes reachable on any logic path. This means that\n    /// the caller can only harm themselves by passing in invalid data and\n    /// either reverting, exhausting gas or getting back some garbage data.\n    /// The caller can trivially protect themselves from these OOB issues by\n    /// ensuring the integrity check has successfully run over the bytecode\n    /// before calling eval. Any smart contract caller can do this by using a\n    /// trusted and appropriate deployer contract to deploy the bytecode, which\n    /// will automatically run the integrity check during deployment, then\n    /// keeping a registry of trusted expression addresses for itself in storage.\n    ///\n    /// This appears first in the contract in the hope that the compiler will\n    /// put it in the most efficient internal dispatch location to save a few\n    /// gas per eval call.\n    ///\n    /// @inheritdoc IInterpreterV1\n    function eval(\n        IInterpreterStoreV1 store,\n        StateNamespace namespace,\n        EncodedDispatch dispatch,\n        uint256[][] memory context\n    ) external view returns (uint256[] memory, uint256[] memory) {\n        // Decode the dispatch.\n        (address expression, SourceIndex sourceIndex16, uint256 maxOutputs) = LibEncodedDispatch.decode(dispatch);\n        bytes memory expressionData = LibDataContract.read(expression);\n\n        // Need to clean source index as it is a uint16.\n        uint256 sourceIndex;\n        assembly (\"memory-safe\") {\n            sourceIndex := and(sourceIndex16, 0xFFFF)\n        }\n\n        InterpreterStateNP memory state = expressionData.unsafeDeserializeNP(\n            sourceIndex, namespace.qualifyNamespace(msg.sender), store, context, OPCODE_FUNCTION_POINTERS\n        );\n        // We use the return by returning it. Slither false positive.\n        //slither-disable-next-line unused-return\n        return state.evalNP(new uint256[](0), maxOutputs);\n    }\n\n    // @inheritdoc ERC165\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IInterpreterV1).interfaceId || interfaceId == type(IDebugInterpreterV2).interfaceId\n            || super.supportsInterface(interfaceId);\n    }\n\n    /// @inheritdoc IDebugInterpreterV2\n    function offchainDebugEval(\n        IInterpreterStoreV1 store,\n        FullyQualifiedNamespace namespace,\n        bytes memory expressionData,\n        SourceIndex sourceIndex16,\n        uint256 maxOutputs,\n        uint256[][] memory context,\n        uint256[] memory inputs\n    ) external view returns (uint256[] memory, uint256[] memory) {\n        // Need to clean source index as it is a uint16.\n        uint256 sourceIndex;\n        assembly (\"memory-safe\") {\n            sourceIndex := and(sourceIndex16, 0xFFFF)\n        }\n        InterpreterStateNP memory state =\n            expressionData.unsafeDeserializeNP(sourceIndex, namespace, store, context, OPCODE_FUNCTION_POINTERS);\n        // We use the return by returning it. Slither false positive.\n        //slither-disable-next-line unused-return\n        return state.evalNP(inputs, maxOutputs);\n    }\n\n    /// @inheritdoc IInterpreterV1\n    function functionPointers() external view virtual returns (bytes memory) {\n        return LibAllStandardOpsNP.opcodeFunctionPointers();\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.factory/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/rain.lib.typecast/src/LibCast.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// @title LibCast\n/// @notice Additional type casting logic that the Solidity compiler doesn't\n/// give us by default. A type cast (vs. conversion) is considered one where the\n/// structure is unchanged by the cast. The cast does NOT (can't) check that the\n/// input is a valid output, for example any integer MAY be cast to a function\n/// pointer but almost all integers are NOT valid function pointers. It is the\n/// calling context that MUST ensure the validity of the data, the cast will\n/// merely retype the data in place, generally without additional checks.\n/// As most structures in solidity have the same memory structure as a `uint256`\n/// or fixed/dynamic array of `uint256` there are many conversions that can be\n/// done with near zero or minimal overhead.\nlibrary LibCast {\n    /// Retype an array of `uint256[]` to `address[]`.\n    /// @param us_ The array of integers to cast to addresses.\n    /// @return addresses_ The array of addresses cast from each integer.\n    function asAddressesArray(uint256[] memory us_) internal pure returns (address[] memory addresses_) {\n        assembly (\"memory-safe\") {\n            addresses_ := us_\n        }\n    }\n\n    function asUint256Array(address[] memory addresses_) internal pure returns (uint256[] memory us_) {\n        assembly (\"memory-safe\") {\n            us_ := addresses_\n        }\n    }\n\n    /// Retype an array of `uint256[]` to `bytes32[]`.\n    /// @param us_ The array of integers to cast to 32 byte words.\n    /// @return b32s_ The array of 32 byte words.\n    function asBytes32Array(uint256[] memory us_) internal pure returns (bytes32[] memory b32s_) {\n        assembly (\"memory-safe\") {\n            b32s_ := us_\n        }\n    }\n\n    function asUint256Array(bytes32[] memory b32s_) internal pure returns (uint256[] memory us_) {\n        assembly (\"memory-safe\") {\n            us_ := b32s_\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/rain.datacontract/src/lib/LibDataContract.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"rain.solmem/lib/LibPointer.sol\";\n\n/// Thrown if writing the data by creating the contract fails somehow.\nerror WriteError();\n\n/// Thrown if reading a zero length address.\nerror ReadError();\n\n/// @dev SSTORE2 Verbatim reference\n/// https://github.com/0xsequence/sstore2/blob/master/contracts/utils/Bytecode.sol#L15\n///\n/// 0x00    0x63         0x63XXXXXX  PUSH4 _code.length  size\n/// 0x01    0x80         0x80        DUP1                size size\n/// 0x02    0x60         0x600e      PUSH1 14            14 size size\n/// 0x03    0x60         0x6000      PUSH1 00            0 14 size size\n/// 0x04    0x39         0x39        CODECOPY            size\n/// 0x05    0x60         0x6000      PUSH1 00            0 size\n/// 0x06    0xf3         0xf3        RETURN\n/// <CODE>\n///\n/// However note that 00 is also prepended (although docs say append) so there's\n/// an additional byte that isn't described above.\n/// https://github.com/0xsequence/sstore2/blob/master/contracts/SSTORE2.sol#L25\n///\n/// Note also typo 0x63XXXXXX which indicates 3 bytes but instead 4 are used as\n/// 0x64XXXXXXXX.\n///\n/// Note also that we don't need 4 bytes to represent the size of a contract as\n/// 24kb is the max PUSH2 (0x61) can be used instead of PUSH4 for code length.\n/// This also changes the 0x600e to 0x600c as we've reduced prefix size by 2\n/// relative to reference implementation.\n/// https://github.com/0xsequence/sstore2/pull/5/files\nuint256 constant BASE_PREFIX = 0x61_0000_80_600C_6000_39_6000_F3_00_00000000000000000000000000000000000000;\n\n/// @dev Length of the prefix that converts in memory data to a deployable\n/// contract.\nuint256 constant PREFIX_BYTES_LENGTH = 13;\n\n/// A container is a region of memory that is directly deployable with `create`,\n/// without length prefixes or other Solidity type trappings. Where the length is\n/// needed, such as in `write` it can be read as bytes `[1,2]` from the prefix.\n/// This is just a pointer but given a new type to help avoid mistakes.\ntype DataContractMemoryContainer is uint256;\n\n/// @title DataContract\n///\n/// DataContract is a simplified reimplementation of\n/// https://github.com/0xsequence/sstore2\n///\n/// - Doesn't force additonal internal allocations with ABI encoding calls\n/// - Optimised for the case where the data to read/write and contract are 1:1\n/// - Assembly optimisations for less gas usage\n/// - Not shipped with other unrelated code to reduce dependency bloat\n/// - Fuzzed with foundry\n///\n/// It is a little more low level in that it doesn't work on `bytes` from\n/// Solidity but instead requires the caller to copy memory directy by pointer.\n/// https://github.com/rainprotocol/sol.lib.bytes can help with that.\nlibrary LibDataContract {\n    /// Prepares a container ready to write exactly `length_` bytes at the\n    /// returned `pointer_`. The caller MUST write exactly the number of bytes\n    /// that it asks for at the pointer otherwise memory WILL be corrupted.\n    /// @param length_ Caller specifies the number of bytes to allocate for the\n    /// data it wants to write. The actual size of the container in memory will\n    /// be larger than this due to the contract creation prefix and the padding\n    /// potentially required to align the memory allocation.\n    /// @return container_ The pointer to the start of the container that can be\n    /// deployed as an onchain contract. Caller can pass this back to `write` to\n    /// have the data contract deployed\n    /// (after it copies its data to the pointer).\n    /// @return pointer_ The caller can copy its data at the pointer without any\n    /// additional allocations or Solidity type wrangling.\n    function newContainer(uint256 length_)\n        internal\n        pure\n        returns (DataContractMemoryContainer container_, Pointer pointer_)\n    {\n        unchecked {\n            uint256 prefixBytesLength_ = PREFIX_BYTES_LENGTH;\n            uint256 basePrefix_ = BASE_PREFIX;\n            assembly (\"memory-safe\") {\n                // allocate output byte array - this could also be done without assembly\n                // by using container_ = new bytes(size)\n                container_ := mload(0x40)\n                // new \"memory end\" including padding\n                mstore(0x40, add(container_, and(add(add(length_, prefixBytesLength_), 0x1f), not(0x1f))))\n                // pointer is where the caller will write data to\n                pointer_ := add(container_, prefixBytesLength_)\n\n                // copy length into the 2 bytes gap in the base prefix\n                let prefix_ :=\n                    or(\n                        basePrefix_,\n                        shl(\n                            // length sits 29 bytes from the right\n                            232,\n                            and(\n                                // mask the length to 2 bytes\n                                0xFFFF,\n                                add(length_, 1)\n                            )\n                        )\n                    )\n                mstore(container_, prefix_)\n            }\n        }\n    }\n\n    /// Given a container prepared by `newContainer` and populated with bytes by\n    /// the caller, deploy to a new onchain contract and return the contract\n    /// address.\n    /// @param container_ The container full of data to deploy as an onchain data\n    /// contract.\n    /// @return The newly deployed contract containing the data in the container.\n    function write(DataContractMemoryContainer container_) internal returns (address) {\n        address pointer_;\n        uint256 prefixLength_ = PREFIX_BYTES_LENGTH;\n        assembly (\"memory-safe\") {\n            pointer_ :=\n                create(\n                    0,\n                    container_,\n                    add(\n                        prefixLength_,\n                        // Read length out of prefix.\n                        and(0xFFFF, shr(232, mload(container_)))\n                    )\n                )\n        }\n        // Zero address means create failed.\n        if (pointer_ == address(0)) revert WriteError();\n        return pointer_;\n    }\n\n    /// Reads data back from a previously deployed container.\n    /// Almost verbatim Solidity docs.\n    /// https://docs.soliditylang.org/en/v0.8.17/assembly.html#example\n    /// Notable difference is that we skip the first byte when we read as it is\n    /// a `0x00` prefix injected by containers on deploy.\n    /// @param pointer_ The address of the data contract to read from. MUST have\n    /// a leading byte that can be safely ignored.\n    /// @return data_ The data read from the data contract. First byte is skipped\n    /// and contract is read completely to the end.\n    function read(address pointer_) internal view returns (bytes memory data_) {\n        uint256 size_;\n        assembly (\"memory-safe\") {\n            // Retrieve the size of the code, this needs assembly.\n            size_ := extcodesize(pointer_)\n        }\n        if (size_ == 0) revert ReadError();\n        assembly (\"memory-safe\") {\n            // Skip the first byte.\n            size_ := sub(size_, 1)\n            // Allocate output byte array - this could also be done without\n            // assembly by using data_ = new bytes(size)\n            data_ := mload(0x40)\n            // New \"memory end\" including padding.\n            // Compiler will optimise away the double constant addition.\n            mstore(0x40, add(data_, and(add(add(size_, 0x20), 0x1f), not(0x1f))))\n            // Store length in memory.\n            mstore(data_, size_)\n            // actually retrieve the code, this needs assembly\n            // skip the first byte\n            extcodecopy(pointer_, add(data_, 0x20), 1, size_)\n        }\n    }\n\n    /// Hybrid of address-only read, SSTORE2 read and Solidity docs.\n    /// Unlike SSTORE2, reading past the end of the data contract WILL REVERT.\n    /// @param pointer_ As per `read`.\n    /// @param start_ Starting offset for reads from the data contract.\n    /// @param length_ Number of bytes to read.\n    function readSlice(address pointer_, uint16 start_, uint16 length_) internal view returns (bytes memory data_) {\n        uint256 size_;\n        // uint256 offset and end avoids overflow issues from uint16.\n        uint256 offset_;\n        uint256 end_;\n        assembly (\"memory-safe\") {\n            // Skip the first byte.\n            offset_ := add(start_, 1)\n            end_ := add(offset_, length_)\n            // Retrieve the size of the code, this needs assembly.\n            size_ := extcodesize(pointer_)\n        }\n        if (size_ < end_) revert ReadError();\n        assembly (\"memory-safe\") {\n            // Allocate output byte array - this could also be done without\n            // assembly by using data_ = new bytes(size)\n            data_ := mload(0x40)\n            // New \"memory end\" including padding.\n            // Compiler will optimise away the double constant addition.\n            mstore(0x40, add(data_, and(add(add(length_, 0x20), 0x1f), not(0x1f))))\n            // Store length in memory.\n            mstore(data_, length_)\n            // actually retrieve the code, this needs assembly\n            extcodecopy(pointer_, add(data_, 0x20), offset_, length_)\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/interface/unstable/IDebugInterpreterV2.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"../IInterpreterV1.sol\";\n\ninterface IDebugInterpreterV2 {\n    /// A more explicit/open version of `eval` that is designed for offchain\n    /// debugging. It MUST function identically to `eval` so implementations\n    /// MAY call it directly internally for `eval` to ensure consistency at the\n    /// expense of a small amount of gas.\n    /// The affordances made for debugging are:\n    /// - A fully qualified namespace is passed in. This allows for storage reads\n    ///   from the perspective of an arbitrary caller during `eval`. Note that it\n    ///   does not allow for arbitrary writes, which are still gated by the store\n    ///   contract itself, so this is safe to expose.\n    /// - The bytecode is passed in directly. This allows for debugging of\n    ///   bytecode that has not been deployed to the chain yet.\n    /// - The components of the encoded dispatch other than the onchain\n    ///   expression address are passed separately. This remove the need to\n    ///   provide an address at all.\n    /// - Inputs to the entrypoint stack are passed in directly. This allows for\n    ///   debugging/simulating logic that could normally only be accessed via.\n    ///   some internal dispatch with a mid-flight state creating inputs for the\n    ///   internal call.\n    function offchainDebugEval(\n        IInterpreterStoreV1 store,\n        FullyQualifiedNamespace namespace,\n        bytes calldata expressionData,\n        SourceIndex sourceIndex,\n        uint256 maxOutputs,\n        uint256[][] calldata context,\n        uint256[] calldata inputs\n    ) external view returns (uint256[] calldata finalStack, uint256[] calldata writes);\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/eval/LibEvalNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"../state/LibInterpreterStateNP.sol\";\n\nimport \"rain.solmem/lib/LibMemCpy.sol\";\nimport \"rain.lib.memkv/lib/LibMemoryKV.sol\";\nimport \"../bytecode/LibBytecode.sol\";\n\n/// Thrown when the inputs length does not match the expected inputs length.\n/// @param expected The expected number of inputs.\n/// @param actual The actual number of inputs.\nerror InputsLengthMismatch(uint256 expected, uint256 actual);\n\nlibrary LibEvalNP {\n    using LibMemoryKV for MemoryKV;\n\n    function evalLoopNP(InterpreterStateNP memory state, Pointer stackTop) internal view returns (Pointer) {\n        uint256 sourceIndex = state.sourceIndex;\n        uint256 cursor;\n        uint256 end;\n        uint256 m;\n        uint256 fPointersStart;\n        // We mod the indexes with the fsCount for each lookup to ensure that\n        // the indexes are in bounds. A mod is cheaper than a bounds check.\n        uint256 fsCount = state.fs.length / 2;\n        {\n            bytes memory bytecode = state.bytecode;\n            bytes memory fPointers = state.fs;\n            assembly (\"memory-safe\") {\n                // SourceIndex is a uint16 so needs cleaning.\n                sourceIndex := and(sourceIndex, 0xFFFF)\n                // Cursor starts at the beginning of the source.\n                cursor := add(bytecode, 0x20)\n                let sourcesLength := byte(0, mload(cursor))\n                cursor := add(cursor, 1)\n                // Find start of sources.\n                let sourcesStart := add(cursor, mul(sourcesLength, 2))\n                // Find relative pointer to source.\n                let sourcesPointer := shr(0xf0, mload(add(cursor, mul(sourceIndex, 2))))\n                // Move cursor to start of source.\n                cursor := add(sourcesStart, sourcesPointer)\n                // Calculate the end.\n                let opsLength := byte(0, mload(cursor))\n                // Move cursor past 4 byte source prefix.\n                cursor := add(cursor, 4)\n\n                // Calculate the mod `m` which is the portion of the source\n                // that can't be copied in 32 byte chunks.\n                m := mod(opsLength, 8)\n\n                // Each op is 4 bytes, and there's a 4 byte prefix for the\n                // source. The initial end is only what can be processed in\n                // 32 byte chunks.\n                end := add(cursor, mul(sub(opsLength, m), 4))\n\n                fPointersStart := add(fPointers, 0x20)\n            }\n        }\n\n        function(InterpreterStateNP memory, Operand, Pointer)\n                    internal\n                    view\n                    returns (Pointer) f;\n        Operand operand;\n        uint256 word;\n        while (cursor < end) {\n            assembly (\"memory-safe\") {\n                word := mload(cursor)\n            }\n\n            // Process high bytes [28, 31]\n            // f needs to be looked up from the fn pointers table.\n            // operand is 3 bytes.\n            assembly (\"memory-safe\") {\n                f := shr(0xf0, mload(add(fPointersStart, mul(mod(byte(0, word), fsCount), 2))))\n                operand := and(shr(0xe0, word), 0xFFFFFF)\n            }\n            stackTop = f(state, operand, stackTop);\n\n            // Bytes [24, 27].\n            assembly (\"memory-safe\") {\n                f := shr(0xf0, mload(add(fPointersStart, mul(mod(byte(4, word), fsCount), 2))))\n                operand := and(shr(0xc0, word), 0xFFFFFF)\n            }\n            stackTop = f(state, operand, stackTop);\n\n            // Bytes [20, 23].\n            assembly (\"memory-safe\") {\n                f := shr(0xf0, mload(add(fPointersStart, mul(mod(byte(8, word), fsCount), 2))))\n                operand := and(shr(0xa0, word), 0xFFFFFF)\n            }\n            stackTop = f(state, operand, stackTop);\n\n            // Bytes [16, 19].\n            assembly (\"memory-safe\") {\n                f := shr(0xf0, mload(add(fPointersStart, mul(mod(byte(12, word), fsCount), 2))))\n                operand := and(shr(0x80, word), 0xFFFFFF)\n            }\n            stackTop = f(state, operand, stackTop);\n\n            // Bytes [12, 15].\n            assembly (\"memory-safe\") {\n                f := shr(0xf0, mload(add(fPointersStart, mul(mod(byte(16, word), fsCount), 2))))\n                operand := and(shr(0x60, word), 0xFFFFFF)\n            }\n            stackTop = f(state, operand, stackTop);\n\n            // Bytes [8, 11].\n            assembly (\"memory-safe\") {\n                f := shr(0xf0, mload(add(fPointersStart, mul(mod(byte(20, word), fsCount), 2))))\n                operand := and(shr(0x40, word), 0xFFFFFF)\n            }\n            stackTop = f(state, operand, stackTop);\n\n            // Bytes [4, 7].\n            assembly (\"memory-safe\") {\n                f := shr(0xf0, mload(add(fPointersStart, mul(mod(byte(24, word), fsCount), 2))))\n                operand := and(shr(0x20, word), 0xFFFFFF)\n            }\n            stackTop = f(state, operand, stackTop);\n\n            // Bytes [0, 3].\n            assembly (\"memory-safe\") {\n                f := shr(0xf0, mload(add(fPointersStart, mul(mod(byte(28, word), fsCount), 2))))\n                operand := and(word, 0xFFFFFF)\n            }\n            stackTop = f(state, operand, stackTop);\n\n            cursor += 0x20;\n        }\n\n        // Loop over the remainder.\n        // Need to shift the cursor back 28 bytes so that we're reading from\n        // its 4 low bits rather than high bits, to make the loop logic more\n        // efficient.\n        cursor -= 0x1c;\n        end = cursor + m * 4;\n        while (cursor < end) {\n            assembly (\"memory-safe\") {\n                word := mload(cursor)\n                f := shr(0xf0, mload(add(fPointersStart, mul(mod(byte(28, word), fsCount), 2))))\n                // 3 bytes mask.\n                operand := and(word, 0xFFFFFF)\n            }\n            stackTop = f(state, operand, stackTop);\n            cursor += 4;\n        }\n\n        return stackTop;\n    }\n\n    function evalNP(InterpreterStateNP memory state, uint256[] memory inputs, uint256 maxOutputs)\n        internal\n        view\n        returns (uint256[] memory, uint256[] memory)\n    {\n        unchecked {\n            // Use the bytecode's own definition of its IO. Clear example of\n            // how the bytecode could accidentally or maliciously force OOB reads\n            // if the integrity check is not run.\n            (uint256 sourceInputs, uint256 sourceOutputs) =\n                LibBytecode.sourceInputsOutputsLength(state.bytecode, state.sourceIndex);\n\n            Pointer stackTop;\n            {\n                stackTop = state.stackBottoms[state.sourceIndex];\n                // Copy inputs into place if needed.\n                if (inputs.length > 0) {\n                    // Inline some logic to avoid jumping due to function calls\n                    // on hot path.\n                    Pointer inputsDataPointer;\n                    assembly (\"memory-safe\") {\n                        // Move stack top by the number of inputs.\n                        stackTop := sub(stackTop, mul(mload(inputs), 0x20))\n                        inputsDataPointer := add(inputs, 0x20)\n                    }\n                    LibMemCpy.unsafeCopyWordsTo(inputsDataPointer, stackTop, inputs.length);\n                } else if (inputs.length != sourceInputs) {\n                    revert InputsLengthMismatch(sourceInputs, inputs.length);\n                }\n            }\n\n            // Run the loop.\n            stackTop = evalLoopNP(state, stackTop);\n\n            // Convert the stack top pointer to an array with the correct length.\n            // If the stack top is pointing to the base of Solidity's understanding\n            // of the stack array, then this will simply write the same length over\n            // the length the stack was initialized with, otherwise a shorter array\n            // will be built within the bounds of the stack. After this point `tail`\n            // and the original stack MUST be immutable as they're both pointing to\n            // the same memory region.\n            uint256 outputs = maxOutputs < sourceOutputs ? maxOutputs : sourceOutputs;\n            uint256[] memory result;\n            assembly (\"memory-safe\") {\n                result := sub(stackTop, 0x20)\n                mstore(result, outputs)\n\n                // Need to reverse the result array for backwards compatibility.\n                // Ideally we'd not do this, but will need to roll a new interface\n                // for such a breaking change.\n                for {\n                    let a := add(result, 0x20)\n                    let b := add(result, mul(outputs, 0x20))\n                } lt(a, b) {\n                    a := add(a, 0x20)\n                    b := sub(b, 0x20)\n                } {\n                    let tmp := mload(a)\n                    mstore(a, mload(b))\n                    mstore(b, tmp)\n                }\n            }\n\n            return (result, state.stateKV.toUint256Array());\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/ns/LibNamespace.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"../../interface/IInterpreterV1.sol\";\n\nlibrary LibNamespace {\n    /// Standard way to elevate a caller-provided state namespace to a universal\n    /// namespace that is disjoint from all other caller-provided namespaces.\n    /// Essentially just hashes the `msg.sender` into the state namespace as-is.\n    ///\n    /// This is deterministic such that the same combination of state namespace\n    /// and caller will produce the same fully qualified namespace, even across\n    /// multiple transactions/blocks.\n    ///\n    /// @param stateNamespace The state namespace as specified by the caller.\n    /// @param sender The caller this namespace is bound to.\n    /// @return qualifiedNamespace A fully qualified namespace that cannot\n    /// collide with any other state namespace specified by any other caller.\n    function qualifyNamespace(StateNamespace stateNamespace, address sender)\n        internal\n        pure\n        returns (FullyQualifiedNamespace qualifiedNamespace)\n    {\n        assembly (\"memory-safe\") {\n            mstore(0, stateNamespace)\n            mstore(0x20, sender)\n            qualifiedNamespace := keccak256(0, 0x40)\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/state/LibInterpreterStateDataContractNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"rain.solmem/lib/LibPointer.sol\";\nimport \"rain.solmem/lib/LibMemCpy.sol\";\nimport \"rain.solmem/lib/LibBytes.sol\";\n\nimport \"../ns/LibNamespace.sol\";\nimport \"./LibInterpreterStateNP.sol\";\n\nlibrary LibInterpreterStateDataContractNP {\n    using LibBytes for bytes;\n\n    function serializeSizeNP(bytes memory bytecode, uint256[] memory constants) internal pure returns (uint256 size) {\n        unchecked {\n            size = bytecode.length + constants.length * 0x20 + 0x40;\n        }\n    }\n\n    function unsafeSerializeNP(Pointer cursor, bytes memory bytecode, uint256[] memory constants) internal pure {\n        unchecked {\n            // Copy constants into place with length.\n            assembly (\"memory-safe\") {\n                for {\n                    let constantsCursor := constants\n                    let constantsEnd := add(constantsCursor, mul(0x20, add(mload(constants), 1)))\n                } lt(constantsCursor, constantsEnd) {\n                    constantsCursor := add(constantsCursor, 0x20)\n                    cursor := add(cursor, 0x20)\n                } { mstore(cursor, mload(constantsCursor)) }\n            }\n            // Copy the bytecode into place with length.\n            LibMemCpy.unsafeCopyBytesTo(bytecode.startPointer(), cursor, bytecode.length + 0x20);\n        }\n    }\n\n    function unsafeDeserializeNP(\n        bytes memory serialized,\n        uint256 sourceIndex,\n        FullyQualifiedNamespace namespace,\n        IInterpreterStoreV1 store,\n        uint256[][] memory context,\n        bytes memory fs\n    ) internal pure returns (InterpreterStateNP memory) {\n        unchecked {\n            Pointer cursor;\n            assembly (\"memory-safe\") {\n                cursor := add(serialized, 0x20)\n            }\n\n            // Reference the constants array as-is and move cursor past it.\n            uint256[] memory constants;\n            assembly (\"memory-safe\") {\n                constants := cursor\n                cursor := add(cursor, mul(0x20, add(mload(cursor), 1)))\n            }\n\n            // Reference the bytecode array as-is.\n            bytes memory bytecode;\n            assembly (\"memory-safe\") {\n                bytecode := cursor\n            }\n\n            // Build all the stacks.\n            Pointer[] memory stackBottoms;\n            assembly (\"memory-safe\") {\n                cursor := add(cursor, 0x20)\n                let stacksLength := byte(0, mload(cursor))\n                cursor := add(cursor, 1)\n                let sourcesStart := add(cursor, mul(stacksLength, 2))\n\n                // Allocate the memory for stackBottoms.\n                // We don't need to zero this because we're about to write to it.\n                stackBottoms := mload(0x40)\n                mstore(stackBottoms, stacksLength)\n                mstore(0x40, add(stackBottoms, mul(add(stacksLength, 1), 0x20)))\n\n                // Allocate each stack and point to it.\n                let stacksCursor := add(stackBottoms, 0x20)\n                for { let i := 0 } lt(i, stacksLength) {\n                    i := add(i, 1)\n                    // Move over the 2 byte source pointer.\n                    cursor := add(cursor, 2)\n                    // Move the stacks cursor forward.\n                    stacksCursor := add(stacksCursor, 0x20)\n                } {\n                    // The stack size is in the prefix of the source data, which\n                    // is behind a relative pointer in the bytecode prefix.\n                    let sourcePointer := add(sourcesStart, shr(0xf0, mload(cursor)))\n                    // Stack size is the second byte of the source prefix.\n                    let stackSize := byte(1, mload(sourcePointer))\n\n                    // Allocate the stack.\n                    // We don't need to zero the stack because the interpreter\n                    // assumes values above the stack top are dirty anyway.\n                    let stack := mload(0x40)\n                    mstore(stack, stackSize)\n                    let stackBottom := add(stack, mul(add(stackSize, 1), 0x20))\n                    mstore(0x40, stackBottom)\n\n                    // Point to the stack bottom\n                    mstore(stacksCursor, stackBottom)\n                }\n            }\n\n            return InterpreterStateNP(\n                stackBottoms, constants, sourceIndex, MemoryKV.wrap(0), namespace, store, context, bytecode, fs\n            );\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/caller/LibEncodedDispatch.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"../../interface/IInterpreterV1.sol\";\n\n/// @title LibEncodedDispatch\n/// @notice Establishes and implements a convention for encoding an interpreter\n/// dispatch. Handles encoding of several things required for efficient dispatch.\nlibrary LibEncodedDispatch {\n    /// Builds an `EncodedDispatch` from its constituent parts.\n    /// @param expression The onchain address of the expression to run.\n    /// @param sourceIndex The index of the source to run within the expression\n    /// as an entrypoint.\n    /// @param maxOutputs The maximum outputs the caller can meaningfully use.\n    /// If the interpreter returns a larger stack than this it is merely wasting\n    /// gas across the external call boundary.\n    /// @return The encoded dispatch.\n    function encode(address expression, SourceIndex sourceIndex, uint16 maxOutputs)\n        internal\n        pure\n        returns (EncodedDispatch)\n    {\n        return EncodedDispatch.wrap(\n            (uint256(uint160(expression)) << 32) | (uint256(SourceIndex.unwrap(sourceIndex)) << 16) | maxOutputs\n        );\n    }\n\n    /// Decodes an `EncodedDispatch` to its constituent parts.\n    /// @param dispatch_ The `EncodedDispatch` to decode.\n    /// @return The expression, source index, and max outputs as per `encode`.\n    function decode(EncodedDispatch dispatch_) internal pure returns (address, SourceIndex, uint16) {\n        return (\n            address(uint160(EncodedDispatch.unwrap(dispatch_) >> 32)),\n            SourceIndex.wrap(uint16(EncodedDispatch.unwrap(dispatch_) >> 16)),\n            uint16(EncodedDispatch.unwrap(dispatch_))\n        );\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/state/LibInterpreterStateNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"rain.solmem/lib/LibPointer.sol\";\nimport \"rain.lib.memkv/lib/LibMemoryKV.sol\";\nimport \"../ns/LibNamespace.sol\";\n\nstruct InterpreterStateNP {\n    Pointer[] stackBottoms;\n    uint256[] constants;\n    uint256 sourceIndex;\n    MemoryKV stateKV;\n    FullyQualifiedNamespace namespace;\n    IInterpreterStoreV1 store;\n    uint256[][] context;\n    bytes bytecode;\n    bytes fs;\n}\n\nlibrary LibInterpreterStateNP {\n    function fingerprint(InterpreterStateNP memory state) internal pure returns (bytes32) {\n        return keccak256(abi.encode(state));\n    }\n\n    function stackBottoms(uint256[][] memory stacks) internal pure returns (Pointer[] memory) {\n        Pointer[] memory bottoms = new Pointer[](stacks.length);\n        assembly (\"memory-safe\") {\n            for {\n                let cursor := add(stacks, 0x20)\n                let end := add(cursor, mul(mload(stacks), 0x20))\n                let bottomsCursor := add(bottoms, 0x20)\n            } lt(cursor, end) {\n                cursor := add(cursor, 0x20)\n                bottomsCursor := add(bottomsCursor, 0x20)\n            } {\n                let stack := mload(cursor)\n                let stackBottom := add(stack, mul(0x20, add(mload(stack), 1)))\n                mstore(bottomsCursor, stackBottom)\n            }\n        }\n        return bottoms;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/LibAllStandardOpsNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.19;\n\nimport {LibConvert} from \"rain.lib.typecast/LibConvert.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {Operand} from \"../../interface/IInterpreterV1.sol\";\nimport {LibIntegrityCheckNP, IntegrityCheckStateNP} from \"../integrity/LibIntegrityCheckNP.sol\";\nimport {LibInterpreterStateNP, InterpreterStateNP} from \"../state/LibInterpreterStateNP.sol\";\nimport {AuthoringMeta} from \"../parse/LibParseMeta.sol\";\nimport {\n    OPERAND_PARSER_OFFSET_DISALLOWED,\n    OPERAND_PARSER_OFFSET_SINGLE_FULL,\n    OPERAND_PARSER_OFFSET_DOUBLE_PERBYTE_NO_DEFAULT,\n    OPERAND_PARSER_OFFSET_M1_M1,\n    OPERAND_PARSER_OFFSET_8_M1_M1\n} from \"../parse/LibParseOperand.sol\";\nimport {LibUint256Array} from \"rain.solmem/lib/LibUint256Array.sol\";\nimport {LibOpStackNP} from \"./00/LibOpStackNP.sol\";\nimport {LibOpConstantNP} from \"./00/LibOpConstantNP.sol\";\n\nimport {LibOpCtPopNP} from \"./bitwise/LibOpCtPopNP.sol\";\n\nimport {LibOpCallNP} from \"./call/LibOpCallNP.sol\";\n\nimport {LibOpContextNP} from \"./context/LibOpContextNP.sol\";\n\nimport {LibOpHashNP} from \"./crypto/LibOpHashNP.sol\";\n\nimport {LibOpERC721BalanceOfNP} from \"./erc721/LibOpERC721BalanceOfNP.sol\";\nimport {LibOpERC721OwnerOfNP} from \"./erc721/LibOpERC721OwnerOfNP.sol\";\n\nimport {LibOpBlockNumberNP} from \"./evm/LibOpBlockNumberNP.sol\";\nimport {LibOpChainIdNP} from \"./evm/LibOpChainIdNP.sol\";\nimport {LibOpMaxUint256NP} from \"./evm/LibOpMaxUint256NP.sol\";\nimport {LibOpTimestampNP} from \"./evm/LibOpTimestampNP.sol\";\n\nimport {LibOpAnyNP} from \"./logic/LibOpAnyNP.sol\";\nimport {LibOpConditionsNP} from \"./logic/LibOpConditionsNP.sol\";\nimport {EnsureFailed, LibOpEnsureNP} from \"./logic/LibOpEnsureNP.sol\";\nimport {LibOpEqualToNP} from \"./logic/LibOpEqualToNP.sol\";\nimport {LibOpEveryNP} from \"./logic/LibOpEveryNP.sol\";\nimport {LibOpGreaterThanNP} from \"./logic/LibOpGreaterThanNP.sol\";\nimport {LibOpGreaterThanOrEqualToNP} from \"./logic/LibOpGreaterThanOrEqualToNP.sol\";\nimport {LibOpIfNP} from \"./logic/LibOpIfNP.sol\";\nimport {LibOpIsZeroNP} from \"./logic/LibOpIsZeroNP.sol\";\nimport {LibOpLessThanNP} from \"./logic/LibOpLessThanNP.sol\";\nimport {LibOpLessThanOrEqualToNP} from \"./logic/LibOpLessThanOrEqualToNP.sol\";\n\nimport {LibOpDecimal18MulNP} from \"./math/decimal18/LibOpDecimal18MulNP.sol\";\nimport {LibOpDecimal18DivNP} from \"./math/decimal18/LibOpDecimal18DivNP.sol\";\nimport {LibOpDecimal18Scale18DynamicNP} from \"./math/decimal18/LibOpDecimal18Scale18DynamicNP.sol\";\nimport {LibOpDecimal18Scale18NP} from \"./math/decimal18/LibOpDecimal18Scale18NP.sol\";\nimport {LibOpDecimal18ScaleNNP} from \"./math/decimal18/LibOpDecimal18ScaleNNP.sol\";\n\nimport {LibOpIntAddNP} from \"./math/int/LibOpIntAddNP.sol\";\nimport {LibOpIntDivNP} from \"./math/int/LibOpIntDivNP.sol\";\nimport {LibOpIntExpNP} from \"./math/int/LibOpIntExpNP.sol\";\nimport {LibOpIntMaxNP} from \"./math/int/LibOpIntMaxNP.sol\";\nimport {LibOpIntMinNP} from \"./math/int/LibOpIntMinNP.sol\";\nimport {LibOpIntModNP} from \"./math/int/LibOpIntModNP.sol\";\nimport {LibOpIntMulNP} from \"./math/int/LibOpIntMulNP.sol\";\nimport {LibOpIntSubNP} from \"./math/int/LibOpIntSubNP.sol\";\n\nimport {LibOpGetNP} from \"./store/LibOpGetNP.sol\";\nimport {LibOpSetNP} from \"./store/LibOpSetNP.sol\";\n\nimport {LibOpUniswapV2AmountIn} from \"./uniswap/LibOpUniswapV2AmountIn.sol\";\nimport {LibOpUniswapV2AmountOut} from \"./uniswap/LibOpUniswapV2AmountOut.sol\";\n\n/// Thrown when a dynamic length array is NOT 1 more than a fixed length array.\n/// Should never happen outside a major breaking change to memory layouts.\nerror BadDynamicLength(uint256 dynamicLength, uint256 standardOpsLength);\n\n/// @dev Number of ops currently provided by `AllStandardOpsNP`.\nuint256 constant ALL_STANDARD_OPS_LENGTH = 45;\n\n/// @title LibAllStandardOpsNP\n/// @notice Every opcode available from the core repository laid out as a single\n/// array to easily build function pointers for `IInterpreterV1`.\nlibrary LibAllStandardOpsNP {\n    function authoringMeta() internal pure returns (bytes memory) {\n        AuthoringMeta memory lengthPlaceholder;\n        AuthoringMeta[ALL_STANDARD_OPS_LENGTH + 1] memory wordsFixed = [\n            lengthPlaceholder,\n            // Stack and constant MUST be in this order for parsing to work.\n            AuthoringMeta(\"stack\", OPERAND_PARSER_OFFSET_SINGLE_FULL, \"Copies an existing value from the stack.\"),\n            AuthoringMeta(\"constant\", OPERAND_PARSER_OFFSET_SINGLE_FULL, \"Copies a constant value onto the stack.\"),\n            // These are all ordered according to how they appear in the file system.\n            AuthoringMeta(\n                \"bitwise-count-ones\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Counts the number of binary bits set to 1 in the input.\"\n            ),\n            AuthoringMeta(\n                \"call\",\n                OPERAND_PARSER_OFFSET_DOUBLE_PERBYTE_NO_DEFAULT,\n                \"Calls a source by index in the same Rain bytecode. The inputs to call are copied to the top of the called stack and the outputs specified in the operand are copied back to the calling stack. The first operand is the source index and the second is the number of outputs.\"\n            ),\n            AuthoringMeta(\n                \"context\",\n                OPERAND_PARSER_OFFSET_DOUBLE_PERBYTE_NO_DEFAULT,\n                \"Copies a value from the context. The first operand is the context column and second is the context row.\"\n            ),\n            AuthoringMeta(\n                \"hash\", OPERAND_PARSER_OFFSET_DISALLOWED, \"Hashes all inputs into a single 32 byte value using keccak256.\"\n            ),\n            AuthoringMeta(\n                \"erc721-balance-of\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Gets the balance of an erc721 token for an account. The first input is the token address and the second is the account address.\"\n            ),\n            AuthoringMeta(\n                \"erc721-owner-of\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Gets the owner of an erc721 token. The first input is the token address and the second is the token id.\"\n            ),\n            AuthoringMeta(\"block-number\", OPERAND_PARSER_OFFSET_DISALLOWED, \"The current block number.\"),\n            AuthoringMeta(\"chain-id\", OPERAND_PARSER_OFFSET_DISALLOWED, \"The current chain id.\"),\n            AuthoringMeta(\n                \"max-int-value\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"The maximum possible non-negative integer value. 2^256 - 1.\"\n            ),\n            AuthoringMeta(\n                \"max-decimal18-value\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"The maximum possible 18 decimal fixed point value. roughly 1.15e77.\"\n            ),\n            AuthoringMeta(\"block-timestamp\", OPERAND_PARSER_OFFSET_DISALLOWED, \"The current block timestamp.\"),\n            AuthoringMeta(\n                \"any\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"The first non-zero value out of all inputs, or 0 if every input is 0.\"\n            ),\n            AuthoringMeta(\n                \"conditions\",\n                OPERAND_PARSER_OFFSET_SINGLE_FULL,\n                \"Treats inputs as pairwise condition/value pairs. The first nonzero condition's value is used. If no conditions are nonzero, the expression reverts. The operand can be used as an error code to differentiate between multiple conditions in the same expression.\"\n            ),\n            AuthoringMeta(\n                \"ensure\",\n                OPERAND_PARSER_OFFSET_SINGLE_FULL,\n                \"Reverts if any input is 0. All inputs are eagerly evaluated there are no outputs. The operand can be used as an error code to differentiate between multiple conditions in the same expression.\"\n            ),\n            AuthoringMeta(\"equal-to\", OPERAND_PARSER_OFFSET_DISALLOWED, \"1 if all inputs are equal, 0 otherwise.\"),\n            AuthoringMeta(\n                \"every\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"The last nonzero value out of all inputs, or 0 if any input is 0.\"\n            ),\n            AuthoringMeta(\n                \"greater-than\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"1 if the first input is greater than the second input, 0 otherwise.\"\n            ),\n            AuthoringMeta(\n                \"greater-than-or-equal-to\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"1 if the first input is greater than or equal to the second input, 0 otherwise.\"\n            ),\n            AuthoringMeta(\n                \"if\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"If the first input is nonzero, the second input is used. Otherwise, the third input is used. If is eagerly evaluated.\"\n            ),\n            AuthoringMeta(\"is-zero\", OPERAND_PARSER_OFFSET_DISALLOWED, \"1 if the input is 0, 0 otherwise.\"),\n            AuthoringMeta(\n                \"less-than\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"1 if the first input is less than the second input, 0 otherwise.\"\n            ),\n            AuthoringMeta(\n                \"less-than-or-equal-to\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"1 if the first input is less than or equal to the second input, 0 otherwise.\"\n            ),\n            AuthoringMeta(\n                \"decimal18-div\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Divides the first input by all other inputs as fixed point 18 decimal numbers (i.e. 'one' is 1e18). Errors if any divisor is zero.\"\n            ),\n            AuthoringMeta(\n                \"decimal18-mul\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Multiplies all inputs together as fixed point 18 decimal numbers (i.e. 'one' is 1e18). Errors if the multiplication exceeds the maximum value (roughly 1.15e77).\"\n            ),\n            AuthoringMeta(\n                \"decimal18-scale18-dynamic\",\n                OPERAND_PARSER_OFFSET_M1_M1,\n                \"Scales a value from some fixed point decimal scale to 18 decimal fixed point. The first input is the scale to scale from and the second is the value to scale. The two optional operands control rounding and saturation respectively as per `decimal18-scale18`.\"\n            ),\n            AuthoringMeta(\n                \"decimal18-scale18\",\n                OPERAND_PARSER_OFFSET_8_M1_M1,\n                \"Scales an input value from some fixed point decimal scale to 18 decimal fixed point. The first operand is the scale to scale from. The second (optional) operand controls rounding where 0 (default) rounds down and 1 rounds up. The third (optional) operand controls saturation where 0 (default) errors on overflow and 1 saturates at max-decimal-value.\"\n            ),\n            AuthoringMeta(\n                \"decimal18-scale-n\",\n                OPERAND_PARSER_OFFSET_8_M1_M1,\n                \"Scales an input value from 18 decimal fixed point to some other fixed point scale N. The first operand is the scale to scale to. The second (optional) operand controls rounding where 0 (default) rounds down and 1 rounds up. The third (optional) operand controls saturation where 0 (default) errors on overflow and 1 saturates at max-decimal-value.\"\n            ),\n            // int and decimal18 add have identical implementations and point to\n            // the same function pointer. This is intentional.\n            AuthoringMeta(\n                \"int-add\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Adds all inputs together as non-negative integers. Errors if the addition exceeds the maximum value (roughly 1.15e77).\"\n            ),\n            AuthoringMeta(\n                \"decimal18-add\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Adds all inputs together as fixed point 18 decimal numbers (i.e. 'one' is 1e18). Errors if the addition exceeds the maximum value (roughly 1.15e77).\"\n            ),\n            AuthoringMeta(\n                \"int-div\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Divides the first input by all other inputs as non-negative integers. Errors if any divisor is zero.\"\n            ),\n            AuthoringMeta(\n                \"int-exp\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Raises the first input to the power of all other inputs as non-negative integers. Errors if the exponentiation would exceed the maximum value (roughly 1.15e77).\"\n            ),\n            // int and decimal18 max have identical implementations and point to\n            // the same function pointer. This is intentional.\n            AuthoringMeta(\n                \"int-max\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Finds the maximum value from all inputs as non-negative integers.\"\n            ),\n            AuthoringMeta(\n                \"decimal18-max\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Finds the maximum value from all inputs as fixed point 18 decimal numbers (i.e. 'one' is 1e18).\"\n            ),\n            // int and decimal18 min have identical implementations and point to\n            // the same function pointer. This is intentional.\n            AuthoringMeta(\n                \"int-min\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Finds the minimum value from all inputs as non-negative integers.\"\n            ),\n            AuthoringMeta(\n                \"decimal18-min\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Finds the minimum value from all inputs as fixed point 18 decimal numbers (i.e. 'one' is 1e18).\"\n            ),\n            AuthoringMeta(\n                \"int-mod\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Modulos the first input by all other inputs as non-negative integers. Errors if any divisor is zero.\"\n            ),\n            AuthoringMeta(\n                \"int-mul\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Multiplies all inputs together as non-negative integers. Errors if the multiplication exceeds the maximum value (roughly 1.15e77).\"\n            ),\n            // int and decimal18 sub have identical implementations and point to\n            // the same function pointer. This is intentional.\n            AuthoringMeta(\n                \"int-sub\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Subtracts all inputs from the first input as non-negative integers. Errors if the subtraction would result in a negative value.\"\n            ),\n            AuthoringMeta(\n                \"decimal18-sub\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Subtracts all inputs from the first input as fixed point 18 decimal numbers (i.e. 'one' is 1e18). Errors if the subtraction would result in a negative value.\"\n            ),\n            AuthoringMeta(\n                \"get\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Gets a value from storage. The first operand is the key to lookup.\"\n            ),\n            AuthoringMeta(\n                \"set\",\n                OPERAND_PARSER_OFFSET_DISALLOWED,\n                \"Sets a value in storage. The first operand is the key to set and the second operand is the value to set.\"\n            ),\n            AuthoringMeta(\n                \"uniswap-v2-amount-in\",\n                OPERAND_PARSER_OFFSET_SINGLE_FULL,\n                \"Computes the minimum amount of input tokens required to get a given amount of output tokens from a UniswapV2 pair. Input/output token directions are from the perspective of the Uniswap contract. The first input is the factory address, the second is the amount of output tokens, the third is the input token address, and the fourth is the output token address. If the operand is 1 the last time the prices changed will be returned as well.\"\n            ),\n            AuthoringMeta(\n                \"uniswap-v2-amount-out\",\n                OPERAND_PARSER_OFFSET_SINGLE_FULL,\n                \"Computes the maximum amount of output tokens received from a given amount of input tokens from a UniswapV2 pair. Input/output token directions are from the perspective of the Uniswap contract. The first input is the factory address, the second is the amount of input tokens, the third is the input token address, and the fourth is the output token address. If the operand is 1 the last time the prices changed will be returned as well.\"\n            )\n        ];\n        AuthoringMeta[] memory wordsDynamic;\n        uint256 length = ALL_STANDARD_OPS_LENGTH;\n        assembly (\"memory-safe\") {\n            wordsDynamic := wordsFixed\n            mstore(wordsDynamic, length)\n        }\n        return abi.encode(wordsDynamic);\n    }\n\n    function integrityFunctionPointers() internal pure returns (bytes memory) {\n        unchecked {\n            function(IntegrityCheckStateNP memory, Operand)\n                view\n                returns (uint256, uint256) lengthPointer;\n            uint256 length = ALL_STANDARD_OPS_LENGTH;\n            assembly (\"memory-safe\") {\n                lengthPointer := length\n            }\n            function(IntegrityCheckStateNP memory, Operand)\n                view\n                returns (uint256, uint256)[ALL_STANDARD_OPS_LENGTH + 1] memory pointersFixed = [\n                    lengthPointer,\n                    // Stack then constant are the first two ops to match the\n                    // field ordering in the interpreter state NOT the lexical\n                    // ordering of the file system.\n                    LibOpStackNP.integrity,\n                    LibOpConstantNP.integrity,\n                    // Everything else is alphabetical, including folders.\n                    LibOpCtPopNP.integrity,\n                    LibOpCallNP.integrity,\n                    LibOpContextNP.integrity,\n                    LibOpHashNP.integrity,\n                    LibOpERC721BalanceOfNP.integrity,\n                    LibOpERC721OwnerOfNP.integrity,\n                    LibOpBlockNumberNP.integrity,\n                    LibOpChainIdNP.integrity,\n                    // int and decimal18 max have identical implementations and\n                    // point to the same function pointer. This is intentional.\n                    LibOpMaxUint256NP.integrity,\n                    // decimal18 max.\n                    LibOpMaxUint256NP.integrity,\n                    LibOpTimestampNP.integrity,\n                    LibOpAnyNP.integrity,\n                    LibOpConditionsNP.integrity,\n                    LibOpEnsureNP.integrity,\n                    LibOpEqualToNP.integrity,\n                    LibOpEveryNP.integrity,\n                    LibOpGreaterThanNP.integrity,\n                    LibOpGreaterThanOrEqualToNP.integrity,\n                    LibOpIfNP.integrity,\n                    LibOpIsZeroNP.integrity,\n                    LibOpLessThanNP.integrity,\n                    LibOpLessThanOrEqualToNP.integrity,\n                    LibOpDecimal18DivNP.integrity,\n                    LibOpDecimal18MulNP.integrity,\n                    LibOpDecimal18Scale18DynamicNP.integrity,\n                    LibOpDecimal18Scale18NP.integrity,\n                    LibOpDecimal18ScaleNNP.integrity,\n                    // int and decimal18 add have identical implementations and\n                    // point to the same function pointer. This is intentional.\n                    LibOpIntAddNP.integrity,\n                    // decimal18 add.\n                    LibOpIntAddNP.integrity,\n                    LibOpIntDivNP.integrity,\n                    LibOpIntExpNP.integrity,\n                    // int and decimal18 max have identical implementations and\n                    // point to the same function pointer. This is intentional.\n                    LibOpIntMaxNP.integrity,\n                    // decimal18 max.\n                    LibOpIntMaxNP.integrity,\n                    // int and decimal18 min have identical implementations and\n                    // point to the same function pointer. This is intentional.\n                    LibOpIntMinNP.integrity,\n                    // decimal18 min.\n                    LibOpIntMinNP.integrity,\n                    LibOpIntModNP.integrity,\n                    LibOpIntMulNP.integrity,\n                    // int and decimal18 sub have identical implementations and\n                    // point to the same function pointer. This is intentional.\n                    LibOpIntSubNP.integrity,\n                    // decimal18 sub.\n                    LibOpIntSubNP.integrity,\n                    LibOpGetNP.integrity,\n                    LibOpSetNP.integrity,\n                    LibOpUniswapV2AmountIn.integrity,\n                    LibOpUniswapV2AmountOut.integrity\n                ];\n            uint256[] memory pointersDynamic;\n            assembly (\"memory-safe\") {\n                pointersDynamic := pointersFixed\n            }\n            // Sanity check that the dynamic length is correct. Should be an\n            // unreachable error.\n            if (pointersDynamic.length != ALL_STANDARD_OPS_LENGTH) {\n                revert BadDynamicLength(pointersDynamic.length, length);\n            }\n            return LibConvert.unsafeTo16BitBytes(pointersDynamic);\n        }\n    }\n\n    /// All function pointers for the standard opcodes. Intended to be used to\n    /// build a `IInterpreterV1` instance, specifically the `functionPointers`\n    /// method can just be a thin wrapper around this function.\n    function opcodeFunctionPointers() internal pure returns (bytes memory) {\n        unchecked {\n            function(InterpreterStateNP memory, Operand, Pointer)\n                view\n                returns (Pointer) lengthPointer;\n            uint256 length = ALL_STANDARD_OPS_LENGTH;\n            assembly (\"memory-safe\") {\n                lengthPointer := length\n            }\n            function(InterpreterStateNP memory, Operand, Pointer)\n                view\n                returns (Pointer)[ALL_STANDARD_OPS_LENGTH + 1] memory pointersFixed = [\n                    lengthPointer,\n                    // Stack then constant are the first two ops to match the\n                    // field ordering in the interpreter state NOT the lexical\n                    // ordering of the file system.\n                    LibOpStackNP.run,\n                    LibOpConstantNP.run,\n                    // Everything else is alphabetical, including folders.\n                    LibOpCtPopNP.run,\n                    LibOpCallNP.run,\n                    LibOpContextNP.run,\n                    LibOpHashNP.run,\n                    LibOpERC721BalanceOfNP.run,\n                    LibOpERC721OwnerOfNP.run,\n                    LibOpBlockNumberNP.run,\n                    LibOpChainIdNP.run,\n                    // int and decimal18 max have identical implementations and\n                    // point to the same function pointer. This is intentional.\n                    LibOpMaxUint256NP.run,\n                    // decimal18 max.\n                    LibOpMaxUint256NP.run,\n                    LibOpTimestampNP.run,\n                    LibOpAnyNP.run,\n                    LibOpConditionsNP.run,\n                    LibOpEnsureNP.run,\n                    LibOpEqualToNP.run,\n                    LibOpEveryNP.run,\n                    LibOpGreaterThanNP.run,\n                    LibOpGreaterThanOrEqualToNP.run,\n                    LibOpIfNP.run,\n                    LibOpIsZeroNP.run,\n                    LibOpLessThanNP.run,\n                    LibOpLessThanOrEqualToNP.run,\n                    LibOpDecimal18DivNP.run,\n                    LibOpDecimal18MulNP.run,\n                    LibOpDecimal18Scale18DynamicNP.run,\n                    LibOpDecimal18Scale18NP.run,\n                    LibOpDecimal18ScaleNNP.run,\n                    // int and decimal18 add have identical implementations and\n                    // point to the same function pointer. This is intentional.\n                    LibOpIntAddNP.run,\n                    // decimal18 add.\n                    LibOpIntAddNP.run,\n                    LibOpIntDivNP.run,\n                    LibOpIntExpNP.run,\n                    // int and decimal18 max have identical implementations and\n                    // point to the same function pointer. This is intentional.\n                    LibOpIntMaxNP.run,\n                    // decimal18 max.\n                    LibOpIntMaxNP.run,\n                    // int and decimal18 min have identical implementations and\n                    // point to the same function pointer. This is intentional.\n                    LibOpIntMinNP.run,\n                    // decimal18 min.\n                    LibOpIntMinNP.run,\n                    LibOpIntModNP.run,\n                    LibOpIntMulNP.run,\n                    // int and decimal18 sub have identical implementations and\n                    // point to the same function pointer. This is intentional.\n                    LibOpIntSubNP.run,\n                    // decimal18 sub.\n                    LibOpIntSubNP.run,\n                    LibOpGetNP.run,\n                    LibOpSetNP.run,\n                    LibOpUniswapV2AmountIn.run,\n                    LibOpUniswapV2AmountOut.run\n                ];\n            uint256[] memory pointersDynamic;\n            assembly (\"memory-safe\") {\n                pointersDynamic := pointersFixed\n            }\n            // Sanity check that the dynamic length is correct. Should be an\n            // unreachable error.\n            if (pointersDynamic.length != ALL_STANDARD_OPS_LENGTH) {\n                revert BadDynamicLength(pointersDynamic.length, length);\n            }\n            return LibConvert.unsafeTo16BitBytes(pointersDynamic);\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/rain.solmem/src/lib/LibPointer.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// A pointer to a location in memory. This is a `uint256` to save gas on low\n/// level operations on the evm stack. These same low level operations typically\n/// WILL NOT check for overflow or underflow, so all pointer logic MUST ensure\n/// that reads, writes and movements are not out of bounds.\ntype Pointer is uint256;\n\n/// @title LibPointer\n/// Ergonomic wrappers around common pointer movements, reading and writing. As\n/// wrappers on such low level operations often introduce too much jump gas\n/// overhead, these functions MAY find themselves used in reference\n/// implementations that more optimised code can be fuzzed against. MAY also be\n/// situationally useful on cooler performance paths.\nlibrary LibPointer {\n    /// Cast a `Pointer` to `bytes` without modification or any safety checks.\n    /// The caller MUST ensure the pointer is to a valid region of memory for\n    /// some `bytes`.\n    /// @param pointer The pointer to cast to `bytes`.\n    /// @return data The cast `bytes`.\n    function unsafeAsBytes(Pointer pointer) internal pure returns (bytes memory data) {\n        assembly (\"memory-safe\") {\n            data := pointer\n        }\n    }\n\n    /// Increase some pointer by a number of bytes.\n    ///\n    /// This is UNSAFE because it can silently overflow or point beyond some\n    /// data structure. The caller MUST ensure that this is a safe operation.\n    ///\n    /// Note that moving a pointer by some bytes offset is likely to unalign it\n    /// with the 32 byte increments of the Solidity allocator.\n    ///\n    /// @param pointer The pointer to increase by `length`.\n    /// @param length The number of bytes to increase the pointer by.\n    /// @return The increased pointer.\n    function unsafeAddBytes(Pointer pointer, uint256 length) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(pointer, length)\n        }\n        return pointer;\n    }\n\n    /// Increase some pointer by a single 32 byte word.\n    ///\n    /// This is UNSAFE because it can silently overflow or point beyond some\n    /// data structure. The caller MUST ensure that this is a safe operation.\n    ///\n    /// If the original pointer is aligned to the Solidity allocator it will be\n    /// aligned after the movement.\n    ///\n    /// @param pointer The pointer to increase by a single word.\n    /// @return The increased pointer.\n    function unsafeAddWord(Pointer pointer) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(pointer, 0x20)\n        }\n        return pointer;\n    }\n\n    /// Increase some pointer by multiple 32 byte words.\n    ///\n    /// This is UNSAFE because it can silently overflow or point beyond some\n    /// data structure. The caller MUST ensure that this is a safe operation.\n    ///\n    /// If the original pointer is aligned to the Solidity allocator it will be\n    /// aligned after the movement.\n    ///\n    /// @param pointer The pointer to increase.\n    /// @param words The number of words to increase the pointer by.\n    /// @return The increased pointer.\n    function unsafeAddWords(Pointer pointer, uint256 words) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(pointer, mul(0x20, words))\n        }\n        return pointer;\n    }\n\n    /// Decrease some pointer by a single 32 byte word.\n    ///\n    /// This is UNSAFE because it can silently underflow or point below some\n    /// data structure. The caller MUST ensure that this is a safe operation.\n    ///\n    /// If the original pointer is aligned to the Solidity allocator it will be\n    /// aligned after the movement.\n    ///\n    /// @param pointer The pointer to decrease by a single word.\n    /// @return The decreased pointer.\n    function unsafeSubWord(Pointer pointer) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            pointer := sub(pointer, 0x20)\n        }\n        return pointer;\n    }\n\n    /// Decrease some pointer by multiple 32 byte words.\n    ///\n    /// This is UNSAFE because it can silently underflow or point below some\n    /// data structure. The caller MUST ensure that this is a safe operation.\n    ///\n    /// If the original pointer is aligned to the Solidity allocator it will be\n    /// aligned after the movement.\n    ///\n    /// @param pointer The pointer to decrease.\n    /// @param words The number of words to decrease the pointer by.\n    /// @return The decreased pointer.\n    function unsafeSubWords(Pointer pointer, uint256 words) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            pointer := sub(pointer, mul(0x20, words))\n        }\n        return pointer;\n    }\n\n    /// Read the word at the pointer.\n    ///\n    /// This is UNSAFE because it can read outside any particular data stucture\n    /// or even beyond allocated memory. The caller MUST ensure that this is a\n    /// safe operation.\n    ///\n    /// @param pointer Pointer to read the word at.\n    /// @return word The word read from the pointer.\n    function unsafeReadWord(Pointer pointer) internal pure returns (uint256 word) {\n        assembly (\"memory-safe\") {\n            word := mload(pointer)\n        }\n    }\n\n    /// Write a word at the pointer.\n    ///\n    /// This is UNSAFE because it can write outside any particular data stucture\n    /// or even beyond allocated memory. The caller MUST ensure that this is a\n    /// safe operation.\n    ///\n    /// @param pointer Pointer to write the word at.\n    /// @param word The word to write.\n    function unsafeWriteWord(Pointer pointer, uint256 word) internal pure {\n        assembly (\"memory-safe\") {\n            mstore(pointer, word)\n        }\n    }\n\n    /// Get the pointer to the end of all allocated memory.\n    /// As per Solidity docs, there is no guarantee that the region of memory\n    /// beyond this pointer is zeroed out, as assembly MAY write beyond allocated\n    /// memory for temporary use if the scratch space is insufficient.\n    /// @return pointer The pointer to the end of all allocated memory.\n    function allocatedMemoryPointer() internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := mload(0x40)\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/rain.solmem/src/lib/LibStackPointer.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"./LibUint256Array.sol\";\nimport \"./LibMemory.sol\";\nimport \"./LibMemCpy.sol\";\n\n/// Throws if a stack pointer is not aligned to 32 bytes.\nerror UnalignedStackPointer(Pointer pointer);\n\n/// @title LibStackPointer\n/// @notice A stack `Pointer` is still just a pointer to some memory, but we are\n/// going to treat it like it is pointing to a stack data structure. That means\n/// it can move \"up\" and \"down\" (increment and decrement) by `uint256` (32 bytes)\n/// increments. Structurally a stack is a `uint256[]` but we can save a lot of\n/// gas vs. default Solidity handling of array indexes by using assembly to\n/// bypass runtime bounds checks on every read and write. Of course, this means\n/// the caller is responsible for ensuring the stack reads and write are not out\n/// of bounds.\n///\n/// The pointer to the bottom of a stack points at the 0th item, NOT the length\n/// of the implied `uint256[]` and the top of a stack points AFTER the last item.\n/// e.g. consider a `uint256[]` in memory with values `3 A B C` and assume this\n/// starts at position `0` in memory, i.e. `0` points to value `3` for the\n/// array length. In this case the stack bottom would be `Pointer.wrap(0x20)`\n/// (32 bytes above 0, past the length) and the stack top would be\n/// `StackPointer.wrap(0x80)` (96 bytes above the stack bottom).\n///\n/// Most of the functions in this library are equivalent to each other via\n/// composition, i.e. everything could be achieved with just `up`, `down`,\n/// `pop`, `push`, `peek`. The reason there is so much overloaded/duplicated\n/// logic is that the Solidity compiler seems to fail at inlining equivalent\n/// logic quite a lot. Perhaps once the IR compilation of Solidity is better\n/// supported by tooling etc. we could remove a lot of this duplication as the\n/// compiler itself would handle the optimisations.\nlibrary LibStackPointer {\n    using LibStackPointer for Pointer;\n    using LibStackPointer for uint256[];\n    using LibStackPointer for bytes;\n    using LibUint256Array for uint256[];\n    using LibMemory for uint256;\n\n    /// Read the word immediately below the given stack pointer.\n    ///\n    /// Treats the given pointer as a pointer to the top of the stack, so `peek`\n    /// reads the word below the pointer.\n    ///\n    /// https://en.wikipedia.org/wiki/Peek_(data_type_operation)\n    ///\n    /// The caller MUST ensure this read is not out of bounds, e.g. a `peek` to\n    /// `0` will underflow (and exhaust gas attempting to read).\n    ///\n    /// @param pointer Pointer to the top of the stack to read below.\n    /// @return word The word that was read.\n    function unsafePeek(Pointer pointer) internal pure returns (uint256 word) {\n        assembly (\"memory-safe\") {\n            word := mload(sub(pointer, 0x20))\n        }\n    }\n\n    /// Peeks 2 words from the top of the stack.\n    ///\n    /// Same as `unsafePeek` but returns 2 words instead of 1.\n    ///\n    /// @param pointer The stack top to peek below.\n    /// @return lower The lower of the two words read.\n    /// @return upper The upper of the two words read.\n    function unsafePeek2(Pointer pointer) internal pure returns (uint256 lower, uint256 upper) {\n        assembly (\"memory-safe\") {\n            lower := mload(sub(pointer, 0x40))\n            upper := mload(sub(pointer, 0x20))\n        }\n    }\n\n    /// Pops the word from the top of the stack.\n    ///\n    /// Treats the given pointer as a pointer to the top of the stack, so `pop`\n    /// reads the word below the pointer. The popped pointer is returned\n    /// alongside the read word.\n    ///\n    /// https://en.wikipedia.org/wiki/Stack_(abstract_data_type)\n    ///\n    /// The caller MUST ensure the pop will not result in an out of bounds read.\n    ///\n    /// @param pointer Pointer to the top of the stack to read below.\n    /// @return pointerAfter Pointer after the pop.\n    /// @return word The word that was read.\n    function unsafePop(Pointer pointer) internal pure returns (Pointer pointerAfter, uint256 word) {\n        assembly (\"memory-safe\") {\n            pointerAfter := sub(pointer, 0x20)\n            word := mload(pointerAfter)\n        }\n    }\n\n    /// Pushes a word to the top of the stack.\n    ///\n    /// Treats the given pointer as a pointer to the top of the stack, so `push`\n    /// writes a word at the pointer. The pushed pointer is returned.\n    ///\n    /// https://en.wikipedia.org/wiki/Stack_(abstract_data_type)\n    ///\n    /// The caller MUST ensure the push will not result in an out of bounds\n    /// write.\n    ///\n    /// @param pointer The stack pointer to write at.\n    /// @param word The value to write.\n    /// @return The stack pointer above where `word` was written to.\n    function unsafePush(Pointer pointer, uint256 word) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            mstore(pointer, word)\n            pointer := add(pointer, 0x20)\n        }\n        return pointer;\n    }\n\n    /// Returns `length` values from the stack as an array without allocating\n    /// new memory. As arrays always start with their length, this requires\n    /// writing the length value to the stack below the array values. The value\n    /// that is overwritten in the process is also returned so that data is not\n    /// lost. For example, imagine a stack `[ A B C D ]` and we list 2 values.\n    /// This will write the stack to look like `[ A 2 C D ]` and return both `B`\n    /// and a pointer to `2` represented as a `uint256[]`.\n    /// The returned array is ONLY valid for as long as the stack DOES NOT move\n    /// back into its memory. As soon as the stack moves up again and writes into\n    /// the array it will be corrupt. The caller MUST ensure that it does not\n    /// read from the returned array after it has been corrupted by subsequent\n    /// stack writes.\n    /// @param pointer The stack pointer to read the values below into an\n    /// array.\n    /// @param length The number of values to include in the returned array.\n    /// @return head The value that was overwritten with the length.\n    /// @return tail The array constructed from the stack memory.\n    function unsafeList(Pointer pointer, uint256 length) internal pure returns (uint256 head, uint256[] memory tail) {\n        assembly (\"memory-safe\") {\n            tail := sub(pointer, add(0x20, mul(length, 0x20)))\n            head := mload(tail)\n            mstore(tail, length)\n        }\n    }\n\n    /// Convert two stack pointer values to a single stack index. A stack index\n    /// is the distance in 32 byte increments between two stack pointers. The\n    /// calculations require the two stack pointers are aligned. If the pointers\n    /// are not aligned, the function will revert.\n    ///\n    /// @param lower The lower of the two values.\n    /// @param upper The higher of the two values.\n    /// @return The stack index as 32 byte words distance between the top and\n    /// bottom. Negative if `lower` is above `upper`.\n    function toIndexSigned(Pointer lower, Pointer upper) internal pure returns (int256) {\n        unchecked {\n            if (Pointer.unwrap(lower) % 0x20 != 0) {\n                revert UnalignedStackPointer(lower);\n            }\n            if (Pointer.unwrap(upper) % 0x20 != 0) {\n                revert UnalignedStackPointer(upper);\n            }\n            // Dividing by 0x20 before casting to a signed int avoids the case\n            // where the difference between the two pointers is greater than\n            // `type(int256).max` and would overflow the signed int.\n            return int256(Pointer.unwrap(upper) / 0x20) - int256(Pointer.unwrap(lower) / 0x20);\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/rain.solmem/src/lib/LibUint256Array.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"./LibMemCpy.sol\";\n\n/// Thrown if a truncated length is longer than the array being truncated. It is\n/// not possible to truncate something and increase its length as the memory\n/// region after the array MAY be allocated for something else already.\nerror OutOfBoundsTruncate(uint256 arrayLength, uint256 truncatedLength);\n\n/// @title Uint256Array\n/// @notice Things we want to do carefully and efficiently with uint256 arrays\n/// that Solidity doesn't give us native tools for.\nlibrary LibUint256Array {\n    using LibUint256Array for uint256[];\n\n    /// Pointer to the start (length prefix) of a `uint256[]`.\n    /// @param array The array to get the start pointer of.\n    /// @return pointer The pointer to the start of `array`.\n    function startPointer(uint256[] memory array) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := array\n        }\n    }\n\n    /// Pointer to the data of a `uint256[]` NOT the length prefix.\n    /// @param array The array to get the data pointer of.\n    /// @return pointer The pointer to the data of `array`.\n    function dataPointer(uint256[] memory array) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(array, 0x20)\n        }\n    }\n\n    /// Pointer to the end of the allocated memory of an array.\n    /// @param array The array to get the end pointer of.\n    /// @return pointer The pointer to the end of `array`.\n    function endPointer(uint256[] memory array) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(array, add(0x20, mul(0x20, mload(array))))\n        }\n    }\n\n    /// Cast a `Pointer` to `uint256[]` without modification or safety checks.\n    /// The caller MUST ensure the pointer is to a valid region of memory for\n    /// some `uint256[]`.\n    /// @param pointer The pointer to cast to `uint256[]`.\n    /// @return array The cast `uint256[]`.\n    function unsafeAsUint256Array(Pointer pointer) internal pure returns (uint256[] memory array) {\n        assembly (\"memory-safe\") {\n            array := pointer\n        }\n    }\n\n    /// Building arrays from literal components is a common task that introduces\n    /// boilerplate that is either inefficient or error prone.\n    /// @param a A single integer to build an array around.\n    /// @return array The newly allocated array including `a` as a single item.\n    function arrayFrom(uint256 a) internal pure returns (uint256[] memory array) {\n        assembly (\"memory-safe\") {\n            array := mload(0x40)\n            mstore(array, 1)\n            mstore(add(array, 0x20), a)\n            mstore(0x40, add(array, 0x40))\n        }\n    }\n\n    /// Building arrays from literal components is a common task that introduces\n    /// boilerplate that is either inefficient or error prone.\n    /// @param a The first integer to build an array around.\n    /// @param b The second integer to build an array around.\n    /// @return array The newly allocated array including `a` and `b` as the only\n    /// items.\n    function arrayFrom(uint256 a, uint256 b) internal pure returns (uint256[] memory array) {\n        assembly (\"memory-safe\") {\n            array := mload(0x40)\n            mstore(array, 2)\n            mstore(add(array, 0x20), a)\n            mstore(add(array, 0x40), b)\n            mstore(0x40, add(array, 0x60))\n        }\n    }\n\n    /// Building arrays from literal components is a common task that introduces\n    /// boilerplate that is either inefficient or error prone.\n    /// @param a The first integer to build an array around.\n    /// @param b The second integer to build an array around.\n    /// @param c The third integer to build an array around.\n    /// @return array The newly allocated array including `a`, `b` and `c` as the\n    /// only items.\n    function arrayFrom(uint256 a, uint256 b, uint256 c) internal pure returns (uint256[] memory array) {\n        assembly (\"memory-safe\") {\n            array := mload(0x40)\n            mstore(array, 3)\n            mstore(add(array, 0x20), a)\n            mstore(add(array, 0x40), b)\n            mstore(add(array, 0x60), c)\n            mstore(0x40, add(array, 0x80))\n        }\n    }\n\n    /// Building arrays from literal components is a common task that introduces\n    /// boilerplate that is either inefficient or error prone.\n    /// @param a The first integer to build an array around.\n    /// @param b The second integer to build an array around.\n    /// @param c The third integer to build an array around.\n    /// @param d The fourth integer to build an array around.\n    /// @return array The newly allocated array including `a`, `b`, `c` and `d` as the\n    /// only items.\n    function arrayFrom(uint256 a, uint256 b, uint256 c, uint256 d) internal pure returns (uint256[] memory array) {\n        assembly (\"memory-safe\") {\n            array := mload(0x40)\n            mstore(array, 4)\n            mstore(add(array, 0x20), a)\n            mstore(add(array, 0x40), b)\n            mstore(add(array, 0x60), c)\n            mstore(add(array, 0x80), d)\n            mstore(0x40, add(array, 0xA0))\n        }\n    }\n\n    /// Building arrays from literal components is a common task that introduces\n    /// boilerplate that is either inefficient or error prone.\n    /// @param a The first integer to build an array around.\n    /// @param b The second integer to build an array around.\n    /// @param c The third integer to build an array around.\n    /// @param d The fourth integer to build an array around.\n    /// @param e The fifth integer to build an array around.\n    /// @return array The newly allocated array including `a`, `b`, `c`, `d` and\n    /// `e` as the only items.\n    function arrayFrom(uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n        internal\n        pure\n        returns (uint256[] memory array)\n    {\n        assembly (\"memory-safe\") {\n            array := mload(0x40)\n            mstore(array, 5)\n            mstore(add(array, 0x20), a)\n            mstore(add(array, 0x40), b)\n            mstore(add(array, 0x60), c)\n            mstore(add(array, 0x80), d)\n            mstore(add(array, 0xA0), e)\n            mstore(0x40, add(array, 0xC0))\n        }\n    }\n\n    /// Building arrays from literal components is a common task that introduces\n    /// boilerplate that is either inefficient or error prone.\n    /// @param a The first integer to build an array around.\n    /// @param b The second integer to build an array around.\n    /// @param c The third integer to build an array around.\n    /// @param d The fourth integer to build an array around.\n    /// @param e The fifth integer to build an array around.\n    /// @param f The sixth integer to build an array around.\n    /// @return array The newly allocated array including `a`, `b`, `c`, `d`, `e`\n    /// and `f` as the only items.\n    function arrayFrom(uint256 a, uint256 b, uint256 c, uint256 d, uint256 e, uint256 f)\n        internal\n        pure\n        returns (uint256[] memory array)\n    {\n        assembly (\"memory-safe\") {\n            array := mload(0x40)\n            mstore(array, 6)\n            mstore(add(array, 0x20), a)\n            mstore(add(array, 0x40), b)\n            mstore(add(array, 0x60), c)\n            mstore(add(array, 0x80), d)\n            mstore(add(array, 0xA0), e)\n            mstore(add(array, 0xC0), f)\n            mstore(0x40, add(array, 0xE0))\n        }\n    }\n\n    /// Building arrays from literal components is a common task that introduces\n    /// boilerplate that is either inefficient or error prone.\n    /// @param a The head of the new array.\n    /// @param tail The tail of the new array.\n    /// @return array The new array.\n    function arrayFrom(uint256 a, uint256[] memory tail) internal pure returns (uint256[] memory array) {\n        assembly (\"memory-safe\") {\n            let length := add(mload(tail), 1)\n            let outputCursor := mload(0x40)\n            array := outputCursor\n            let outputEnd := add(outputCursor, add(0x20, mul(length, 0x20)))\n            mstore(0x40, outputEnd)\n\n            mstore(outputCursor, length)\n            mstore(add(outputCursor, 0x20), a)\n\n            for {\n                outputCursor := add(outputCursor, 0x40)\n                let inputCursor := add(tail, 0x20)\n            } lt(outputCursor, outputEnd) {\n                outputCursor := add(outputCursor, 0x20)\n                inputCursor := add(inputCursor, 0x20)\n            } { mstore(outputCursor, mload(inputCursor)) }\n        }\n    }\n\n    /// Building arrays from literal components is a common task that introduces\n    /// boilerplate that is either inefficient or error prone.\n    /// @param a The first item of the new array.\n    /// @param b The second item of the new array.\n    /// @param tail The tail of the new array.\n    /// @return array The new array.\n    function arrayFrom(uint256 a, uint256 b, uint256[] memory tail) internal pure returns (uint256[] memory array) {\n        assembly (\"memory-safe\") {\n            let length := add(mload(tail), 2)\n            let outputCursor := mload(0x40)\n            array := outputCursor\n            let outputEnd := add(outputCursor, add(0x20, mul(length, 0x20)))\n            mstore(0x40, outputEnd)\n\n            mstore(outputCursor, length)\n            mstore(add(outputCursor, 0x20), a)\n            mstore(add(outputCursor, 0x40), b)\n\n            for {\n                outputCursor := add(outputCursor, 0x60)\n                let inputCursor := add(tail, 0x20)\n            } lt(outputCursor, outputEnd) {\n                outputCursor := add(outputCursor, 0x20)\n                inputCursor := add(inputCursor, 0x20)\n            } { mstore(outputCursor, mload(inputCursor)) }\n        }\n    }\n\n    /// Solidity provides no way to change the length of in-memory arrays but\n    /// it also does not deallocate memory ever. It is always safe to shrink an\n    /// array that has already been allocated, with the caveat that the\n    /// truncated items will effectively become inaccessible regions of memory.\n    /// That is to say, we deliberately \"leak\" the truncated items, but that is\n    /// no worse than Solidity's native behaviour of leaking everything always.\n    /// The array is MUTATED in place so there is no return value and there is\n    /// no new allocation or copying of data either.\n    /// @param array The array to truncate.\n    /// @param newLength The new length of the array after truncation.\n    function truncate(uint256[] memory array, uint256 newLength) internal pure {\n        if (newLength > array.length) {\n            revert OutOfBoundsTruncate(array.length, newLength);\n        }\n        assembly (\"memory-safe\") {\n            mstore(array, newLength)\n        }\n    }\n\n    /// Extends `base_` with `extend_` by allocating only an additional\n    /// `extend_.length` words onto `base_` and copying only `extend_` if\n    /// possible. If `base_` is large this MAY be significantly more efficient\n    /// than allocating `base_.length + extend_.length` for an entirely new array\n    /// and copying both `base_` and `extend_` into the new array one item at a\n    /// time in Solidity.\n    ///\n    /// The efficient version of extension is only possible if the free memory\n    /// pointer sits at the end of the base array at the moment of extension. If\n    /// there is allocated memory after the end of base then extension will\n    /// require copying both the base and extend arays to a new region of memory.\n    /// The caller is responsible for optimising code paths to avoid additional\n    /// allocations.\n    ///\n    /// This function is UNSAFE because the base array IS MUTATED DIRECTLY by\n    /// some code paths AND THE FINAL RETURN ARRAY MAY POINT TO THE SAME REGION\n    /// OF MEMORY. It is NOT POSSIBLE to reliably see this behaviour from the\n    /// caller in all cases as the Solidity compiler optimisations may switch the\n    /// caller between the allocating and non-allocating logic due to subtle\n    /// optimisation reasons. To use this function safely THE CALLER MUST NOT USE\n    /// THE BASE ARRAY AND MUST USE THE RETURNED ARRAY ONLY. It is safe to use\n    /// the extend array after calling this function as it is never mutated, it\n    /// is only copied from.\n    ///\n    /// @param b The base integer array that will be extended by `e`.\n    /// @param e The extend integer array that extends `b`.\n    /// @return extended The extended array of `b` extended by `e`.\n    function unsafeExtend(uint256[] memory b, uint256[] memory e) internal pure returns (uint256[] memory extended) {\n        assembly (\"memory-safe\") {\n            // Slither doesn't recognise assembly function names as mixed case\n            // even if they are.\n            // https://github.com/crytic/slither/issues/1815\n            //slither-disable-next-line naming-convention\n            function extendInline(base, extend) -> baseAfter {\n                let outputCursor := mload(0x40)\n                let baseLength := mload(base)\n                let baseEnd := add(base, add(0x20, mul(baseLength, 0x20)))\n\n                // If base is NOT the last thing in allocated memory, allocate,\n                // copy and recurse.\n                switch eq(outputCursor, baseEnd)\n                case 0 {\n                    let newBase := outputCursor\n                    let newBaseEnd := add(newBase, sub(baseEnd, base))\n                    mstore(0x40, newBaseEnd)\n                    for { let inputCursor := base } lt(outputCursor, newBaseEnd) {\n                        inputCursor := add(inputCursor, 0x20)\n                        outputCursor := add(outputCursor, 0x20)\n                    } { mstore(outputCursor, mload(inputCursor)) }\n\n                    baseAfter := extendInline(newBase, extend)\n                }\n                case 1 {\n                    let totalLength_ := add(baseLength, mload(extend))\n                    let outputEnd_ := add(base, add(0x20, mul(totalLength_, 0x20)))\n                    mstore(base, totalLength_)\n                    mstore(0x40, outputEnd_)\n                    for { let inputCursor := add(extend, 0x20) } lt(outputCursor, outputEnd_) {\n                        inputCursor := add(inputCursor, 0x20)\n                        outputCursor := add(outputCursor, 0x20)\n                    } { mstore(outputCursor, mload(inputCursor)) }\n\n                    baseAfter := base\n                }\n            }\n\n            extended := extendInline(b, e)\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/rain.lib.memkv/src/lib/LibMemoryKV.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// Entrypoint into the key/value store. Is a mutable pointer to the head of the\n/// linked list. Initially points to `0` for an empty list. The total word count\n/// of all inserts is also encoded alongside the pointer to allow efficient O(1)\n/// memory allocation for a `uint256[]` in the case of a final snapshot/export.\ntype MemoryKV is uint256;\n\n/// The key associated with the value for each item in the store.\ntype MemoryKVKey is uint256;\n\n/// The value associated with the key for each item in the store.\ntype MemoryKVVal is uint256;\n\n/// @title LibMemoryKV\nlibrary LibMemoryKV {\n    /// Gets the value associated with a given key.\n    /// The value returned will be `0` if the key exists and was set to zero OR\n    /// the key DOES NOT exist, i.e. was never set.\n    ///\n    /// The caller MUST check the `exists` flag to disambiguate between zero\n    /// values and unset keys.\n    ///\n    /// @param kv The entrypoint to the key/value store.\n    /// @param key The key to lookup a `value` for.\n    /// @return exists `0` if the key was not found. The `value` MUST NOT be\n    /// used if the `key` does not exist.\n    /// @return value The value for the `key`, if it exists, else `0`. MAY BE `0`\n    /// even if the `key` exists. It is possible to set any key to a `0` value.\n    function get(MemoryKV kv, MemoryKVKey key) internal pure returns (uint256 exists, MemoryKVVal value) {\n        assembly (\"memory-safe\") {\n            // Hash to find the internal linked list to walk.\n            // Hash logic MUST match set.\n            mstore(0, key)\n            let bitOffset := mul(mod(keccak256(0, 0x20), 15), 0x10)\n\n            // Loop until k found or give up if pointer is zero.\n            for { let pointer := and(shr(bitOffset, kv), 0xFFFF) } iszero(iszero(pointer)) {\n                pointer := mload(add(pointer, 0x40))\n            } {\n                if eq(key, mload(pointer)) {\n                    exists := 1\n                    value := mload(add(pointer, 0x20))\n                    break\n                }\n            }\n        }\n    }\n\n    /// Upserts a value in the set by its key. I.e. if the key exists then the\n    /// associated value will be mutated in place, else a new key/value pair will\n    /// be inserted. The key/value store pointer will be mutated and returned as\n    /// it MAY point to a new list item in memory.\n    /// @param kv The key/value store pointer to modify.\n    /// @param key The key to upsert against.\n    /// @param value The value to associate with the upserted key.\n    /// @return The final value of `kv` as it MAY be modified if the upsert\n    /// resulted in an insert operation.\n    function set(MemoryKV kv, MemoryKVKey key, MemoryKVVal value) internal pure returns (MemoryKV) {\n        assembly (\"memory-safe\") {\n            // Hash to spread inserts across internal lists.\n            // This MUST remain in sync with `get` logic.\n            mstore(0, key)\n            let bitOffset := mul(mod(keccak256(0, 0x20), 15), 0x10)\n\n            // Set aside the starting pointer as we'll need to include it in any\n            // newly inserted linked list items.\n            let startPointer := and(shr(bitOffset, kv), 0xFFFF)\n\n            // Find a key match then break so that we populate a nonzero pointer.\n            let pointer := startPointer\n            for {} iszero(iszero(pointer)) { pointer := mload(add(pointer, 0x40)) } {\n                if eq(key, mload(pointer)) { break }\n            }\n\n            // If the pointer is nonzero we have to update the associated value\n            // directly, otherwise this is an insert operation.\n            switch iszero(pointer)\n            // Update.\n            case 0 { mstore(add(pointer, 0x20), value) }\n            // Insert.\n            default {\n                // Allocate 3 words of memory.\n                pointer := mload(0x40)\n                mstore(0x40, add(pointer, 0x60))\n\n                // Write key/value/pointer.\n                mstore(pointer, key)\n                mstore(add(pointer, 0x20), value)\n                mstore(add(pointer, 0x40), startPointer)\n\n                // Update total stored word count.\n                let length := add(shr(0xf0, kv), 2)\n\n                //slither-disable-next-line incorrect-shift\n                kv := or(shl(0xf0, length), and(kv, not(shl(0xf0, 0xFFFF))))\n\n                // kv must point to new insertion.\n                //slither-disable-next-line incorrect-shift\n                kv :=\n                    or(\n                        shl(bitOffset, pointer),\n                        // Mask out the old pointer\n                        and(kv, not(shl(bitOffset, 0xFFFF)))\n                    )\n            }\n        }\n        return kv;\n    }\n\n    /// Export/snapshot the underlying linked list of the key/value store into\n    /// a standard `uint256[]`. Reads the total length to preallocate the\n    /// `uint256[]` then bisects the bits of the `kv` to find non-zero pointers\n    /// to linked lists, walking each found list to the end to extract all\n    /// values. As a single `kv` has 15 slots for pointers to linked lists it is\n    /// likely for smallish structures that many slots can simply be skipped, so\n    /// the bisect approach can save ~1-1.5k gas vs. a naive linear loop over\n    /// all 15 slots for every export.\n    ///\n    /// Note this is a one time export, if the key/value store is subsequently\n    /// mutated the built array will not reflect these mutations.\n    ///\n    /// @param kv The entrypoint into the key/value store.\n    /// @return array All the keys and values copied pairwise into a `uint256[]`.\n    /// Slither is not wrong about the cyclomatic complexity but I don't know\n    /// another way to implement the bisect and keep the gas savings.\n    //slither-disable-next-line cyclomatic-complexity\n    function toUint256Array(MemoryKV kv) internal pure returns (uint256[] memory array) {\n        uint256 mask16 = type(uint16).max;\n        uint256 mask32 = type(uint32).max;\n        uint256 mask64 = type(uint64).max;\n        uint256 mask128 = type(uint128).max;\n        assembly (\"memory-safe\") {\n            // Manually create an `uint256[]`.\n            // No need to zero out memory as we're about to write to it.\n            array := mload(0x40)\n            let length := shr(0xf0, kv)\n            mstore(0x40, add(array, add(0x20, mul(length, 0x20))))\n            mstore(array, length)\n\n            // Known false positives in slither\n            // https://github.com/crytic/slither/issues/1815\n            //slither-disable-next-line naming-convention\n            function copyFromPtr(cursor, pointer) -> end {\n                for {} iszero(iszero(pointer)) {\n                    pointer := mload(add(pointer, 0x40))\n                    cursor := add(cursor, 0x40)\n                } {\n                    mstore(cursor, mload(pointer))\n                    mstore(add(cursor, 0x20), mload(add(pointer, 0x20)))\n                }\n                end := cursor\n            }\n\n            // Bisect.\n            // This crazy tree saves ~1-1.5k gas vs. a simple loop with larger\n            // relative savings for small-medium sized structures.\n            // The internal scoping blocks are to provide some safety against\n            // typos causing the incorrect symbol to be referenced by enforcing\n            // each symbol is as tightly scoped as it can be.\n            let cursor := add(array, 0x20)\n            {\n                // Remove the length from kv before iffing to save ~100 gas.\n                let p0 := shr(0x90, shl(0x10, kv))\n                if iszero(iszero(p0)) {\n                    {\n                        let p00 := shr(0x40, p0)\n                        if iszero(iszero(p00)) {\n                            {\n                                // This branch is a special case because we\n                                // already zeroed out the high bits which are\n                                // used by the length and are NOT a pointer.\n                                // We can skip processing where the pointer would\n                                // have been if it were not the length, and do\n                                // not need to scrub the high bits to move from\n                                // `p00` to `p0001`.\n                                let p0001 := shr(0x20, p00)\n                                if iszero(iszero(p0001)) { cursor := copyFromPtr(cursor, p0001) }\n                            }\n                            let p001 := and(mask32, p00)\n                            if iszero(iszero(p001)) {\n                                {\n                                    let p0010 := shr(0x10, p001)\n                                    if iszero(iszero(p0010)) { cursor := copyFromPtr(cursor, p0010) }\n                                }\n                                let p0011 := and(mask16, p001)\n                                if iszero(iszero(p0011)) { cursor := copyFromPtr(cursor, p0011) }\n                            }\n                        }\n                    }\n                    let p01 := and(mask64, p0)\n                    if iszero(iszero(p01)) {\n                        {\n                            let p010 := shr(0x20, p01)\n                            if iszero(iszero(p010)) {\n                                {\n                                    let p0100 := shr(0x10, p010)\n                                    if iszero(iszero(p0100)) { cursor := copyFromPtr(cursor, p0100) }\n                                }\n                                let p0101 := and(mask16, p010)\n                                if iszero(iszero(p0101)) { cursor := copyFromPtr(cursor, p0101) }\n                            }\n                        }\n\n                        let p011 := and(mask32, p01)\n                        if iszero(iszero(p011)) {\n                            {\n                                let p0110 := shr(0x10, p011)\n                                if iszero(iszero(p0110)) { cursor := copyFromPtr(cursor, p0110) }\n                            }\n\n                            let p0111 := and(mask16, p011)\n                            if iszero(iszero(p0111)) { cursor := copyFromPtr(cursor, p0111) }\n                        }\n                    }\n                }\n            }\n\n            {\n                let p1 := and(mask128, kv)\n                if iszero(iszero(p1)) {\n                    {\n                        let p10 := shr(0x40, p1)\n                        if iszero(iszero(p10)) {\n                            {\n                                let p100 := shr(0x20, p10)\n                                if iszero(iszero(p100)) {\n                                    {\n                                        let p1000 := shr(0x10, p100)\n                                        if iszero(iszero(p1000)) { cursor := copyFromPtr(cursor, p1000) }\n                                    }\n                                    let p1001 := and(mask16, p100)\n                                    if iszero(iszero(p1001)) { cursor := copyFromPtr(cursor, p1001) }\n                                }\n                            }\n                            let p101 := and(mask32, p10)\n                            if iszero(iszero(p101)) {\n                                {\n                                    let p1010 := shr(0x10, p101)\n                                    if iszero(iszero(p1010)) { cursor := copyFromPtr(cursor, p1010) }\n                                }\n                                let p1011 := and(mask16, p101)\n                                if iszero(iszero(p1011)) { cursor := copyFromPtr(cursor, p1011) }\n                            }\n                        }\n                    }\n                    let p11 := and(mask64, p1)\n                    if iszero(iszero(p11)) {\n                        {\n                            let p110 := shr(0x20, p11)\n                            if iszero(iszero(p110)) {\n                                {\n                                    let p1100 := shr(0x10, p110)\n                                    if iszero(iszero(p1100)) { cursor := copyFromPtr(cursor, p1100) }\n                                }\n                                let p1101 := and(mask16, p110)\n                                if iszero(iszero(p1101)) { cursor := copyFromPtr(cursor, p1101) }\n                            }\n                        }\n\n                        let p111 := and(mask32, p11)\n                        if iszero(iszero(p111)) {\n                            {\n                                let p1110 := shr(0x10, p111)\n                                if iszero(iszero(p1110)) { cursor := copyFromPtr(cursor, p1110) }\n                            }\n\n                            let p1111 := and(mask16, p111)\n                            if iszero(iszero(p1111)) { cursor := copyFromPtr(cursor, p1111) }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.factory/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/interface/IInterpreterV1.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"./IInterpreterStoreV1.sol\";\n\n/// @dev The index of a source within a deployed expression that can be evaluated\n/// by an `IInterpreterV1`. MAY be an entrypoint or the index of a source called\n/// internally such as by the `call` opcode.\ntype SourceIndex is uint16;\n\n/// @dev Encoded information about a specific evaluation including the expression\n/// address onchain, entrypoint and expected return values.\ntype EncodedDispatch is uint256;\n\n/// @dev The namespace for state changes as requested by the calling contract.\n/// The interpreter MUST apply this namespace IN ADDITION to namespacing by\n/// caller etc.\ntype StateNamespace is uint256;\n\n/// @dev Additional bytes that can be used to configure a single opcode dispatch.\n/// Commonly used to specify the number of inputs to a variadic function such\n/// as addition or multiplication.\ntype Operand is uint256;\n\n/// @dev The default state namespace MUST be used when a calling contract has no\n/// particular opinion on or need for dynamic namespaces.\nStateNamespace constant DEFAULT_STATE_NAMESPACE = StateNamespace.wrap(0);\n\n/// @title IInterpreterV1\n/// Interface into a standard interpreter that supports:\n///\n/// - evaluating `view` logic deployed onchain by an `IExpressionDeployerV1`\n/// - receiving arbitrary `uint256[][]` supporting context to be made available\n///   to the evaluated logic\n/// - handling subsequent state changes in bulk in response to evaluated logic\n/// - namespacing state changes according to the caller's preferences to avoid\n///   unwanted key collisions\n/// - exposing its internal function pointers to support external precompilation\n///   of logic for more gas efficient runtime evaluation by the interpreter\n///\n/// The interface is designed to be stable across many versions and\n/// implementations of an interpreter, balancing minimalism with features\n/// required for a general purpose onchain interpreted compute environment.\n///\n/// The security model of an interpreter is that it MUST be resilient to\n/// malicious expressions even if they dispatch arbitrary internal function\n/// pointers during an eval. The interpreter MAY return garbage or exhibit\n/// undefined behaviour or error during an eval, _provided that no state changes\n/// are persisted_ e.g. in storage, such that only the caller that specifies the\n/// malicious expression can be negatively impacted by the result. In turn, the\n/// caller must guard itself against arbitrarily corrupt/malicious reverts and\n/// return values from any interpreter that it requests an expression from. And\n/// so on and so forth up to the externally owned account (EOA) who signs the\n/// transaction and agrees to a specific combination of contracts, expressions\n/// and interpreters, who can presumably make an informed decision about which\n/// ones to trust to get the job done.\n///\n/// The state changes for an interpreter are expected to be produces by an `eval`\n/// and passed to the `IInterpreterStoreV1` returned by the eval, as-is by the\n/// caller, after the caller has had an opportunity to apply their own\n/// intermediate logic such as reentrancy defenses against malicious\n/// interpreters. The interpreter is free to structure the state changes however\n/// it wants but MUST guard against the calling contract corrupting the changes\n/// between `eval` and `set`. For example a store could sandbox storage writes\n/// per-caller so that a malicious caller can only damage their own state\n/// changes, while honest callers respect, benefit from and are protected by the\n/// interpreter store's state change handling.\n///\n/// The two step eval-state model allows eval to be read-only which provides\n/// security guarantees for the caller such as no stateful reentrancy, either\n/// from the interpreter or some contract interface used by some word, while\n/// still allowing for storage writes. As the storage writes happen on the\n/// interpreter rather than the caller (c.f. delegate call) the caller DOES NOT\n/// need to trust the interpreter, which allows for permissionless selection of\n/// interpreters by end users. Delegate call always implies an admin key on the\n/// caller because the delegatee contract can write arbitrarily to the state of\n/// the delegator, which severely limits the generality of contract composition.\ninterface IInterpreterV1 {\n    /// Exposes the function pointers as `uint16` values packed into a single\n    /// `bytes` in the same order as they would be indexed into by opcodes. For\n    /// example, if opcode `2` should dispatch function at position `0x1234` then\n    /// the start of the returned bytes would be `0xXXXXXXXX1234` where `X` is\n    /// a placeholder for the function pointers of opcodes `0` and `1`.\n    ///\n    /// `IExpressionDeployerV1` contracts use these function pointers to\n    /// \"compile\" the expression into something that an interpreter can dispatch\n    /// directly without paying gas to lookup the same at runtime. As the\n    /// validity of any integrity check and subsequent dispatch is highly\n    /// sensitive to both the function pointers and overall bytecode of the\n    /// interpreter, `IExpressionDeployerV1` contracts SHOULD implement guards\n    /// against accidentally being deployed onchain paired against an unknown\n    /// interpreter. It is very easy for an apparent compatible pairing to be\n    /// subtly and critically incompatible due to addition/removal/reordering of\n    /// opcodes and compiler optimisations on the interpreter bytecode.\n    ///\n    /// This MAY return different values during construction vs. all other times\n    /// after the interpreter has been successfully deployed onchain. DO NOT rely\n    /// on function pointers reported during contract construction.\n    function functionPointers() external view returns (bytes memory);\n\n    /// The raison d'etre for an interpreter. Given some expression and per-call\n    /// additional contextual data, produce a stack of results and a set of state\n    /// changes that the caller MAY OPTIONALLY pass back to be persisted by a\n    /// call to `IInterpreterStoreV1.set`.\n    /// @param store The storage contract that the returned key/value pairs\n    /// MUST be passed to IF the calling contract is in a non-static calling\n    /// context. Static calling contexts MUST pass `address(0)`.\n    /// @param namespace The state namespace that will be fully qualified by the\n    /// interpreter at runtime in order to perform gets on the underlying store.\n    /// MUST be the same namespace passed to the store by the calling contract\n    /// when sending the resulting key/value items to storage.\n    /// @param dispatch All the information required for the interpreter to load\n    /// an expression, select an entrypoint and return the values expected by the\n    /// caller. The interpreter MAY encode dispatches differently to\n    /// `LibEncodedDispatch` but this WILL negatively impact compatibility for\n    /// calling contracts that hardcode the encoding logic.\n    /// @param context A 2-dimensional array of data that can be indexed into at\n    /// runtime by the interpreter. The calling contract is responsible for\n    /// ensuring the authenticity and completeness of context data. The\n    /// interpreter MUST revert at runtime if an expression attempts to index\n    /// into some context value that is not provided by the caller. This implies\n    /// that context reads cannot be checked for out of bounds reads at deploy\n    /// time, as the runtime context MAY be provided in a different shape to what\n    /// the expression is expecting.\n    /// Same as `eval` but allowing the caller to specify a namespace under which\n    /// the state changes will be applied. The interpeter MUST ensure that keys\n    /// will never collide across namespaces, even if, for example:\n    ///\n    /// - The calling contract is malicious and attempts to craft a collision\n    ///   with state changes from another contract\n    /// - The expression is malicious and attempts to craft a collision with\n    ///   other expressions evaluated by the same calling contract\n    ///\n    /// A malicious entity MAY have access to significant offchain resources to\n    /// attempt to precompute key collisions through brute force. The collision\n    /// resistance of namespaces should be comparable or equivalent to the\n    /// collision resistance of the hashing algorithms employed by the blockchain\n    /// itself, such as the design of `mapping` in Solidity that hashes each\n    /// nested key to produce a collision resistant compound key.\n    /// @return stack The list of values produced by evaluating the expression.\n    /// MUST NOT be longer than the maximum length specified by `dispatch`, if\n    /// applicable.\n    /// @return kvs A list of pairwise key/value items to be saved in the store.\n    function eval(\n        IInterpreterStoreV1 store,\n        StateNamespace namespace,\n        EncodedDispatch dispatch,\n        uint256[][] calldata context\n    ) external view returns (uint256[] memory stack, uint256[] memory kvs);\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/rain.solmem/src/lib/LibMemCpy.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"./LibPointer.sol\";\n\nlibrary LibMemCpy {\n    /// Copy an arbitrary number of bytes from one location in memory to another.\n    /// As we can only read/write bytes in 32 byte chunks we first have to loop\n    /// over 32 byte values to copy then handle any unaligned remaining data. The\n    /// remaining data will be appropriately masked with the existing data in the\n    /// final chunk so as to not write past the desired length. Note that the\n    /// final unaligned write will be more gas intensive than the prior aligned\n    /// writes. The writes are completely unsafe, the caller MUST ensure that\n    /// sufficient memory is allocated and reading/writing the requested number\n    /// of bytes from/to the requested locations WILL NOT corrupt memory in the\n    /// opinion of solidity or other subsequent read/write operations.\n    /// @param sourceCursor The starting pointer to read from.\n    /// @param targetCursor The starting pointer to write to.\n    /// @param length The number of bytes to read/write.\n    function unsafeCopyBytesTo(Pointer sourceCursor, Pointer targetCursor, uint256 length) internal pure {\n        assembly (\"memory-safe\") {\n            // Precalculating the end here, rather than tracking the remaining\n            // length each iteration uses relatively more gas for less data, but\n            // scales better for more data. Copying 1-2 words is ~30 gas more\n            // expensive but copying 3+ words favours a precalculated end point\n            // increasingly for more data.\n            let m := mod(length, 0x20)\n            let end := add(sourceCursor, sub(length, m))\n            for {} lt(sourceCursor, end) {\n                sourceCursor := add(sourceCursor, 0x20)\n                targetCursor := add(targetCursor, 0x20)\n            } { mstore(targetCursor, mload(sourceCursor)) }\n\n            if iszero(iszero(m)) {\n                //slither-disable-next-line incorrect-shift\n                let mask_ := shr(mul(m, 8), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n                // preserve existing bytes\n                mstore(\n                    targetCursor,\n                    or(\n                        // input\n                        and(mload(sourceCursor), not(mask_)),\n                        and(mload(targetCursor), mask_)\n                    )\n                )\n            }\n        }\n    }\n\n    /// Copies `length` `uint256` values starting from `source` to `target`\n    /// with NO attempt to check that this is safe to do so. The caller MUST\n    /// ensure that there exists allocated memory at `target` in which it is\n    /// safe and appropriate to copy `length * 32` bytes to. Anything that was\n    /// already written to memory at `[target:target+(length * 32 bytes)]`\n    /// will be overwritten.\n    /// There is no return value as memory is modified directly.\n    /// @param source The starting position in memory that data will be copied\n    /// from.\n    /// @param target The starting position in memory that data will be copied\n    /// to.\n    /// @param length The number of 32 byte (i.e. `uint256`) words that will\n    /// be copied.\n    function unsafeCopyWordsTo(Pointer source, Pointer target, uint256 length) internal pure {\n        assembly (\"memory-safe\") {\n            for { let end_ := add(source, mul(0x20, length)) } lt(source, end_) {\n                source := add(source, 0x20)\n                target := add(target, 0x20)\n            } { mstore(target, mload(source)) }\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/bytecode/LibBytecode.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.19;\n\nimport {LibPointer, Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {LibBytes} from \"rain.solmem/lib/LibBytes.sol\";\nimport {LibMemCpy} from \"rain.solmem/lib/LibMemCpy.sol\";\n\n/// Thrown when a bytecode source index is out of bounds.\n/// @param bytecode The bytecode that was inspected.\n/// @param sourceIndex The source index that was out of bounds.\nerror SourceIndexOutOfBounds(bytes bytecode, uint256 sourceIndex);\n\n/// Thrown when a bytecode reports itself as 0 sources but has more than 1 byte.\n/// @param bytecode The bytecode that was inspected.\nerror UnexpectedSources(bytes bytecode);\n\n/// Thrown when bytes are discovered between the offsets and the sources.\n/// @param bytecode The bytecode that was inspected.\nerror UnexpectedTrailingOffsetBytes(bytes bytecode);\n\n/// Thrown when the end of a source as self reported by its header doesnt match\n/// the start of the next source or the end of the bytecode.\n/// @param bytecode The bytecode that was inspected.\nerror TruncatedSource(bytes bytecode);\n\n/// Thrown when the offset to a source points to a location that cannot fit a\n/// header before the start of the next source or the end of the bytecode.\n/// @param bytecode The bytecode that was inspected.\nerror TruncatedHeader(bytes bytecode);\n\n/// Thrown when the bytecode is truncated before the end of the header offsets.\n/// @param bytecode The bytecode that was inspected.\nerror TruncatedHeaderOffsets(bytes bytecode);\n\n/// Thrown when the stack sizings, allocation, inputs and outputs, are not\n/// monotonically increasing.\n/// @param bytecode The bytecode that was inspected.\n/// @param relativeOffset The relative offset of the source that was inspected.\nerror StackSizingsNotMonotonic(bytes bytecode, uint256 relativeOffset);\n\n/// @title LibBytecode\n/// @notice A library for inspecting the bytecode of an expression. Largely\n/// focused on reading the source headers rather than the opcodes themselves.\n/// Designed to be efficient enough to be used in the interpreter directly.\n/// As such, it is not particularly safe, notably it always assumes that the\n/// headers are not lying about the structure and runtime behaviour of the\n/// bytecode. This is by design as it allows much more simple, efficient and\n/// decoupled implementation of authoring/parsing logic, which makes the author\n/// of an expression responsible for producing well formed bytecode, such as\n/// balanced LHS/RHS stacks. The deployment integrity checks are responsible for\n/// checking that the headers match the structure and behaviour of the bytecode.\nlibrary LibBytecode {\n    using LibPointer for Pointer;\n    using LibBytes for bytes;\n    using LibMemCpy for Pointer;\n\n    /// The number of sources in the bytecode.\n    /// If the bytecode is empty, returns 0.\n    /// Otherwise, returns the first byte of the bytecode, which is the number\n    /// of sources.\n    /// Implies that 0x and 0x00 are equivalent, both having 0 sources. For this\n    /// reason, contracts that handle bytecode MUST NOT rely on simple data\n    /// length checks to determine if the bytecode is empty or not.\n    /// DOES NOT check the integrity or even existence of the sources.\n    /// @param bytecode The bytecode to inspect.\n    /// @return count The number of sources in the bytecode.\n    function sourceCount(bytes memory bytecode) internal pure returns (uint256 count) {\n        if (bytecode.length == 0) {\n            return 0;\n        }\n        assembly {\n            // The first byte of rain bytecode is the count of how many sources\n            // there are.\n            count := byte(0, mload(add(bytecode, 0x20)))\n        }\n    }\n\n    /// Checks the structural integrity of the bytecode from the perspective of\n    /// potential out of bounds reads. Will revert if the bytecode is not\n    /// well-formed. This check MUST be done BEFORE any attempts at per-opcode\n    /// integrity checks, as the per-opcode checks assume that the headers define\n    /// valid regions in memory to iterate over.\n    ///\n    /// Checks:\n    /// - The offsets are populated according to the source count.\n    /// - The offsets point to positions within the bytecode `bytes`.\n    /// - There exists at least the 4 byte header for each source at the offset,\n    ///   within the bounds of the bytecode `bytes`.\n    /// - The number of opcodes specified in the header of each source locates\n    ///   the end of the source exactly at either the offset of the next source\n    ///   or the end of the bytecode `bytes`.\n    function checkNoOOBPointers(bytes memory bytecode) internal pure {\n        unchecked {\n            uint256 count = sourceCount(bytecode);\n            // The common case is that there are more than 0 sources.\n            if (count > 0) {\n                uint256 sourcesRelativeStart = 1 + count * 2;\n                if (sourcesRelativeStart > bytecode.length) {\n                    revert TruncatedHeaderOffsets(bytecode);\n                }\n                uint256 sourcesStart;\n                assembly (\"memory-safe\") {\n                    sourcesStart := add(bytecode, add(0x20, sourcesRelativeStart))\n                }\n\n                // Start at the end of the bytecode and work backwards. Find the\n                // last unchecked relative offset, follow it, read the opcode\n                // count from the header, and check that ends at the end cursor.\n                // Set the end cursor to the relative offset then repeat until\n                // there are no more unchecked relative offsets. The endCursor\n                // as a relative offset must be 0 at the end of this process\n                // (i.e. the first relative offset is always 0).\n                uint256 endCursor;\n                assembly (\"memory-safe\") {\n                    endCursor := add(bytecode, add(0x20, mload(bytecode)))\n                }\n                // This cursor points at the 2 byte relative offset that we need\n                // to check next.\n                uint256 uncheckedOffsetCursor;\n                uint256 end;\n                assembly (\"memory-safe\") {\n                    uncheckedOffsetCursor := add(bytecode, add(0x21, mul(sub(count, 1), 2)))\n                    end := add(bytecode, 0x21)\n                }\n\n                while (uncheckedOffsetCursor >= end) {\n                    // Read the relative offset from the bytecode.\n                    uint256 relativeOffset;\n                    assembly (\"memory-safe\") {\n                        relativeOffset := shr(0xF0, mload(uncheckedOffsetCursor))\n                    }\n                    uint256 absoluteOffset = sourcesStart + relativeOffset;\n\n                    // Check that the 4 byte header is within the upper bound\n                    // established by the end cursor before attempting to read\n                    // from it.\n                    uint256 headerEnd = absoluteOffset + 4;\n                    if (headerEnd > endCursor) {\n                        revert TruncatedHeader(bytecode);\n                    }\n\n                    // The ops count is the first byte of the header.\n                    uint256 opsCount;\n                    {\n                        // The stack allocation, inputs, and outputs are the next\n                        // 3 bytes of the header. We can't know exactly what they\n                        // need to be according to the opcodes without checking\n                        // every opcode implementation, but we can check that\n                        // they satisfy the invariant\n                        // `inputs <= outputs <= stackAllocation`.\n                        // Note that the outputs may include the inputs, as the\n                        // outputs is merely the final stack size.\n                        uint256 stackAllocation;\n                        uint256 inputs;\n                        uint256 outputs;\n                        assembly (\"memory-safe\") {\n                            let data := mload(absoluteOffset)\n                            opsCount := byte(0, data)\n                            stackAllocation := byte(1, data)\n                            inputs := byte(2, data)\n                            outputs := byte(3, data)\n                        }\n\n                        if (inputs > outputs || outputs > stackAllocation) {\n                            revert StackSizingsNotMonotonic(bytecode, relativeOffset);\n                        }\n                    }\n\n                    // The ops count is the number of 4 byte opcodes in the\n                    // source. Check that the end of the source is at the end\n                    // cursor.\n                    uint256 sourceEnd = headerEnd + opsCount * 4;\n                    if (sourceEnd != endCursor) {\n                        revert TruncatedSource(bytecode);\n                    }\n\n                    // Move the end cursor to the start of the header.\n                    endCursor = absoluteOffset;\n                    // Move the unchecked offset cursor to the previous offset.\n                    uncheckedOffsetCursor -= 2;\n                }\n\n                // If the end cursor is not pointing at the absolute start of the\n                // sources, then somehow the bytecode has malformed data between\n                // the offsets and the sources.\n                if (endCursor != sourcesStart) {\n                    revert UnexpectedTrailingOffsetBytes(bytecode);\n                }\n            } else {\n                // If there are no sources the bytecode is either 0 length or a\n                // single 0 byte, which we already implicity checked by reaching\n                // this code path. Ensure the bytecode has no trailing bytes.\n                if (bytecode.length > 1) {\n                    revert UnexpectedSources(bytecode);\n                }\n            }\n        }\n    }\n\n    /// The relative byte offset of a source in the bytecode.\n    /// This is the offset from the start of the first source header, which is\n    /// after the source count byte and the source offsets.\n    /// This function DOES NOT check that the relative offset is within the\n    /// bounds of the bytecode. Callers MUST `checkNoOOBPointers` BEFORE\n    /// attempting to traverse the bytecode, otherwise the relative offset MAY\n    /// point to memory outside the bytecode `bytes`.\n    /// @param bytecode The bytecode to inspect.\n    /// @param sourceIndex The index of the source to inspect.\n    /// @return offset The relative byte offset of the source in the bytecode.\n    function sourceRelativeOffset(bytes memory bytecode, uint256 sourceIndex) internal pure returns (uint256 offset) {\n        // If the source index requested is out of bounds, revert.\n        if (sourceIndex >= sourceCount(bytecode)) {\n            revert SourceIndexOutOfBounds(bytecode, sourceIndex);\n        }\n        assembly {\n            // After the first byte, all the relative offset pointers are\n            // stored sequentially as 16 bit values.\n            offset := and(mload(add(add(bytecode, 3), mul(sourceIndex, 2))), 0xFFFF)\n        }\n    }\n\n    /// The absolute byte pointer of a source in the bytecode. Points to the\n    /// header of the source, NOT the first opcode.\n    /// This function DOES NOT check that the source index is within the bounds\n    /// of the bytecode. Callers MUST `checkNoOOBPointers` BEFORE attempting to\n    /// traverse the bytecode, otherwise the relative offset MAY point to memory\n    /// outside the bytecode `bytes`.\n    /// @param bytecode The bytecode to inspect.\n    /// @param sourceIndex The index of the source to inspect.\n    /// @return pointer The absolute byte pointer of the source in the bytecode.\n    function sourcePointer(bytes memory bytecode, uint256 sourceIndex) internal pure returns (Pointer pointer) {\n        unchecked {\n            uint256 sourcesStartOffset = 1 + sourceCount(bytecode) * 2;\n            uint256 offset = sourceRelativeOffset(bytecode, sourceIndex);\n            assembly {\n                pointer := add(add(add(bytecode, 0x20), sourcesStartOffset), offset)\n            }\n        }\n    }\n\n    /// The number of opcodes in a source.\n    /// This function DOES NOT check that the source index is within the bounds\n    /// of the bytecode. Callers MUST `checkNoOOBPointers` BEFORE attempting to\n    /// traverse the bytecode, otherwise the relative offset MAY point to memory\n    /// outside the bytecode `bytes`.\n    /// @param bytecode The bytecode to inspect.\n    /// @param sourceIndex The index of the source to inspect.\n    /// @return opsCount The number of opcodes in the source.\n    function sourceOpsCount(bytes memory bytecode, uint256 sourceIndex) internal pure returns (uint256 opsCount) {\n        unchecked {\n            Pointer pointer = sourcePointer(bytecode, sourceIndex);\n            assembly (\"memory-safe\") {\n                opsCount := byte(0, mload(pointer))\n            }\n        }\n    }\n\n    /// The number of stack slots allocated by a source. This is the number of\n    /// 32 byte words that MUST be allocated for the stack for the given source\n    /// index to avoid memory corruption when executing the source.\n    /// This function DOES NOT check that the source index is within the bounds\n    /// of the bytecode. Callers MUST `checkNoOOBPointers` BEFORE attempting to\n    /// traverse the bytecode, otherwise the relative offset MAY point to memory\n    /// outside the bytecode `bytes`.\n    /// @param bytecode The bytecode to inspect.\n    /// @param sourceIndex The index of the source to inspect.\n    /// @return allocation The number of stack slots allocated by the source.\n    function sourceStackAllocation(bytes memory bytecode, uint256 sourceIndex)\n        internal\n        pure\n        returns (uint256 allocation)\n    {\n        unchecked {\n            Pointer pointer = sourcePointer(bytecode, sourceIndex);\n            assembly (\"memory-safe\") {\n                allocation := byte(1, mload(pointer))\n            }\n        }\n    }\n\n    /// The number of inputs and outputs of a source.\n    /// This function DOES NOT check that the source index is within the bounds\n    /// of the bytecode. Callers MUST `checkNoOOBPointers` BEFORE attempting to\n    /// traverse the bytecode, otherwise the relative offset MAY point to memory\n    /// outside the bytecode `bytes`.\n    /// Note that both the inputs and outputs are always returned togther, this\n    /// is because the caller SHOULD be checking both together whenever using\n    /// some bytecode. Returning two values is more efficient than two separate\n    /// function calls.\n    /// @param bytecode The bytecode to inspect.\n    /// @param sourceIndex The index of the source to inspect.\n    /// @return inputs The number of inputs of the source.\n    /// @return outputs The number of outputs of the source.\n    function sourceInputsOutputsLength(bytes memory bytecode, uint256 sourceIndex)\n        internal\n        pure\n        returns (uint256 inputs, uint256 outputs)\n    {\n        unchecked {\n            Pointer pointer = sourcePointer(bytecode, sourceIndex);\n            assembly (\"memory-safe\") {\n                let data := mload(pointer)\n                inputs := byte(2, data)\n                outputs := byte(3, data)\n            }\n        }\n    }\n\n    /// Backwards compatibility with the old way of representing sources.\n    /// Requires allocation and copying so it isn't particularly efficient, but\n    /// allows us to use the new bytecode format with old interpreter code. Not\n    /// recommended for production code but useful for testing.\n    function bytecodeToSources(bytes memory bytecode) internal pure returns (bytes[] memory) {\n        unchecked {\n            uint256 count = sourceCount(bytecode);\n            bytes[] memory sources = new bytes[](count);\n            for (uint256 i = 0; i < count; i++) {\n                // Skip over the prefix 4 bytes.\n                Pointer pointer = sourcePointer(bytecode, i).unsafeAddBytes(4);\n                uint256 length = sourceOpsCount(bytecode, i) * 4;\n                bytes memory source = new bytes(length);\n                pointer.unsafeCopyBytesTo(source.dataPointer(), length);\n                // Move the opcode index one byte for each opcode, into the input\n                // position, as legacly sources did not have input bytes.\n                assembly (\"memory-safe\") {\n                    for {\n                        let cursor := add(source, 0x20)\n                        let end := add(cursor, length)\n                    } lt(cursor, end) { cursor := add(cursor, 4) } {\n                        mstore8(add(cursor, 1), byte(0, mload(cursor)))\n                        mstore8(cursor, 0)\n                    }\n                }\n                sources[i] = source;\n            }\n            return sources;\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/rain.solmem/src/lib/LibBytes.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"./LibPointer.sol\";\n\n/// Thrown when asked to truncate data to a longer length.\n/// @param length Actual bytes length.\n/// @param truncate Attempted truncation length.\nerror TruncateError(uint256 length, uint256 truncate);\n\n/// @title LibBytes\n/// @notice Tools for working directly with memory in a Solidity compatible way.\nlibrary LibBytes {\n    /// Truncates bytes of data by mutating its length directly.\n    /// Any excess bytes are leaked\n    function truncate(bytes memory data, uint256 length) internal pure {\n        if (data.length < length) {\n            revert TruncateError(data.length, length);\n        }\n        assembly (\"memory-safe\") {\n            mstore(data, length)\n        }\n    }\n\n    /// Pointer to the data of a bytes array NOT the length prefix.\n    /// @param data Bytes to get the data pointer for.\n    /// @return pointer Pointer to the data of the bytes in memory.\n    function dataPointer(bytes memory data) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(data, 0x20)\n        }\n    }\n\n    /// Pointer to the start of a bytes array (the length prefix).\n    /// @param data Bytes to get the pointer to.\n    /// @return pointer Pointer to the start of the bytes data structure.\n    function startPointer(bytes memory data) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := data\n        }\n    }\n\n    /// Pointer to the end of some bytes.\n    ///\n    /// Note that this pointer MAY NOT BE ALIGNED, i.e. it MAY NOT point to the\n    /// start of a multiple of 32, UNLIKE the free memory pointer at 0x40.\n    ///\n    /// @param data Bytes to get the pointer to the end of.\n    /// @return pointer Pointer to the end of the bytes data structure.\n    function endDataPointer(bytes memory data) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(data, add(0x20, mload(data)))\n        }\n    }\n\n    /// Pointer to the end of the memory allocated for bytes.\n    ///\n    /// The allocator is ALWAYS aligned to whole words, i.e. 32 byte multiples,\n    /// for data structures allocated by Solidity. This includes `bytes` which\n    /// means that any time the length of some `bytes` is NOT a multiple of 32\n    /// the alloation will point past the end of the `bytes` data.\n    ///\n    /// There is no guarantee that the memory region between `endDataPointer`\n    /// and `endAllocatedPointer` is zeroed out. It is best to think of that\n    /// space as leaked garbage.\n    ///\n    /// Almost always, e.g. for the purpose of copying data between regions, you\n    /// will want `endDataPointer` rather than this function.\n    /// @param data Bytes to get the end of the allocated data region for.\n    /// @return pointer Pointer to the end of the allocated data region.\n    function endAllocatedPointer(bytes memory data) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(data, and(add(add(mload(data), 0x20), 0x1f), not(0x1f)))\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/rain.lib.typecast/src/LibConvert.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// @title LibConvert\n/// @notice Type conversions that require additional structural changes to\n/// complete safely. These are NOT mere type casts and involve additional\n/// reads and writes to complete, such as recalculating the length of an array.\n/// The convention \"toX\" is adopted from Rust to imply the additional costs and\n/// consumption of the source to produce the target.\nlibrary LibConvert {\n    /// Convert an array of integers to `bytes` data. This requires modifying\n    /// the length in situ as the integer array length is measured in 32 byte\n    /// increments while the length of `bytes` is the literal number of bytes.\n    ///\n    /// It is unsafe for the caller to use `us_` after it has been converted to\n    /// bytes because there is now two pointers to the same mutable data\n    /// structure AND the length prefix for the `uint256[]` version is corrupt.\n    ///\n    /// @param us_ The integer array to convert to `bytes`.\n    /// @return bytes_ The integer array converted to `bytes` data.\n    function unsafeToBytes(uint256[] memory us_) internal pure returns (bytes memory bytes_) {\n        assembly (\"memory-safe\") {\n            bytes_ := us_\n            // Length in bytes is 32x the length in uint256\n            mstore(bytes_, mul(0x20, mload(bytes_)))\n        }\n    }\n\n    /// Truncate `uint256[]` values down to `uint16[]` then pack this to `bytes`\n    /// without padding or length prefix. Unsafe because the starting `uint256`\n    /// values are not checked for overflow due to the truncation. The caller\n    /// MUST ensure that all values fit in `type(uint16).max` or that silent\n    /// overflow is safe.\n    /// @param us_ The `uint256[]` to truncate and concatenate to 16 bit `bytes`.\n    /// @return The concatenated 2-byte chunks.\n    function unsafeTo16BitBytes(uint256[] memory us_) internal pure returns (bytes memory) {\n        unchecked {\n            // We will keep 2 bytes (16 bits) from each integer.\n            bytes memory bytes_ = new bytes(us_.length * 2);\n            assembly (\"memory-safe\") {\n                let replaceMask_ := 0xFFFF\n                let preserveMask_ := not(replaceMask_)\n                for {\n                    let cursor_ := add(us_, 0x20)\n                    let end_ := add(cursor_, mul(mload(us_), 0x20))\n                    let bytesCursor_ := add(bytes_, 0x02)\n                } lt(cursor_, end_) {\n                    cursor_ := add(cursor_, 0x20)\n                    bytesCursor_ := add(bytesCursor_, 0x02)\n                } {\n                    let data_ := mload(bytesCursor_)\n                    mstore(bytesCursor_, or(and(preserveMask_, data_), and(replaceMask_, mload(cursor_))))\n                }\n            }\n            return bytes_;\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/integrity/LibIntegrityCheckNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.19;\n\nimport \"../../interface/IInterpreterV1.sol\";\nimport \"../../lib/bytecode/LibBytecode.sol\";\n\n/// @dev There are more entrypoints defined by the minimum stack outputs than\n/// there are provided sources. This means the calling contract WILL attempt to\n/// eval a dangling reference to a non-existent source at some point, so this\n/// MUST REVERT.\nerror EntrypointMissing(uint256 expectedEntrypoints, uint256 actualEntrypoints);\n\n/// Thrown when some entrypoint has non-zero inputs. This is not allowed as\n/// only internal dispatches can have source level inputs.\nerror EntrypointNonZeroInput(uint256 entrypointIndex, uint256 inputsLength);\n\n/// Thrown when some entrypoint has less outputs than the minimum required.\nerror EntrypointMinOutputs(uint256 entrypointIndex, uint256 outputsLength, uint256 minOutputs);\n\n/// The bytecode and integrity function disagree on number of inputs.\nerror BadOpInputsLength(uint256 opIndex, uint256 calculatedInputs, uint256 bytecodeInputs);\n\n/// The stack underflowed during integrity check.\nerror StackUnderflow(uint256 opIndex, uint256 stackIndex, uint256 calculatedInputs);\n\n/// The stack underflowed the highwater during integrity check.\nerror StackUnderflowHighwater(uint256 opIndex, uint256 stackIndex, uint256 stackHighwater);\n\n/// The bytecode stack allocation does not match the allocation calculated by\n/// the integrity check.\nerror StackAllocationMismatch(uint256 stackMaxIndex, uint256 bytecodeAllocation);\n\n/// The final stack index does not match the bytecode outputs.\nerror StackOutputsMismatch(uint256 stackIndex, uint256 bytecodeOutputs);\n\nstruct IntegrityCheckStateNP {\n    uint256 stackIndex;\n    uint256 stackMaxIndex;\n    uint256 readHighwater;\n    uint256 constantsLength;\n    uint256 opIndex;\n    bytes bytecode;\n}\n\nlibrary LibIntegrityCheckNP {\n    using LibIntegrityCheckNP for IntegrityCheckStateNP;\n\n    function newState(bytes memory bytecode, uint256 stackIndex, uint256 constantsLength)\n        internal\n        pure\n        returns (IntegrityCheckStateNP memory)\n    {\n        return IntegrityCheckStateNP(\n            // stackIndex\n            stackIndex,\n            // stackMaxIndex\n            stackIndex,\n            // highwater (source inputs are always immutable)\n            stackIndex,\n            // constantsLength\n            constantsLength,\n            // opIndex\n            0,\n            // bytecode\n            bytecode\n        );\n    }\n\n    // The cyclomatic complexity here comes from all the `if` checks for each\n    // integrity check. While the scanner isn't wrong, if we broke the checks\n    // out into functions it would be a mostly superficial reduction in\n    // complexity, and would make the code harder to read, as well as cost gas.\n    //slither-disable-next-line cyclomatic-complexity\n    function integrityCheck(\n        bytes memory fPointers,\n        bytes memory bytecode,\n        uint256[] memory constants,\n        uint256[] memory minOutputs\n    ) internal view {\n        unchecked {\n            uint256 sourceCount = LibBytecode.sourceCount(bytecode);\n\n            // Ensure that we are not missing any entrypoints expected by the calling\n            // contract.\n            if (minOutputs.length > sourceCount) {\n                revert EntrypointMissing(minOutputs.length, sourceCount);\n            }\n\n            uint256 fPointersStart;\n            assembly {\n                fPointersStart := add(fPointers, 0x20)\n            }\n\n            // Ensure that the bytecode has no out of bounds pointers BEFORE we\n            // start attempting to iterate over opcodes. This ensures the\n            // integrity of the source count, relative offset pointers,\n            // ops count per source, and that there is no garbage bytes at the\n            // end or between these things. Basically everything structural about\n            // the bytecode is confirmed here.\n            LibBytecode.checkNoOOBPointers(bytecode);\n\n            // Run the integrity check over each source. This needs to ensure\n            // the integrity of each source's inputs, outputs, and stack\n            // allocation, as well as the integrity of the bytecode itself on\n            // a per-opcode basis, according to each opcode's implementation.\n            for (uint256 i = 0; i < sourceCount; i++) {\n                (uint256 inputsLength, uint256 outputsLength) = LibBytecode.sourceInputsOutputsLength(bytecode, i);\n\n                // This is an entrypoint so has additional restrictions.\n                if (i < minOutputs.length) {\n                    if (inputsLength != 0) {\n                        revert EntrypointNonZeroInput(i, inputsLength);\n                    }\n\n                    if (outputsLength < minOutputs[i]) {\n                        revert EntrypointMinOutputs(i, outputsLength, minOutputs[i]);\n                    }\n                }\n\n                IntegrityCheckStateNP memory state =\n                    LibIntegrityCheckNP.newState(bytecode, inputsLength, constants.length);\n\n                // Have low 4 bytes of cursor overlap the first op, skipping the\n                // prefix.\n                uint256 cursor = Pointer.unwrap(LibBytecode.sourcePointer(bytecode, i)) - 0x18;\n                uint256 end = cursor + LibBytecode.sourceOpsCount(bytecode, i) * 4;\n\n                while (cursor < end) {\n                    Operand operand;\n                    uint256 bytecodeOpInputs;\n                    function(IntegrityCheckStateNP memory, Operand)\n                    view\n                    returns (uint256, uint256) f;\n                    assembly (\"memory-safe\") {\n                        let word := mload(cursor)\n                        f := shr(0xf0, mload(add(fPointersStart, mul(byte(28, word), 2))))\n                        // 3 bytes mask.\n                        operand := and(word, 0xFFFFFF)\n                        bytecodeOpInputs := byte(29, word)\n                    }\n                    (uint256 calcOpInputs, uint256 calcOpOutputs) = f(state, operand);\n                    if (calcOpInputs != bytecodeOpInputs) {\n                        revert BadOpInputsLength(state.opIndex, calcOpInputs, bytecodeOpInputs);\n                    }\n\n                    if (calcOpInputs > state.stackIndex) {\n                        revert StackUnderflow(state.opIndex, state.stackIndex, calcOpInputs);\n                    }\n                    state.stackIndex -= calcOpInputs;\n\n                    // The stack index can't move below the highwater.\n                    if (state.stackIndex < state.readHighwater) {\n                        revert StackUnderflowHighwater(state.opIndex, state.stackIndex, state.readHighwater);\n                    }\n\n                    // Let's assume that sane opcode implementations don't\n                    // overflow uint256 due to their outputs.\n                    state.stackIndex += calcOpOutputs;\n\n                    // Ensure the max stack index is updated if needed.\n                    if (state.stackIndex > state.stackMaxIndex) {\n                        state.stackMaxIndex = state.stackIndex;\n                    }\n\n                    // If there are multiple outputs the highwater MUST move.\n                    if (calcOpOutputs > 1) {\n                        state.readHighwater = state.stackIndex;\n                    }\n\n                    state.opIndex++;\n                    cursor += 4;\n                }\n\n                // The final stack max index MUST match the bytecode allocation.\n                if (state.stackMaxIndex != LibBytecode.sourceStackAllocation(bytecode, i)) {\n                    revert StackAllocationMismatch(state.stackMaxIndex, LibBytecode.sourceStackAllocation(bytecode, i));\n                }\n\n                // The final stack index MUST match the bytecode source outputs.\n                if (state.stackIndex != outputsLength) {\n                    revert StackOutputsMismatch(state.stackIndex, outputsLength);\n                }\n            }\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/parse/LibParseMeta.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"../bitwise/LibCtPop.sol\";\nimport \"../../interface/IInterpreterV1.sol\";\nimport \"./LibParseOperand.sol\";\n\n/// @dev For metadata builder.\nerror DuplicateFingerprint();\n\n/// @dev Words and io fn pointers aren't the same length.\nerror WordIOFnPointerMismatch(uint256 wordsLength, uint256 ioFnPointersLength);\n\n/// @dev 0xFFFFFF = 3 byte fingerprint\n/// The fingerprint is 3 bytes because we're targetting the same collision\n/// resistance on words as solidity functions. As we already use a fully byte to\n/// map words across the expander, we only need 3 bytes for the fingerprint to\n/// achieve 4 bytes of collision resistance, which is the same as a solidity\n/// selector. This assumes that the byte selected to expand is uncorrelated with\n/// the fingerprint bytes, which is a reasonable assumption as long as we use\n/// different bytes from a keccak256 hash for each.\n/// This assumes a single expander, if there are multiple expanders, then the\n/// collision resistance only improves, so this is still safe.\nuint256 constant FINGERPRINT_MASK = 0xFFFFFF;\n/// @dev 4 = 1 byte opcode index + 1 byte operand parser offset + 3 byte fingerprint\nuint256 constant META_ITEM_SIZE = 5;\nuint256 constant META_ITEM_MASK = (1 << META_ITEM_SIZE) - 1;\n/// @dev 33 = 32 bytes for expansion + 1 byte for seed\nuint256 constant META_EXPANSION_SIZE = 0x21;\n/// @dev 1 = 1 byte for depth\nuint256 constant META_PREFIX_SIZE = 1;\n\nstruct AuthoringMeta {\n    // `word` is referenced directly in assembly so don't move the field.\n    bytes32 word;\n    uint8 operandParserOffset;\n    string description;\n}\n\nlibrary LibParseMeta {\n    function wordBitmapped(uint256 seed, bytes32 word) internal pure returns (uint256 bitmap, uint256 hashed) {\n        assembly (\"memory-safe\") {\n            mstore(0, word)\n            mstore8(0x20, seed)\n            hashed := keccak256(0, 0x21)\n            // We have to be careful here to avoid using the same byte for both\n            // the expansion and the fingerprint. This is because we are relying\n            // on the combined effect of both for collision resistance. We do\n            // this by using the high byte of the hash for the bitmap, and the\n            // low 3 bytes for the fingerprint.\n            //slither-disable-next-line incorrect-shift\n            bitmap := shl(byte(0, hashed), 1)\n        }\n    }\n\n    function copyWordsFromAuthoringMeta(AuthoringMeta[] memory authoringMeta)\n        internal\n        pure\n        returns (bytes32[] memory)\n    {\n        bytes32[] memory words = new bytes32[](authoringMeta.length);\n        for (uint256 i = 0; i < authoringMeta.length; i++) {\n            words[i] = authoringMeta[i].word;\n        }\n        return words;\n    }\n\n    function findBestExpander(AuthoringMeta[] memory metas)\n        internal\n        pure\n        returns (uint8 bestSeed, uint256 bestExpansion, AuthoringMeta[] memory remaining)\n    {\n        unchecked {\n            {\n                uint256 bestCt = 0;\n                for (uint256 seed = 0; seed < type(uint8).max; seed++) {\n                    uint256 expansion = 0;\n                    for (uint256 i = 0; i < metas.length; i++) {\n                        (uint256 shifted, uint256 hashed) = wordBitmapped(seed, metas[i].word);\n                        (hashed);\n                        expansion = shifted | expansion;\n                    }\n                    uint256 ct = LibCtPop.ctpop(expansion);\n                    if (ct > bestCt) {\n                        bestCt = ct;\n                        bestSeed = uint8(seed);\n                        bestExpansion = expansion;\n                    }\n                    // perfect expansion.\n                    if (ct == metas.length) {\n                        break;\n                    }\n                }\n\n                uint256 remainingLength = metas.length - bestCt;\n                assembly (\"memory-safe\") {\n                    remaining := mload(0x40)\n                    mstore(remaining, remainingLength)\n                    mstore(0x40, add(remaining, mul(0x20, add(1, remainingLength))))\n                }\n            }\n            uint256 usedExpansion = 0;\n            uint256 j = 0;\n            for (uint256 i = 0; i < metas.length; i++) {\n                (uint256 shifted, uint256 hashed) = wordBitmapped(bestSeed, metas[i].word);\n                (hashed);\n                if ((shifted & usedExpansion) == 0) {\n                    usedExpansion = shifted | usedExpansion;\n                } else {\n                    remaining[j] = metas[i];\n                    j++;\n                }\n            }\n        }\n    }\n\n    function buildParseMeta(AuthoringMeta[] memory authoringMeta, uint8 maxDepth)\n        internal\n        pure\n        returns (bytes memory parseMeta)\n    {\n        unchecked {\n            // Write out expansions.\n            uint8[] memory seeds;\n            uint256[] memory expansions;\n            uint256 dataStart;\n            {\n                uint256 depth = 0;\n                seeds = new uint8[](maxDepth);\n                expansions = new uint256[](maxDepth);\n                {\n                    AuthoringMeta[] memory remainingAuthoringMeta = authoringMeta;\n                    while (remainingAuthoringMeta.length > 0) {\n                        uint8 seed;\n                        uint256 expansion;\n                        (seed, expansion, remainingAuthoringMeta) = findBestExpander(remainingAuthoringMeta);\n                        seeds[depth] = seed;\n                        expansions[depth] = expansion;\n                        depth++;\n                    }\n                }\n\n                uint256 parseMetaLength =\n                    META_PREFIX_SIZE + depth * META_EXPANSION_SIZE + authoringMeta.length * META_ITEM_SIZE;\n                parseMeta = new bytes(parseMetaLength);\n                assembly (\"memory-safe\") {\n                    mstore8(add(parseMeta, 0x20), depth)\n                }\n                for (uint256 j = 0; j < depth; j++) {\n                    assembly (\"memory-safe\") {\n                        // Write each seed immediately before its expansion.\n                        let seedWriteAt := add(add(parseMeta, 0x21), mul(0x21, j))\n                        mstore8(seedWriteAt, mload(add(seeds, add(0x20, mul(0x20, j)))))\n                        mstore(add(seedWriteAt, 1), mload(add(expansions, add(0x20, mul(0x20, j)))))\n                    }\n                }\n\n                {\n                    uint256 dataOffset = META_PREFIX_SIZE + META_ITEM_SIZE + depth * META_EXPANSION_SIZE;\n                    assembly (\"memory-safe\") {\n                        dataStart := add(parseMeta, dataOffset)\n                    }\n                }\n            }\n\n            // Write words.\n            for (uint256 k = 0; k < authoringMeta.length; k++) {\n                uint256 s = 0;\n                uint256 cumulativePos = 0;\n                while (true) {\n                    uint256 toWrite;\n                    uint256 writeAt;\n\n                    // Need some careful scoping here to avoid stack too deep.\n                    {\n                        uint256 expansion = expansions[s];\n\n                        uint256 hashed;\n                        {\n                            uint256 shifted;\n                            (shifted, hashed) = wordBitmapped(seeds[s], authoringMeta[k].word);\n\n                            uint256 metaItemSize = META_ITEM_SIZE;\n                            uint256 pos = LibCtPop.ctpop(expansion & (shifted - 1)) + cumulativePos;\n                            assembly (\"memory-safe\") {\n                                writeAt := add(dataStart, mul(pos, metaItemSize))\n                            }\n                        }\n\n                        {\n                            uint256 wordFingerprint = hashed & FINGERPRINT_MASK;\n                            uint256 posFingerprint;\n                            assembly (\"memory-safe\") {\n                                posFingerprint := mload(writeAt)\n                            }\n                            posFingerprint &= FINGERPRINT_MASK;\n                            if (posFingerprint != 0) {\n                                if (posFingerprint == wordFingerprint) {\n                                    revert DuplicateFingerprint();\n                                }\n                                // Collision, try next expansion.\n                                s++;\n                                cumulativePos = cumulativePos + LibCtPop.ctpop(expansion);\n                                continue;\n                            }\n                            // Not collision, start preparing the write with the\n                            // fingerprint.\n                            toWrite = wordFingerprint;\n                        }\n                    }\n\n                    // Write the io fn pointer and index offset.\n                    toWrite |= (k << 0x20) | (uint256(authoringMeta[k].operandParserOffset) << 0x18);\n\n                    uint256 mask = ~META_ITEM_MASK;\n                    assembly (\"memory-safe\") {\n                        mstore(writeAt, or(and(mload(writeAt), mask), toWrite))\n                    }\n                    // We're done with this word.\n                    break;\n                }\n            }\n        }\n    }\n\n    /// Given the parse meta and a word, return the index and io fn pointer for\n    /// the word. If the word is not found, then `exists` will be false. The\n    /// caller MUST check `exists` before using the other return values.\n    /// @param meta The parse meta.\n    /// @param word The word to lookup.\n    /// @return True if the word exists in the parse meta.\n    /// @return The index of the word in the parse meta.\n    function lookupWord(bytes memory meta, uint256 operandParsers, bytes32 word)\n        internal\n        pure\n        returns (bool, uint256, function(uint256, bytes memory, uint256) pure returns (uint256, Operand))\n    {\n        unchecked {\n            uint256 dataStart;\n            uint256 cursor;\n            uint256 end;\n            {\n                uint256 metaExpansionSize = META_EXPANSION_SIZE;\n                uint256 metaItemSize = META_ITEM_SIZE;\n                assembly (\"memory-safe\") {\n                    // Read depth from first meta byte.\n                    cursor := add(meta, 1)\n                    let depth := and(mload(cursor), 0xFF)\n                    // 33 bytes per depth\n                    end := add(cursor, mul(depth, metaExpansionSize))\n                    dataStart := add(end, metaItemSize)\n                }\n            }\n\n            uint256 cumulativeCt = 0;\n            while (cursor < end) {\n                uint256 expansion;\n                uint256 posData;\n                uint256 wordFingerprint;\n                // Lookup the data at pos.\n                {\n                    uint256 seed;\n                    assembly (\"memory-safe\") {\n                        cursor := add(cursor, 1)\n                        seed := and(mload(cursor), 0xFF)\n                        cursor := add(cursor, 0x20)\n                        expansion := mload(cursor)\n                    }\n\n                    (uint256 shifted, uint256 hashed) = wordBitmapped(seed, word);\n                    uint256 pos = LibCtPop.ctpop(expansion & (shifted - 1)) + cumulativeCt;\n                    wordFingerprint = hashed & FINGERPRINT_MASK;\n                    uint256 metaItemSize = META_ITEM_SIZE;\n                    assembly (\"memory-safe\") {\n                        posData := mload(add(dataStart, mul(pos, metaItemSize)))\n                    }\n                }\n\n                // Match\n                if (wordFingerprint == posData & FINGERPRINT_MASK) {\n                    uint256 index;\n                    function(uint256, bytes memory, uint256) pure returns (uint256, Operand) operandParser;\n                    assembly (\"memory-safe\") {\n                        index := byte(27, posData)\n                        operandParser := and(shr(byte(28, posData), operandParsers), 0xFFFF)\n                    }\n                    return (true, index, operandParser);\n                } else {\n                    cumulativeCt += LibCtPop.ctpop(expansion);\n                }\n            }\n            // The caller MUST NOT use this operand parser as `exists` is false.\n            function(uint256, bytes memory, uint256) pure returns (uint256, Operand) operandParserZero;\n            assembly (\"memory-safe\") {\n                operandParserZero := 0\n            }\n            return (false, 0, operandParserZero);\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/parse/LibParseOperand.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"../../interface/IInterpreterV1.sol\";\nimport \"./LibParseCMask.sol\";\nimport \"./LibParse.sol\";\nimport \"./LibParseLiteral.sol\";\n\nuint8 constant OPERAND_PARSER_OFFSET_DISALLOWED = 0;\nuint8 constant OPERAND_PARSER_OFFSET_SINGLE_FULL = 0x10;\nuint8 constant OPERAND_PARSER_OFFSET_DOUBLE_PERBYTE_NO_DEFAULT = 0x20;\nuint8 constant OPERAND_PARSER_OFFSET_M1_M1 = 0x30;\nuint8 constant OPERAND_PARSER_OFFSET_8_M1_M1 = 0x40;\n\nerror UnexpectedOperand(uint256 offset);\n\nerror ExpectedOperand(uint256 offset);\n\nerror OperandOverflow(uint256 offset);\n\nerror UnclosedOperand(uint256 offset);\n\nlibrary LibParseOperand {\n    function buildOperandParsers() internal pure returns (uint256 operandParsers) {\n        function(uint256, bytes memory, uint256) pure returns (uint256, Operand) operandParserDisallowed =\n            LibParseOperand.parseOperandDisallowed;\n        uint256 parseOperandDisallowedOffset = OPERAND_PARSER_OFFSET_DISALLOWED;\n        assembly {\n            operandParsers := or(operandParsers, shl(parseOperandDisallowedOffset, operandParserDisallowed))\n        }\n        function(uint256, bytes memory, uint256) pure returns (uint256, Operand) operandParserSingleFull =\n            LibParseOperand.parseOperandSingleFull;\n        uint256 parseOperandSingleFullOffset = OPERAND_PARSER_OFFSET_SINGLE_FULL;\n        assembly {\n            operandParsers := or(operandParsers, shl(parseOperandSingleFullOffset, operandParserSingleFull))\n        }\n        function(uint256, bytes memory, uint256) pure returns (uint256, Operand) operandParserDoublePerByteNoDefault =\n            LibParseOperand.parseOperandDoublePerByteNoDefault;\n        uint256 parseOperandDoublePerByteNoDefaultOffset = OPERAND_PARSER_OFFSET_DOUBLE_PERBYTE_NO_DEFAULT;\n        assembly {\n            operandParsers :=\n                or(operandParsers, shl(parseOperandDoublePerByteNoDefaultOffset, operandParserDoublePerByteNoDefault))\n        }\n        function(uint256, bytes memory, uint256) pure returns (uint256, Operand) operandParser_m1_m1 =\n            LibParseOperand.parseOperandM1M1;\n        uint256 parseOperand_m1_m1Offset = OPERAND_PARSER_OFFSET_M1_M1;\n        assembly {\n            operandParsers := or(operandParsers, shl(parseOperand_m1_m1Offset, operandParser_m1_m1))\n        }\n        function(uint256, bytes memory, uint256) pure returns (uint256, Operand) operandParser_8_m1_m1 =\n            LibParseOperand.parseOperand8M1M1;\n        uint256 parseOperand_8_m1_m1Offset = OPERAND_PARSER_OFFSET_8_M1_M1;\n        assembly {\n            operandParsers := or(operandParsers, shl(parseOperand_8_m1_m1Offset, operandParser_8_m1_m1))\n        }\n    }\n\n    /// Parse a literal for an operand.\n    function parseOperandLiteral(uint256 literalParsers, bytes memory data, uint256 max, uint256 cursor)\n        internal\n        pure\n        returns (uint256, uint256)\n    {\n        uint256 char;\n        assembly {\n            //slither-disable-next-line incorrect-shift\n            char := shl(byte(0, mload(cursor)), 1)\n        }\n        if (char == CMASK_OPERAND_END) {\n            revert ExpectedOperand(LibParse.parseErrorOffset(data, cursor));\n        }\n        (\n            function(bytes memory, uint256, uint256) pure returns (uint256) literalParser,\n            uint256 innerStart,\n            uint256 innerEnd,\n            uint256 outerEnd\n        ) = LibParseLiteral.boundLiteral(literalParsers, data, cursor);\n        uint256 value = literalParser(data, innerStart, innerEnd);\n        if (value > max) {\n            revert OperandOverflow(LibParse.parseErrorOffset(data, cursor));\n        }\n        cursor = outerEnd;\n        return (cursor, value);\n    }\n\n    /// Operand is disallowed for this word.\n    function parseOperandDisallowed(uint256, bytes memory data, uint256 cursor)\n        internal\n        pure\n        returns (uint256, Operand)\n    {\n        uint256 char;\n        assembly {\n            //slither-disable-next-line incorrect-shift\n            char := shl(byte(0, mload(cursor)), 1)\n        }\n        if (char == CMASK_OPERAND_START) {\n            revert UnexpectedOperand(LibParse.parseErrorOffset(data, cursor));\n        }\n        // Don't move the cursor. This is a no-op.\n        return (cursor, Operand.wrap(0));\n    }\n\n    /// Operand is a 16-bit unsigned integer.\n    function parseOperandSingleFull(uint256 literalParsers, bytes memory data, uint256 cursor)\n        internal\n        pure\n        returns (uint256, Operand)\n    {\n        unchecked {\n            uint256 char;\n            uint256 end;\n            assembly {\n                end := add(data, add(mload(data), 0x20))\n                //slither-disable-next-line incorrect-shift\n                char := shl(byte(0, mload(cursor)), 1)\n            }\n            if (char == CMASK_OPERAND_START) {\n                cursor = LibParse.skipMask(cursor + 1, end, CMASK_WHITESPACE);\n\n                uint256 value;\n                (cursor, value) = parseOperandLiteral(literalParsers, data, type(uint16).max, cursor);\n\n                cursor = LibParse.skipMask(cursor, end, CMASK_WHITESPACE);\n                assembly (\"memory-safe\") {\n                    //slither-disable-next-line incorrect-shift\n                    char := shl(byte(0, mload(cursor)), 1)\n                }\n                if (char != CMASK_OPERAND_END) {\n                    revert UnclosedOperand(LibParse.parseErrorOffset(data, cursor));\n                }\n                return (cursor + 1, Operand.wrap(value));\n            }\n            // Default is 0.\n            else {\n                return (cursor, Operand.wrap(0));\n            }\n        }\n    }\n\n    /// Operand is two bytes.\n    function parseOperandDoublePerByteNoDefault(uint256 literalParsers, bytes memory data, uint256 cursor)\n        internal\n        pure\n        returns (uint256, Operand)\n    {\n        unchecked {\n            uint256 char;\n            uint256 end;\n            assembly (\"memory-safe\") {\n                end := add(data, add(mload(data), 0x20))\n                //slither-disable-next-line incorrect-shift\n                char := shl(byte(0, mload(cursor)), 1)\n            }\n            if (char == CMASK_OPERAND_START) {\n                cursor = LibParse.skipMask(cursor + 1, end, CMASK_WHITESPACE);\n\n                uint256 a;\n                (cursor, a) = parseOperandLiteral(literalParsers, data, type(uint8).max, cursor);\n                Operand operand = Operand.wrap(a);\n\n                cursor = LibParse.skipMask(cursor, end, CMASK_WHITESPACE);\n\n                uint256 b;\n                (cursor, b) = parseOperandLiteral(literalParsers, data, type(uint8).max, cursor);\n                operand = Operand.wrap(Operand.unwrap(operand) | (b << 8));\n\n                cursor = LibParse.skipMask(cursor, end, CMASK_WHITESPACE);\n\n                assembly (\"memory-safe\") {\n                    //slither-disable-next-line incorrect-shift\n                    char := shl(byte(0, mload(cursor)), 1)\n                }\n                if (char != CMASK_OPERAND_END) {\n                    revert UnclosedOperand(LibParse.parseErrorOffset(data, cursor));\n                }\n                return (cursor + 1, operand);\n            }\n            // There is no default fallback value.\n            else {\n                revert ExpectedOperand(LibParse.parseErrorOffset(data, cursor));\n            }\n        }\n    }\n\n    /// 8 bit value, maybe 1 bit flag, maybe 1 big flag.\n    function parseOperand8M1M1(uint256 literalParsers, bytes memory data, uint256 cursor)\n        internal\n        pure\n        returns (uint256, Operand)\n    {\n        unchecked {\n            uint256 char;\n            uint256 end;\n            assembly {\n                end := add(data, add(mload(data), 0x20))\n                //slither-disable-next-line incorrect-shift\n                char := shl(byte(0, mload(cursor)), 1)\n            }\n            if (char == CMASK_OPERAND_START) {\n                cursor = LibParse.skipMask(cursor + 1, end, CMASK_WHITESPACE);\n\n                // 8 bit value. Required.\n                uint256 a;\n                (cursor, a) = parseOperandLiteral(literalParsers, data, type(uint8).max, cursor);\n                cursor = LibParse.skipMask(cursor, end, CMASK_WHITESPACE);\n\n                // Maybe 1 bit flag.\n                uint256 b;\n                assembly (\"memory-safe\") {\n                    //slither-disable-next-line incorrect-shift\n                    char := shl(byte(0, mload(cursor)), 1)\n                }\n                if (char == CMASK_OPERAND_END) {\n                    b = 0;\n                } else {\n                    (cursor, b) = parseOperandLiteral(literalParsers, data, 1, cursor);\n                    cursor = LibParse.skipMask(cursor, end, CMASK_WHITESPACE);\n                }\n\n                // Maybe 1 bit flag.\n                uint256 c;\n                assembly (\"memory-safe\") {\n                    //slither-disable-next-line incorrect-shift\n                    char := shl(byte(0, mload(cursor)), 1)\n                }\n                if (char == CMASK_OPERAND_END) {\n                    c = 0;\n                } else {\n                    (cursor, c) = parseOperandLiteral(literalParsers, data, 1, cursor);\n                    cursor = LibParse.skipMask(cursor, end, CMASK_WHITESPACE);\n                }\n\n                Operand operand = Operand.wrap(a | (b << 8) | (c << 9));\n\n                assembly (\"memory-safe\") {\n                    //slither-disable-next-line incorrect-shift\n                    char := shl(byte(0, mload(cursor)), 1)\n                }\n                if (char != CMASK_OPERAND_END) {\n                    revert UnclosedOperand(LibParse.parseErrorOffset(data, cursor));\n                }\n                return (cursor + 1, operand);\n            }\n            // There is no default fallback value. The first 8 bits are\n            // required.\n            else {\n                revert ExpectedOperand(LibParse.parseErrorOffset(data, cursor));\n            }\n        }\n    }\n\n    /// 2x maybe 1 bit flags.\n    function parseOperandM1M1(uint256 literalParsers, bytes memory data, uint256 cursor)\n        internal\n        pure\n        returns (uint256, Operand)\n    {\n        unchecked {\n            uint256 char;\n            uint256 end;\n            assembly {\n                end := add(data, add(mload(data), 0x20))\n                //slither-disable-next-line incorrect-shift\n                char := shl(byte(0, mload(cursor)), 1)\n            }\n            if (char == CMASK_OPERAND_START) {\n                cursor = LibParse.skipMask(cursor + 1, end, CMASK_WHITESPACE);\n\n                uint256 a;\n                assembly (\"memory-safe\") {\n                    //slither-disable-next-line incorrect-shift\n                    char := shl(byte(0, mload(cursor)), 1)\n                }\n                if (char == CMASK_OPERAND_END) {\n                    a = 0;\n                } else {\n                    (cursor, a) = parseOperandLiteral(literalParsers, data, 1, cursor);\n                    cursor = LibParse.skipMask(cursor, end, CMASK_WHITESPACE);\n                }\n\n                uint256 b;\n                assembly (\"memory-safe\") {\n                    //slither-disable-next-line incorrect-shift\n                    char := shl(byte(0, mload(cursor)), 1)\n                }\n                if (char == CMASK_OPERAND_END) {\n                    b = 0;\n                } else {\n                    (cursor, b) = parseOperandLiteral(literalParsers, data, 1, cursor);\n                    cursor = LibParse.skipMask(cursor, end, CMASK_WHITESPACE);\n                }\n\n                Operand operand = Operand.wrap(a | (b << 1));\n\n                assembly (\"memory-safe\") {\n                    //slither-disable-next-line incorrect-shift\n                    char := shl(byte(0, mload(cursor)), 1)\n                }\n                if (char != CMASK_OPERAND_END) {\n                    revert UnclosedOperand(LibParse.parseErrorOffset(data, cursor));\n                }\n                return (cursor + 1, operand);\n            }\n            // Default is 0.\n            else {\n                return (cursor, Operand.wrap(0));\n            }\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/00/LibOpStackNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\n\n/// Thrown when a stack read index is outside the current stack top.\nerror OutOfBoundsStackRead(uint256 opIndex, uint256 stackTopIndex, uint256 stackRead);\n\n/// @title LibOpStackNP\n/// Implementation of copying a stack item from the stack to the stack.\n/// Integrated deeply into LibParse, which requires this opcode or a variant\n/// to be present at a known opcode index.\nlibrary LibOpStackNP {\n    function integrity(IntegrityCheckStateNP memory state, Operand operand) internal pure returns (uint256, uint256) {\n        uint256 readIndex = Operand.unwrap(operand);\n        // Operand is the index so ensure it doesn't exceed the stack index.\n        if (readIndex >= state.stackIndex) {\n            revert OutOfBoundsStackRead(state.opIndex, state.stackIndex, readIndex);\n        }\n\n        // Move the read highwater if needed.\n        if (readIndex > state.readHighwater) {\n            state.readHighwater = readIndex;\n        }\n\n        return (0, 1);\n    }\n\n    function run(InterpreterStateNP memory state, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 sourceIndex = state.sourceIndex;\n        assembly (\"memory-safe\") {\n            let stackBottom := mload(add(mload(state), mul(0x20, add(sourceIndex, 1))))\n            let stackValue := mload(sub(stackBottom, mul(0x20, add(operand, 1))))\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, stackValue)\n        }\n        return stackTop;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/00/LibOpConstantNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\n\n/// Thrown when a constant read index is outside the constants array.\nerror OutOfBoundsConstantRead(uint256 opIndex, uint256 constantsLength, uint256 constantRead);\n\n/// @title LibOpConstantNP\n/// Implementation of copying a constant from the constants array to the stack.\n/// Integrated deeply into LibParse, which requires this opcode or a variant\n/// to be present at a known opcode index.\nlibrary LibOpConstantNP {\n    function integrity(IntegrityCheckStateNP memory state, Operand operand) internal pure returns (uint256, uint256) {\n        // Operand is the index so ensure it doesn't exceed the constants length.\n        if (Operand.unwrap(operand) >= state.constantsLength) {\n            revert OutOfBoundsConstantRead(state.opIndex, state.constantsLength, Operand.unwrap(operand));\n        }\n        // As inputs MUST always be 0, we don't have to check the high byte of\n        // the operand here, the integrity check will do that for us.\n        return (0, 1);\n    }\n\n    function run(InterpreterStateNP memory state, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256[] memory constants = state.constants;\n        // Skip index OOB check and rely on integrity check for that.\n        assembly (\"memory-safe\") {\n            let value := mload(add(constants, mul(add(operand, 1), 0x20)))\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, value)\n        }\n        return stackTop;\n    }\n\n    function referenceFn(InterpreterStateNP memory state, Operand operand, uint256[] memory)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        uint256 index = Operand.unwrap(operand);\n        outputs = new uint256[](1);\n        outputs[0] = state.constants[index];\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/bitwise/LibOpCtPopNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\nimport {LibCtPop} from \"../../bitwise/LibCtPop.sol\";\n\n/// @title LibOpCtPopNP\n/// @notice An opcode that counts the number of bits set in a word. This is\n/// called ctpop because that's the name of this kind of thing elsewhere, but\n/// the more common name is \"population count\" or \"Hamming weight\". The word\n/// in the standard ops lib is called `bitwise-count-ones`, which follows the\n/// Rust naming convention.\n/// There is no evm opcode for this, so we have to implement it ourselves.\nlibrary LibOpCtPopNP {\n    /// ctpop unconditionally takes one value and returns one value.\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        return (1, 1);\n    }\n\n    /// Output is the number of bits set to one in the input. Thin wrapper around\n    /// `LibCtPop.ctpop`.\n    function run(InterpreterStateNP memory, Operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 value;\n        assembly (\"memory-safe\") {\n            value := mload(stackTop)\n        }\n        value = LibCtPop.ctpop(value);\n        assembly (\"memory-safe\") {\n            mstore(stackTop, value)\n        }\n        return stackTop;\n    }\n\n    /// The reference implementation of ctpop.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory)\n    {\n        inputs[0] = LibCtPop.ctpopSlow(inputs[0]);\n        return inputs;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/call/LibOpCallNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {LibInterpreterStateNP, InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {LibIntegrityCheckNP, IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\nimport {Pointer, LibPointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {LibBytecode} from \"../../bytecode/LibBytecode.sol\";\nimport {LibEvalNP} from \"../../eval/LibEvalNP.sol\";\n\n/// Thrown when the outputs requested by the operand exceed the outputs\n/// available from the source.\n/// @param sourceOutputs The number of outputs available from the source.\n/// @param outputs The number of outputs requested by the operand.\nerror CallOutputsExceedSource(uint256 sourceOutputs, uint256 outputs);\n\n/// @title LibOpCallNP\n/// @notice Contains the call operation. This allows sources to be treated in a\n/// function-like manner. Primarily intended as a way for expression authors to\n/// create reusable logic inline with their expression, in a way that mimics how\n/// words and stack consumption works at the Solidity level.\n///\n/// Similarities between `call` and a traditional function:\n/// - The source is called with a set of 0+ inputs.\n/// - The source returns a set of 0+ outputs.\n/// - The source has a fixed number of inputs and outputs.\n/// - When the source executes it has its own stack/scope.\n/// - Sources use lexical scoping rules for named LHS items.\n/// - The source can be called from multiple places.\n/// - The source can `call` other sources.\n/// - The source is stateless across calls\n///   (although it can use words like get/set to read/write external state).\n/// - The caller and callee have to agree on the number of inputs\n///   (but not outputs, see below).\n/// - Generally speaking, the behaviour of a source can be reasoned about\n///   without needing to know the context in which it is called. Which is the\n///   basic requirement for reusability.\n///\n/// Differences between `call` and a traditional function:\n/// - The caller defines the number of outputs to be returned, NOT the callee.\n///   This is because the caller is responsible for allocating space on the\n///   stack for the outputs, and the callee is responsible for providing the\n///   outputs. The only limitation is that the caller cannot request more\n///   outputs than the callee has available. This means that two calls to the\n///   same source can return different numbers of outputs in different contexts.\n/// - The inputs to a source are considered to be the top of the callee's stack\n///   from the perspective of the caller. This means that the inputs are eligible\n///   to be read as outputs, if the caller chooses to do so.\n/// - The sources are not named, they are identified by their index in the\n///   bytecode. Tooling can provide sugar over this but the underlying\n///   representation is just an index.\n/// - Sources are not \"first class\" like functions often are, i.e. they cannot\n///   be passed as arguments to other sources or otherwise be treated as values.\n/// - Recursion is not supported. This is because currently there is no laziness\n///   in the interpreter, so a recursive call would result in an infinite loop\n///   unconditionally (even when wrapped in an `if`). This may change in the\n///   future.\n/// - The memory allocation for a source must be known at compile time.\n/// - There's no way to return early from a source.\n///\n/// The order of inputs and outputs is designed so that the visual representation\n/// of a source call matches the visual representation of a function call. This\n/// requires some reversals of order \"under the hood\" while copying data around\n/// but it makes the behaviour of `call` more intuitive.\n///\n/// Illustrative example:\n/// ```\n/// /* Final result */\n/// /* a = 2 */\n/// /* b = 9 */\n/// a b: call<1 2>(10 5); ten five:, a b: int-div(ten five) 9;\n/// ```\nlibrary LibOpCallNP {\n    using LibPointer for Pointer;\n\n    function integrity(IntegrityCheckStateNP memory state, Operand operand) internal pure returns (uint256, uint256) {\n        uint256 sourceIndex = Operand.unwrap(operand) & 0xFF;\n        uint256 outputs = (Operand.unwrap(operand) >> 8) & 0xFF;\n\n        (uint256 sourceInputs, uint256 sourceOutputs) =\n            LibBytecode.sourceInputsOutputsLength(state.bytecode, sourceIndex);\n\n        if (sourceOutputs < outputs) {\n            revert CallOutputsExceedSource(sourceOutputs, outputs);\n        }\n\n        return (sourceInputs, outputs);\n    }\n\n    /// The `call` word is conceptually very simple. It takes a source index, a\n    /// number of outputs, and a number of inputs. It then runs the standard\n    /// eval loop for the source, with a starting stack pointer above the inputs,\n    /// and then copies the outputs to the calling stack.\n    function run(InterpreterStateNP memory state, Operand operand, Pointer stackTop) internal view returns (Pointer) {\n        // Extract config from the operand.\n        uint256 sourceIndex = Operand.unwrap(operand) & 0xFF;\n        uint256 outputs = (Operand.unwrap(operand) >> 8) & 0xFF;\n        uint256 inputs = (Operand.unwrap(operand) >> 0x10) & 0xFF;\n\n        // Copy inputs in. The inputs have to be copied in reverse order so that\n        // the top of the stack from the perspective of `call`, i.e. the first\n        // input to call, is the bottom of the stack from the perspective of the\n        // callee.\n        Pointer[] memory stackBottoms = state.stackBottoms;\n        Pointer evalStackTop;\n        assembly (\"memory-safe\") {\n            evalStackTop := mload(add(stackBottoms, mul(add(sourceIndex, 1), 0x20)))\n            let end := add(stackTop, mul(inputs, 0x20))\n            for {} lt(stackTop, end) { stackTop := add(stackTop, 0x20) } {\n                evalStackTop := sub(evalStackTop, 0x20)\n                mstore(evalStackTop, mload(stackTop))\n            }\n        }\n\n        // Keep a copy of the current source index so that we can restore it\n        // after the call.\n        uint256 currentSourceIndex = state.sourceIndex;\n\n        // Set the state to the source we are calling.\n        state.sourceIndex = sourceIndex;\n\n        // Run the eval loop.\n        evalStackTop = LibEvalNP.evalLoopNP(state, evalStackTop);\n\n        // Restore the source index in the state.\n        state.sourceIndex = currentSourceIndex;\n\n        // Copy outputs out.\n        assembly (\"memory-safe\") {\n            stackTop := sub(stackTop, mul(outputs, 0x20))\n            let end := add(evalStackTop, mul(outputs, 0x20))\n            let cursor := stackTop\n            for {} lt(evalStackTop, end) {\n                cursor := add(cursor, 0x20)\n                evalStackTop := add(evalStackTop, 0x20)\n            } { mstore(cursor, mload(evalStackTop)) }\n        }\n\n        return stackTop;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/context/LibOpContextNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\n\nlibrary LibOpContextNP {\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        // Context doesn't have any inputs. The operand defines the reads.\n        // Unfortunately we don't know the shape of the context that we will\n        // receive at runtime, so we can't check the reads at integrity time.\n        return (0, 1);\n    }\n\n    function run(InterpreterStateNP memory state, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 i = Operand.unwrap(operand) & 0xFF;\n        // Integrity check enforces the inputs byte is 0.\n        uint256 j = Operand.unwrap(operand) >> 8;\n        // We want these indexes to be checked at runtime for OOB accesses\n        // because we don't know the shape of the context at compile time.\n        // Solidity handles that for us as long as we don't invoke yul for the\n        // reads.\n        if (Pointer.unwrap(stackTop) < 0x20) {\n            revert(\"stack underflow\");\n        }\n        uint256 v = state.context[i][j];\n        assembly (\"memory-safe\") {\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, v)\n        }\n        return stackTop;\n    }\n\n    function referenceFn(InterpreterStateNP memory state, Operand operand, uint256[] memory)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        uint256 i = Operand.unwrap(operand) & 0xFF;\n        uint256 j = (Operand.unwrap(operand) >> 8) & 0xFF;\n        // We want these indexes to be checked at runtime for OOB accesses\n        // because we don't know the shape of the context at compile time.\n        // Solidity handles that for us as long as we don't invoke yul for the\n        // reads.\n        uint256 v = state.context[i][j];\n        outputs = new uint256[](1);\n        outputs[0] = v;\n        return outputs;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/crypto/LibOpHashNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\n\n/// @title LibOpHashNP\n/// Implementation of keccak256 hashing as a standard Rainlang opcode.\nlibrary LibOpHashNP {\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        // Any number of inputs are valid.\n        // 0 inputs will be the hash of empty (0 length) bytes.\n        uint256 inputs = Operand.unwrap(operand) >> 0x10;\n        return (inputs, 1);\n    }\n\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            let length := mul(shr(0x10, operand), 0x20)\n            let value := keccak256(stackTop, length)\n            stackTop := sub(add(stackTop, length), 0x20)\n            mstore(stackTop, value)\n        }\n        return stackTop;\n    }\n\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        outputs = new uint256[](1);\n        outputs[0] = uint256(keccak256(abi.encodePacked(inputs)));\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/erc721/LibOpERC721BalanceOfNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {IERC721} from \"openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\n\n/// @title OpERC721BalanceOfNP\n/// @notice Opcode for getting the current erc721 balance of an account.\nlibrary LibOpERC721BalanceOfNP {\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        // Always 2 inputs, the token and the account.\n        // Always 1 output, the balance.\n        return (2, 1);\n    }\n\n    function run(InterpreterStateNP memory, Operand, Pointer stackTop) internal view returns (Pointer) {\n        uint256 token;\n        uint256 account;\n        assembly {\n            token := mload(stackTop)\n            stackTop := add(stackTop, 0x20)\n            account := mload(stackTop)\n        }\n        uint256 tokenBalance = IERC721(address(uint160(token))).balanceOf(address(uint160(account)));\n        assembly {\n            mstore(stackTop, tokenBalance)\n        }\n        return stackTop;\n    }\n\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        view\n        returns (uint256[] memory)\n    {\n        uint256 token = inputs[0];\n        uint256 account = inputs[1];\n        uint256 tokenBalance = IERC721(address(uint160(token))).balanceOf(address(uint160(account)));\n        uint256[] memory outputs = new uint256[](1);\n        outputs[0] = tokenBalance;\n        return outputs;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/erc721/LibOpERC721OwnerOfNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {IERC721} from \"openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\n\n/// @title LibOpERC721OwnerOfNP\n/// @notice Opcode for getting the current owner of an erc721 token.\nlibrary LibOpERC721OwnerOfNP {\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        // Always 2 inputs, the token and the tokenId.\n        // Always 1 output, the owner.\n        return (2, 1);\n    }\n\n    function run(InterpreterStateNP memory, Operand, Pointer stackTop) internal view returns (Pointer) {\n        uint256 token;\n        uint256 tokenId;\n        assembly {\n            token := mload(stackTop)\n            stackTop := add(stackTop, 0x20)\n            tokenId := mload(stackTop)\n        }\n        address tokenOwner = IERC721(address(uint160(token))).ownerOf(tokenId);\n        assembly {\n            mstore(stackTop, tokenOwner)\n        }\n        return stackTop;\n    }\n\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        view\n        returns (uint256[] memory)\n    {\n        uint256 token = inputs[0];\n        uint256 tokenId = inputs[1];\n        address tokenOwner = IERC721(address(uint160(token))).ownerOf(tokenId);\n        uint256[] memory outputs = new uint256[](1);\n        outputs[0] = uint256(uint160(tokenOwner));\n        return outputs;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/evm/LibOpBlockNumberNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\n\n/// @title LibOpBlockNumberNP\n/// Implementation of the EVM `BLOCKNUMBER` opcode as a standard Rainlang opcode.\nlibrary LibOpBlockNumberNP {\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        return (0, 1);\n    }\n\n    function run(InterpreterStateNP memory, Operand, Pointer stackTop) internal view returns (Pointer) {\n        assembly (\"memory-safe\") {\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, number())\n        }\n        return stackTop;\n    }\n\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory)\n        internal\n        view\n        returns (uint256[] memory)\n    {\n        uint256[] memory outputs = new uint256[](1);\n        outputs[0] = block.number;\n        return outputs;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/evm/LibOpChainIdNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\n\n/// @title LibOpChainIdNP\n/// Implementation of the EVM `CHAINID` opcode as a standard Rainlang opcode.\nlibrary LibOpChainIdNP {\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        return (0, 1);\n    }\n\n    function run(InterpreterStateNP memory, Operand, Pointer stackTop) internal view returns (Pointer) {\n        assembly (\"memory-safe\") {\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, chainid())\n        }\n        return stackTop;\n    }\n\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory)\n        internal\n        view\n        returns (uint256[] memory)\n    {\n        uint256[] memory outputs = new uint256[](1);\n        outputs[0] = block.chainid;\n        return outputs;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/evm/LibOpMaxUint256NP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\n\n/// @title LibOpMaxUint256NP\n/// Exposes `type(uint256).max` as a Rainlang opcode.\nlibrary LibOpMaxUint256NP {\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        return (0, 1);\n    }\n\n    function run(InterpreterStateNP memory, Operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 value = type(uint256).max;\n        assembly (\"memory-safe\") {\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, value)\n        }\n        return stackTop;\n    }\n\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory)\n        internal\n        pure\n        returns (uint256[] memory)\n    {\n        uint256[] memory outputs = new uint256[](1);\n        outputs[0] = type(uint256).max;\n        return outputs;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/evm/LibOpTimestampNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP, LibInterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\n\n/// @title LibOpTimestampNP\n/// Implementation of the EVM `TIMESTAMP` opcode as a standard Rainlang opcode.\nlibrary LibOpTimestampNP {\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        return (0, 1);\n    }\n\n    function run(InterpreterStateNP memory, Operand, Pointer stackTop) internal view returns (Pointer) {\n        assembly (\"memory-safe\") {\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, timestamp())\n        }\n        return stackTop;\n    }\n\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory)\n        internal\n        view\n        returns (uint256[] memory)\n    {\n        uint256[] memory outputs = new uint256[](1);\n        outputs[0] = block.timestamp;\n        return outputs;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/logic/LibOpAnyNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\n\n/// @title LibOpAnyNP\n/// @notice Opcode to return the first nonzero item on the stack up to the inputs\n/// limit.\nlibrary LibOpAnyNP {\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        // There must be at least one input.\n        uint256 inputs = Operand.unwrap(operand) >> 0x10;\n        inputs = inputs > 0 ? inputs : 1;\n        return (inputs, 1);\n    }\n\n    /// ANY\n    /// ANY is the first nonzero item, else 0.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            let length := mul(shr(0x10, operand), 0x20)\n            let cursor := stackTop\n            stackTop := sub(add(stackTop, length), 0x20)\n            for { let end := add(cursor, length) } lt(cursor, end) { cursor := add(cursor, 0x20) } {\n                let item := mload(cursor)\n                if gt(item, 0) {\n                    mstore(stackTop, item)\n                    break\n                }\n            }\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of ANY for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        // Zero length inputs is not supported so this 0 will always be written\n        // over.\n        uint256 value = 0;\n        for (uint256 i = 0; i < inputs.length; i++) {\n            value = inputs[i];\n            if (value != 0) {\n                break;\n            }\n        }\n        outputs = new uint256[](1);\n        outputs[0] = value;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/logic/LibOpConditionsNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\n\n/// Thrown if no nonzero condition is found.\n/// @param condCode The condition code that was evaluated. This is the low 16\n/// bits of the operand. Allows the author to provide more context about which\n/// condition failed if there is more than one in the expression.\nerror NoConditionsMet(uint256 condCode);\n\n/// @title LibOpConditionsNP\n/// @notice Opcode to return the first nonzero item on the stack up to the inputs\n/// limit.\nlibrary LibOpConditionsNP {\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        // There must be at least two inputs.\n        uint256 inputs = Operand.unwrap(operand) >> 0x10;\n        inputs = inputs > 0 ? inputs : 2;\n        // Odd inputs are not allowed.\n        unchecked {\n            inputs = inputs % 2 == 0 ? inputs : inputs + 1;\n        }\n        return (inputs, 1);\n    }\n\n    /// `conditions`\n    /// Pairwise list of conditions and values. The first nonzero condition\n    /// evaluated puts its corresponding value on the stack. `conditions` is\n    /// eagerly evaluated. If no condition is nonzero, the expression will\n    /// revert. The number of inputs must be even. The number of outputs is 1.\n    /// If an author wants to provide some default value, they can set the last\n    /// condition to some nonzero constant value such as 1.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 condition;\n        assembly (\"memory-safe\") {\n            let cursor := stackTop\n            for {\n                let end := add(cursor, mul(shr(0x10, operand), 0x20))\n                stackTop := sub(end, 0x20)\n            } lt(cursor, end) { cursor := add(cursor, 0x40) } {\n                condition := mload(cursor)\n                if condition {\n                    mstore(stackTop, mload(add(cursor, 0x20)))\n                    break\n                }\n            }\n        }\n        if (condition == 0) {\n            revert NoConditionsMet(uint16(Operand.unwrap(operand)));\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of `condition` for testing.\n    function referenceFn(InterpreterStateNP memory, Operand operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        // Unchecked so that any overflow errors come from the real\n        // implementation.\n        unchecked {\n            uint256 length = inputs.length;\n            require(length % 2 == 0, \"Odd number of inputs\");\n            outputs = new uint256[](1);\n            for (uint256 i = 0; i < length; i += 2) {\n                if (inputs[i] != 0) {\n                    outputs[0] = inputs[i + 1];\n                    return outputs;\n                }\n            }\n            revert NoConditionsMet(uint16(Operand.unwrap(operand)));\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/logic/LibOpEnsureNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\n\n/// Thrown if a zero condition is found.\n/// @param ensureCode The ensure code that was evaluated. This is the low 16\n/// bits of the operand. Allows the author to provide more context about which\n/// condition failed if there is more than one in the expression.\n/// @param errorIndex The index of the condition that failed.\nerror EnsureFailed(uint256 ensureCode, uint256 errorIndex);\n\n/// @title LibOpEnsureNP\n/// @notice Opcode to revert if any condition is zero.\nlibrary LibOpEnsureNP {\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        // There must be at least one input.\n        uint256 inputs = Operand.unwrap(operand) >> 0x10;\n        inputs = inputs > 0 ? inputs : 1;\n        return (inputs, 0);\n    }\n\n    /// `ensure`\n    /// List of conditions. If any condition is zero, the expression will revert.\n    /// All conditions are eagerly evaluated and there are no outputs.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 condition;\n        Pointer cursor = stackTop;\n        assembly (\"memory-safe\") {\n            for {\n                let end := add(cursor, mul(shr(0x10, operand), 0x20))\n                condition := mload(cursor)\n                cursor := add(cursor, 0x20)\n            } and(lt(cursor, end), gt(condition, 0)) {} {\n                condition := mload(cursor)\n                cursor := add(cursor, 0x20)\n            }\n        }\n        if (condition == 0) {\n            // If somehow we hit an underflow on the pointer math, we'd still\n            // prefer to see our ensure error rather than the generic underflow\n            // error.\n            unchecked {\n                revert EnsureFailed(\n                    uint16(Operand.unwrap(operand)), (Pointer.unwrap(cursor) - Pointer.unwrap(stackTop) - 0x20) / 0x20\n                );\n            }\n        }\n        return cursor;\n    }\n\n    /// Gas intensive reference implementation of `ensure` for testing.\n    function referenceFn(InterpreterStateNP memory, Operand operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        // Unchecked so that any overflow errors come from the real\n        // implementation.\n        unchecked {\n            for (uint256 i = 0; i < inputs.length; i++) {\n                if (inputs[i] == 0) {\n                    revert EnsureFailed(uint16(Operand.unwrap(operand)), i);\n                }\n            }\n            outputs = new uint256[](0);\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/logic/LibOpEqualToNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\n\n/// @title LibOpEqualToNP\n/// @notice Opcode to return 1 if the first item on the stack is equal to\n/// the second item on the stack, else 0.\nlibrary LibOpEqualToNP {\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        return (2, 1);\n    }\n\n    /// EQ\n    /// EQ is 1 if the first item is equal to the second item, else 0.\n    function run(InterpreterStateNP memory, Operand, Pointer stackTop) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            let a := mload(stackTop)\n            stackTop := add(stackTop, 0x20)\n            mstore(stackTop, eq(a, mload(stackTop)))\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of EQ for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        outputs = new uint256[](1);\n        outputs[0] = inputs[0] == inputs[1] ? 1 : 0;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/logic/LibOpEveryNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\n\n/// @title LibOpEveryNP\n/// @notice Opcode to return the last item out of N items if they are all true,\n/// else 0.\nlibrary LibOpEveryNP {\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        // There must be at least one input.\n        uint256 inputs = Operand.unwrap(operand) >> 0x10;\n        inputs = inputs > 0 ? inputs : 1;\n        return (inputs, 1);\n    }\n\n    /// EVERY is the last nonzero item, else 0.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            let length := mul(shr(0x10, operand), 0x20)\n            let cursor := stackTop\n            stackTop := sub(add(stackTop, length), 0x20)\n            for { let end := add(cursor, length) } lt(cursor, end) { cursor := add(cursor, 0x20) } {\n                let item := mload(cursor)\n                if iszero(item) {\n                    mstore(stackTop, item)\n                    break\n                }\n            }\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of EVERY for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        // Zero length inputs is not supported so this 0 will always be written\n        // over.\n        uint256 value = 0;\n        for (uint256 i = 0; i < inputs.length; i++) {\n            value = inputs[i];\n            if (value == 0) {\n                break;\n            }\n        }\n        outputs = new uint256[](1);\n        outputs[0] = value;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/logic/LibOpGreaterThanNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\n\n/// @title LibOpGreaterThanNP\n/// @notice Opcode to return 1 if the first item on the stack is greater than\n/// the second item on the stack, else 0.\nlibrary LibOpGreaterThanNP {\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        return (2, 1);\n    }\n\n    /// GT\n    /// GT is 1 if the first item is greater than the second item, else 0.\n    function run(InterpreterStateNP memory, Operand, Pointer stackTop) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            let a := mload(stackTop)\n            stackTop := add(stackTop, 0x20)\n            mstore(stackTop, gt(a, mload(stackTop)))\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of GT for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        outputs = new uint256[](1);\n        outputs[0] = inputs[0] > inputs[1] ? 1 : 0;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/logic/LibOpGreaterThanOrEqualToNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\n\n/// @title LibOpGreaterThanOrEqualToNP\n/// @notice Opcode to return 1 if the first item on the stack is greater than or\n/// equal to the second item on the stack, else 0.\nlibrary LibOpGreaterThanOrEqualToNP {\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        return (2, 1);\n    }\n\n    /// GTE\n    /// GTE is 1 if the first item is greater than or equal to the second item,\n    /// else 0.\n    function run(InterpreterStateNP memory, Operand, Pointer stackTop) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            let a := mload(stackTop)\n            stackTop := add(stackTop, 0x20)\n            mstore(stackTop, iszero(lt(a, mload(stackTop))))\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of GTE for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        outputs = new uint256[](1);\n        outputs[0] = inputs[0] >= inputs[1] ? 1 : 0;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/logic/LibOpIfNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\n\n/// @title LibOpIfNP\n/// @notice Opcode to choose between two values based on a condition. If is\n/// eager, meaning both values are evaluated before the condition is checked.\nlibrary LibOpIfNP {\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        return (3, 1);\n    }\n\n    /// IF\n    /// IF is a conditional. If the first item on the stack is nonero, the second\n    /// item is returned, else the third item is returned.\n    function run(InterpreterStateNP memory, Operand, Pointer stackTop) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            let condition := mload(stackTop)\n            stackTop := add(stackTop, 0x40)\n            mstore(stackTop, mload(sub(stackTop, mul(0x20, iszero(iszero(condition))))))\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of IF for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        outputs = new uint256[](1);\n        outputs[0] = inputs[0] > 0 ? inputs[1] : inputs[2];\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/logic/LibOpIsZeroNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\n\n/// @title LibOpIsZeroNP\n/// @notice Opcode to return 1 if the top item on the stack is zero, else 0.\nlibrary LibOpIsZeroNP {\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        return (1, 1);\n    }\n\n    /// ISZERO\n    /// ISZERO is 1 if the top item is zero, else 0.\n    function run(InterpreterStateNP memory, Operand, Pointer stackTop) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            mstore(stackTop, iszero(mload(stackTop)))\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of ISZERO for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        outputs = new uint256[](1);\n        outputs[0] = inputs[0] == 0 ? 1 : 0;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/logic/LibOpLessThanNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\n\n/// @title LibOpLessThanNP\n/// @notice Opcode to return 1 if the first item on the stack is less than\n/// the second item on the stack, else 0.\nlibrary LibOpLessThanNP {\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        return (2, 1);\n    }\n\n    /// LT\n    /// LT is 1 if the first item is less than the second item, else 0.\n    function run(InterpreterStateNP memory, Operand, Pointer stackTop) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            let a := mload(stackTop)\n            stackTop := add(stackTop, 0x20)\n            mstore(stackTop, lt(a, mload(stackTop)))\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of LT for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        outputs = new uint256[](1);\n        outputs[0] = inputs[0] < inputs[1] ? 1 : 0;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/logic/LibOpLessThanOrEqualToNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\n\n/// @title LibOpLessThanOrEqualToNP\n/// @notice Opcode to return 1 if the first item on the stack is less than or\n/// equal to the second item on the stack, else 0.\nlibrary LibOpLessThanOrEqualToNP {\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        return (2, 1);\n    }\n\n    /// LTE\n    /// LTE is 1 if the first item is less than or equal to the second item,\n    /// else 0.\n    function run(InterpreterStateNP memory, Operand, Pointer stackTop) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            let a := mload(stackTop)\n            stackTop := add(stackTop, 0x20)\n            mstore(stackTop, iszero(gt(a, mload(stackTop))))\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of LTE for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        outputs = new uint256[](1);\n        outputs[0] = inputs[0] <= inputs[1] ? 1 : 0;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/math/decimal18/LibOpDecimal18MulNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// Used for reference implementation so that we have two independent\n/// upstreams to compare against.\nimport {Math as OZMath} from \"openzeppelin-contracts/contracts/utils/math/Math.sol\";\nimport {UD60x18, mul} from \"prb-math/UD60x18.sol\";\nimport {Operand} from \"../../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {InterpreterStateNP} from \"../../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../../integrity/LibIntegrityCheckNP.sol\";\nimport {LibWillOverflow} from \"rain.math.fixedpoint/lib/LibWillOverflow.sol\";\n\n/// @title LibOpDecimal18MulNP\n/// @notice Opcode to mul N 18 decimal fixed point values. Errors on overflow.\nlibrary LibOpDecimal18MulNP {\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        // There must be at least two inputs.\n        uint256 inputs = Operand.unwrap(operand) >> 0x10;\n        inputs = inputs > 1 ? inputs : 2;\n        return (inputs, 1);\n    }\n\n    /// decimal18-mul\n    /// 18 decimal fixed point multiplication with implied overflow checks from\n    /// PRB Math.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 a;\n        uint256 b;\n        assembly (\"memory-safe\") {\n            a := mload(stackTop)\n            b := mload(add(stackTop, 0x20))\n            stackTop := add(stackTop, 0x40)\n        }\n        a = UD60x18.unwrap(mul(UD60x18.wrap(a), UD60x18.wrap(b)));\n\n        {\n            uint256 inputs = Operand.unwrap(operand) >> 0x10;\n            uint256 i = 2;\n            while (i < inputs) {\n                assembly (\"memory-safe\") {\n                    b := mload(stackTop)\n                    stackTop := add(stackTop, 0x20)\n                }\n                a = UD60x18.unwrap(mul(UD60x18.wrap(a), UD60x18.wrap(b)));\n                unchecked {\n                    i++;\n                }\n            }\n        }\n        assembly (\"memory-safe\") {\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, a)\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of multiplication for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        // Unchecked so that when we assert that an overflow error is thrown, we\n        // see the revert from the real function and not the reference function.\n        unchecked {\n            uint256 a = inputs[0];\n            for (uint256 i = 1; i < inputs.length; i++) {\n                uint256 b = inputs[i];\n                if (LibWillOverflow.mulDivWillOverflow(a, b, 1e18)) {\n                    a = uint256(keccak256(abi.encodePacked(\"overflow sentinel\")));\n                    break;\n                }\n                a = OZMath.mulDiv(a, b, 1e18);\n            }\n            outputs = new uint256[](1);\n            outputs[0] = a;\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/math/decimal18/LibOpDecimal18DivNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// Used for reference implementation so that we have two independent\n/// upstreams to compare against.\nimport {Math as OZMath} from \"openzeppelin-contracts/contracts/utils/math/Math.sol\";\nimport {LibWillOverflow} from \"rain.math.fixedpoint/lib/LibWillOverflow.sol\";\nimport {UD60x18, div} from \"prb-math/UD60x18.sol\";\nimport {Operand} from \"../../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {InterpreterStateNP} from \"../../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../../integrity/LibIntegrityCheckNP.sol\";\n\n/// @title LibOpDecimal18DivNP\n/// @notice Opcode to div N 18 decimal fixed point values. Errors on overflow.\nlibrary LibOpDecimal18DivNP {\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        // There must be at least two inputs.\n        uint256 inputs = Operand.unwrap(operand) >> 0x10;\n        inputs = inputs > 1 ? inputs : 2;\n        return (inputs, 1);\n    }\n\n    /// decimal18-div\n    /// 18 decimal fixed point division with implied overflow checks from PRB\n    /// Math.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 a;\n        uint256 b;\n        assembly (\"memory-safe\") {\n            a := mload(stackTop)\n            b := mload(add(stackTop, 0x20))\n            stackTop := add(stackTop, 0x40)\n        }\n        a = UD60x18.unwrap(div(UD60x18.wrap(a), UD60x18.wrap(b)));\n\n        {\n            uint256 inputs = Operand.unwrap(operand) >> 0x10;\n            uint256 i = 2;\n            while (i < inputs) {\n                assembly (\"memory-safe\") {\n                    b := mload(stackTop)\n                    stackTop := add(stackTop, 0x20)\n                }\n                a = UD60x18.unwrap(div(UD60x18.wrap(a), UD60x18.wrap(b)));\n                unchecked {\n                    i++;\n                }\n            }\n        }\n        assembly (\"memory-safe\") {\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, a)\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of division for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        // Unchecked so that when we assert that an overflow error is thrown, we\n        // see the revert from the real function and not the reference function.\n        unchecked {\n            uint256 a = inputs[0];\n            for (uint256 i = 1; i < inputs.length; i++) {\n                uint256 b = inputs[i];\n                // Just bail out with a = some sentinel value if we're going to\n                // overflow or divide by zero. This gives the real implementation\n                // space to throw its own error that the test harness is expecting.\n                // We don't want the real implementation to fail to throw the\n                // error and also produce the same result, so a needs to have\n                // some collision resistant value.\n                if (b == 0 || LibWillOverflow.mulDivWillOverflow(a, 1e18, b)) {\n                    a = uint256(keccak256(abi.encodePacked(\"overflow sentinel\")));\n                    break;\n                }\n                a = OZMath.mulDiv(a, 1e18, b);\n            }\n            outputs = new uint256[](1);\n            outputs[0] = a;\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/math/decimal18/LibOpDecimal18Scale18DynamicNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {LibFixedPointDecimalScale} from \"rain.math.fixedpoint/lib/LibFixedPointDecimalScale.sol\";\nimport {MASK_2BIT} from \"sol.lib.binmaskflag/Binary.sol\";\nimport {Operand} from \"../../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {IntegrityCheckStateNP} from \"../../../integrity/LibIntegrityCheckNP.sol\";\nimport {InterpreterStateNP} from \"../../../state/LibInterpreterStateNP.sol\";\n\n/// @title LibOpDecimal18Scale18DynamicNP\n/// @notice Opcode for scaling a number to 18 decimal fixed point based on\n/// runtime scale input.\nlibrary LibOpDecimal18Scale18DynamicNP {\n    using LibFixedPointDecimalScale for uint256;\n\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        return (2, 1);\n    }\n\n    /// decimal18-scale18-dynamic\n    /// 18 decimal fixed point scaling from runtime value.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 a;\n        uint256 scale;\n        assembly (\"memory-safe\") {\n            scale := mload(stackTop)\n            stackTop := add(stackTop, 0x20)\n            a := mload(stackTop)\n        }\n        a = a.scale18(scale, Operand.unwrap(operand));\n        assembly (\"memory-safe\") {\n            mstore(stackTop, a)\n        }\n        return stackTop;\n    }\n\n    function referenceFn(InterpreterStateNP memory, Operand operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        outputs = new uint256[](1);\n        outputs[0] = inputs[1].scale18(inputs[0], Operand.unwrap(operand) & MASK_2BIT);\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/math/decimal18/LibOpDecimal18Scale18NP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {LibFixedPointDecimalScale} from \"rain.math.fixedpoint/lib/LibFixedPointDecimalScale.sol\";\nimport {Operand} from \"../../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP} from \"../../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../../integrity/LibIntegrityCheckNP.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\n\n/// @title LibOpDecimal18Scale18NP\n/// @notice Opcode for scaling a number to 18 decimal fixed point.\nlibrary LibOpDecimal18Scale18NP {\n    using LibFixedPointDecimalScale for uint256;\n\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        return (1, 1);\n    }\n\n    /// decimal18-scale18\n    /// 18 decimal fixed point scaling.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 a;\n        assembly (\"memory-safe\") {\n            a := mload(stackTop)\n        }\n        a = a.scale18(Operand.unwrap(operand) & 0xFF, Operand.unwrap(operand) >> 8);\n        assembly (\"memory-safe\") {\n            mstore(stackTop, a)\n        }\n        return stackTop;\n    }\n\n    function referenceFn(InterpreterStateNP memory, Operand operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        outputs = new uint256[](1);\n        outputs[0] = inputs[0].scale18(Operand.unwrap(operand) & 0xFF, Operand.unwrap(operand) >> 8);\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/math/decimal18/LibOpDecimal18ScaleNNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {LibFixedPointDecimalScale} from \"rain.math.fixedpoint/lib/LibFixedPointDecimalScale.sol\";\nimport {Operand} from \"../../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP} from \"../../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../../integrity/LibIntegrityCheckNP.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\n\n/// @title LibOpDecimal18ScaleNNP\n/// @notice Opcode for scaling a decimal18 number to some other scale N.\nlibrary LibOpDecimal18ScaleNNP {\n    using LibFixedPointDecimalScale for uint256;\n\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        return (1, 1);\n    }\n\n    /// decimal18-scale-n\n    /// Scale from 18 decimal to n decimal.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 a;\n        assembly (\"memory-safe\") {\n            a := mload(stackTop)\n        }\n        a = a.scaleN(Operand.unwrap(operand) & 0xFF, Operand.unwrap(operand) >> 8);\n        assembly (\"memory-safe\") {\n            mstore(stackTop, a)\n        }\n        return stackTop;\n    }\n\n    function referenceFn(InterpreterStateNP memory, Operand operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        outputs = new uint256[](1);\n        outputs[0] = inputs[0].scaleN(Operand.unwrap(operand) & 0xFF, Operand.unwrap(operand) >> 8);\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/math/int/LibOpIntAddNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {InterpreterStateNP} from \"../../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../../integrity/LibIntegrityCheckNP.sol\";\n\n/// @title LibOpIntAddNP\n/// @notice Opcode to add N integers. Errors on overflow.\nlibrary LibOpIntAddNP {\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        // There must be at least two inputs.\n        uint256 inputs = Operand.unwrap(operand) >> 0x10;\n        inputs = inputs > 1 ? inputs : 2;\n        return (inputs, 1);\n    }\n\n    /// int-add\n    /// Addition with implied overflow checks from the Solidity 0.8.x compiler.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 a;\n        uint256 b;\n        assembly (\"memory-safe\") {\n            a := mload(stackTop)\n            b := mload(add(stackTop, 0x20))\n            stackTop := add(stackTop, 0x40)\n        }\n        a += b;\n\n        {\n            uint256 inputs = Operand.unwrap(operand) >> 0x10;\n            uint256 i = 2;\n            while (i < inputs) {\n                assembly (\"memory-safe\") {\n                    b := mload(stackTop)\n                    stackTop := add(stackTop, 0x20)\n                }\n                a += b;\n                unchecked {\n                    i++;\n                }\n            }\n        }\n\n        assembly (\"memory-safe\") {\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, a)\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of addition for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        // Unchecked so that when we assert that an overflow error is thrown, we\n        // see the revert from the real function and not the reference function.\n        unchecked {\n            uint256 acc = inputs[0];\n            for (uint256 i = 1; i < inputs.length; i++) {\n                acc += inputs[i];\n            }\n            outputs = new uint256[](1);\n            outputs[0] = acc;\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/math/int/LibOpIntDivNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {IntegrityCheckStateNP} from \"../../../integrity/LibIntegrityCheckNP.sol\";\nimport {InterpreterStateNP} from \"../../../state/LibInterpreterStateNP.sol\";\n\n/// @title LibOpIntDivNP\n/// @notice Opcode to divide N integers. Errors on divide by zero. Truncates\n/// towards zero.\nlibrary LibOpIntDivNP {\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        // There must be at least two inputs.\n        uint256 inputs = Operand.unwrap(operand) >> 0x10;\n        inputs = inputs > 1 ? inputs : 2;\n        return (inputs, 1);\n    }\n\n    /// int-div\n    /// Division with implied checks from the Solidity 0.8.x compiler.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 a;\n        uint256 b;\n        assembly (\"memory-safe\") {\n            a := mload(stackTop)\n            b := mload(add(stackTop, 0x20))\n            stackTop := add(stackTop, 0x40)\n        }\n        a /= b;\n\n        {\n            uint256 inputs = Operand.unwrap(operand) >> 0x10;\n            uint256 i = 2;\n            while (i < inputs) {\n                assembly (\"memory-safe\") {\n                    b := mload(stackTop)\n                    stackTop := add(stackTop, 0x20)\n                }\n                a /= b;\n                unchecked {\n                    i++;\n                }\n            }\n        }\n\n        assembly (\"memory-safe\") {\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, a)\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of division for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        // Unchecked so that when we assert that an overflow error is thrown, we\n        // see the revert from the real function and not the reference function.\n        unchecked {\n            uint256 acc = inputs[0];\n            for (uint256 i = 1; i < inputs.length; i++) {\n                acc /= inputs[i];\n            }\n            outputs = new uint256[](1);\n            outputs[0] = acc;\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/math/int/LibOpIntExpNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {InterpreterStateNP} from \"../../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../../integrity/LibIntegrityCheckNP.sol\";\n\n/// @title LibOpIntExpNP\n/// @notice Opcode to raise x successively to N integers. Errors on overflow.\nlibrary LibOpIntExpNP {\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        // There must be at least two inputs.\n        uint256 inputs = Operand.unwrap(operand) >> 0x10;\n        inputs = inputs > 1 ? inputs : 2;\n        return (inputs, 1);\n    }\n\n    /// int-exp\n    /// Exponentiation with implied overflow checks from the Solidity 0.8.x\n    /// compiler.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 a;\n        uint256 b;\n        assembly (\"memory-safe\") {\n            a := mload(stackTop)\n            b := mload(add(stackTop, 0x20))\n            stackTop := add(stackTop, 0x40)\n        }\n        a = a ** b;\n\n        {\n            uint256 inputs = Operand.unwrap(operand) >> 0x10;\n            uint256 i = 2;\n            while (i < inputs) {\n                assembly (\"memory-safe\") {\n                    b := mload(stackTop)\n                    stackTop := add(stackTop, 0x20)\n                }\n                a = a ** b;\n                unchecked {\n                    i++;\n                }\n            }\n        }\n        assembly (\"memory-safe\") {\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, a)\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of exponentiation for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        // Unchecked so that when we assert that an overflow error is thrown, we\n        // see the revert from the real function and not the reference function.\n        unchecked {\n            uint256 acc = inputs[0];\n            for (uint256 i = 1; i < inputs.length; i++) {\n                acc = acc ** inputs[i];\n            }\n            outputs = new uint256[](1);\n            outputs[0] = acc;\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/math/int/LibOpIntMaxNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {InterpreterStateNP} from \"../../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../../integrity/LibIntegrityCheckNP.sol\";\n\n/// @title LibOpIntMaxNP\n/// @notice Opcode to find the max from N integers.\nlibrary LibOpIntMaxNP {\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        // There must be at least two inputs.\n        uint256 inputs = Operand.unwrap(operand) >> 0x10;\n        inputs = inputs > 1 ? inputs : 2;\n        return (inputs, 1);\n    }\n\n    /// int-max\n    /// Finds the maximum value from N integers.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 a;\n        uint256 b;\n        assembly (\"memory-safe\") {\n            a := mload(stackTop)\n            b := mload(add(stackTop, 0x20))\n            stackTop := add(stackTop, 0x40)\n        }\n        if (a < b) {\n            a = b;\n        }\n\n        {\n            uint256 inputs = Operand.unwrap(operand) >> 0x10;\n            uint256 i = 2;\n            while (i < inputs) {\n                assembly (\"memory-safe\") {\n                    b := mload(stackTop)\n                    stackTop := add(stackTop, 0x20)\n                }\n                if (a < b) {\n                    a = b;\n                }\n                unchecked {\n                    i++;\n                }\n            }\n        }\n\n        assembly (\"memory-safe\") {\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, a)\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of maximum for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        // Unchecked so that when we assert that an overflow error is thrown, we\n        // see the revert from the real function and not the reference function.\n        unchecked {\n            uint256 acc = inputs[0];\n            for (uint256 i = 1; i < inputs.length; i++) {\n                acc = acc < inputs[i] ? inputs[i] : acc;\n            }\n            outputs = new uint256[](1);\n            outputs[0] = acc;\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/math/int/LibOpIntMinNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {InterpreterStateNP} from \"../../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../../integrity/LibIntegrityCheckNP.sol\";\n\n/// @title LibOpIntMinNP\n/// @notice Opcode to find the min from N integers.\nlibrary LibOpIntMinNP {\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        // There must be at least two inputs.\n        uint256 inputs = Operand.unwrap(operand) >> 0x10;\n        inputs = inputs > 1 ? inputs : 2;\n        return (inputs, 1);\n    }\n\n    /// int-min\n    /// Finds the minimum value from N integers.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 a;\n        uint256 b;\n        assembly (\"memory-safe\") {\n            a := mload(stackTop)\n            b := mload(add(stackTop, 0x20))\n            stackTop := add(stackTop, 0x40)\n        }\n        if (a > b) {\n            a = b;\n        }\n\n        {\n            uint256 inputs = Operand.unwrap(operand) >> 0x10;\n            uint256 i = 2;\n            while (i < inputs) {\n                assembly (\"memory-safe\") {\n                    b := mload(stackTop)\n                    stackTop := add(stackTop, 0x20)\n                }\n                if (a > b) {\n                    a = b;\n                }\n                unchecked {\n                    i++;\n                }\n            }\n        }\n\n        assembly (\"memory-safe\") {\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, a)\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of minimum for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        // Unchecked so that when we assert that an overflow error is thrown, we\n        // see the revert from the real function and not the reference function.\n        unchecked {\n            uint256 acc = inputs[0];\n            for (uint256 i = 1; i < inputs.length; i++) {\n                acc = acc > inputs[i] ? inputs[i] : acc;\n            }\n            outputs = new uint256[](1);\n            outputs[0] = acc;\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/math/int/LibOpIntModNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../../interface/IInterpreterV1.sol\";\nimport {Pointer, LibPointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {IntegrityCheckStateNP} from \"../../../integrity/LibIntegrityCheckNP.sol\";\nimport {InterpreterStateNP} from \"../../../state/LibInterpreterStateNP.sol\";\n\n/// @title LibOpIntModNP\n/// @notice Opcode to modulo N integers. Errors on modulo by zero.\nlibrary LibOpIntModNP {\n    using LibPointer for Pointer;\n\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        // There must be at least two inputs.\n        uint256 inputs = Operand.unwrap(operand) >> 0x10;\n        inputs = inputs > 1 ? inputs : 2;\n        return (inputs, 1);\n    }\n\n    /// int-mod\n    /// Modulo with implied checks from the Solidity 0.8.x compiler.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 a;\n        uint256 b;\n        assembly (\"memory-safe\") {\n            a := mload(stackTop)\n            b := mload(add(stackTop, 0x20))\n            stackTop := add(stackTop, 0x40)\n        }\n        a %= b;\n\n        {\n            uint256 inputs = Operand.unwrap(operand) >> 0x10;\n            uint256 i = 2;\n            while (i < inputs) {\n                assembly (\"memory-safe\") {\n                    b := mload(stackTop)\n                    stackTop := add(stackTop, 0x20)\n                }\n                a %= b;\n                unchecked {\n                    i++;\n                }\n            }\n        }\n\n        assembly (\"memory-safe\") {\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, a)\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of modulo for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        // Unchecked so that when we assert that an overflow error is thrown, we\n        // see the revert from the real function and not the reference function.\n        unchecked {\n            uint256 acc = inputs[0];\n            for (uint256 i = 1; i < inputs.length; i++) {\n                acc %= inputs[i];\n            }\n            outputs = new uint256[](1);\n            outputs[0] = acc;\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/math/int/LibOpIntMulNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {IntegrityCheckStateNP} from \"../../../integrity/LibIntegrityCheckNP.sol\";\nimport {InterpreterStateNP} from \"../../../state/LibInterpreterStateNP.sol\";\n\n/// @title LibOpIntMulNP\n/// @notice Opcode to mul N integers. Errors on overflow.\nlibrary LibOpIntMulNP {\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        // There must be at least two inputs.\n        uint256 inputs = Operand.unwrap(operand) >> 0x10;\n        inputs = inputs > 1 ? inputs : 2;\n        return (inputs, 1);\n    }\n\n    /// int-mul\n    /// Multiplication with implied overflow checks from the Solidity 0.8.x\n    /// compiler.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 a;\n        uint256 b;\n        assembly (\"memory-safe\") {\n            a := mload(stackTop)\n            b := mload(add(stackTop, 0x20))\n            stackTop := add(stackTop, 0x40)\n        }\n        a *= b;\n\n        {\n            uint256 inputs = Operand.unwrap(operand) >> 0x10;\n            uint256 i = 2;\n            while (i < inputs) {\n                assembly (\"memory-safe\") {\n                    b := mload(stackTop)\n                    stackTop := add(stackTop, 0x20)\n                }\n                a *= b;\n                unchecked {\n                    i++;\n                }\n            }\n        }\n        assembly (\"memory-safe\") {\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, a)\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of multiplication for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        // Unchecked so that when we assert that an overflow error is thrown, we\n        // see the revert from the real function and not the reference function.\n        unchecked {\n            uint256 acc = inputs[0];\n            for (uint256 i = 1; i < inputs.length; i++) {\n                acc *= inputs[i];\n            }\n            outputs = new uint256[](1);\n            outputs[0] = acc;\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/math/int/LibOpIntSubNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand} from \"../../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {IntegrityCheckStateNP} from \"../../../integrity/LibIntegrityCheckNP.sol\";\nimport {InterpreterStateNP} from \"../../../state/LibInterpreterStateNP.sol\";\n\n/// @title LibOpIntSubNP\n/// @notice Opcode to subtract N integers.\nlibrary LibOpIntSubNP {\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        // There must be at least two inputs.\n        uint256 inputs = Operand.unwrap(operand) >> 0x10;\n        inputs = inputs > 1 ? inputs : 2;\n        return (inputs, 1);\n    }\n\n    /// int-sub\n    /// Subtraction with implied overflow checks from the Solidity 0.8.x compiler.\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal pure returns (Pointer) {\n        uint256 a;\n        uint256 b;\n        assembly (\"memory-safe\") {\n            a := mload(stackTop)\n            b := mload(add(stackTop, 0x20))\n            stackTop := add(stackTop, 0x40)\n        }\n        a -= b;\n\n        {\n            uint256 inputs = Operand.unwrap(operand) >> 0x10;\n            uint256 i = 2;\n            while (i < inputs) {\n                assembly (\"memory-safe\") {\n                    b := mload(stackTop)\n                    stackTop := add(stackTop, 0x20)\n                }\n                a -= b;\n                unchecked {\n                    i++;\n                }\n            }\n        }\n\n        assembly (\"memory-safe\") {\n            stackTop := sub(stackTop, 0x20)\n            mstore(stackTop, a)\n        }\n        return stackTop;\n    }\n\n    /// Gas intensive reference implementation of subtraction for testing.\n    function referenceFn(InterpreterStateNP memory, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory outputs)\n    {\n        // Unchecked so that when we assert that an overflow error is thrown, we\n        // see the revert from the real function and not the reference function.\n        unchecked {\n            uint256 acc = inputs[0];\n            for (uint256 i = 1; i < inputs.length; i++) {\n                acc -= inputs[i];\n            }\n            outputs = new uint256[](1);\n            outputs[0] = acc;\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/store/LibOpGetNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {MemoryKVKey, MemoryKVVal, MemoryKV, LibMemoryKV} from \"rain.lib.memkv/lib/LibMemoryKV.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\n\n/// @title LibOpGetNP\n/// @notice Opcode for reading from storage.\nlibrary LibOpGetNP {\n    using LibMemoryKV for MemoryKV;\n\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        // Always 1 input. The key. `hash()` is recommended to build compound\n        // keys.\n        return (1, 1);\n    }\n\n    /// Implements runtime behaviour of the `get` opcode. Attempts to lookup the\n    /// key in the memory key/value store then falls back to the interpreter's\n    /// storage interface as an external call. If the key is not found in either,\n    /// the value will fallback to `0` as per default Solidity/EVM behaviour.\n    /// @param state The interpreter state of the current eval.\n    /// @param stackTop Pointer to the current stack top.\n    function run(InterpreterStateNP memory state, Operand, Pointer stackTop) internal view returns (Pointer) {\n        uint256 key;\n        assembly (\"memory-safe\") {\n            key := mload(stackTop)\n        }\n        (uint256 exists, MemoryKVVal value) = state.stateKV.get(MemoryKVKey.wrap(key));\n\n        // Cache MISS, get from external store.\n        if (exists == 0) {\n            uint256 storeValue = state.store.get(state.namespace, key);\n\n            // Push fetched value to memory to make subsequent lookups on the\n            // same key find a cache HIT.\n            state.stateKV = state.stateKV.set(MemoryKVKey.wrap(key), MemoryKVVal.wrap(storeValue));\n\n            assembly (\"memory-safe\") {\n                mstore(stackTop, storeValue)\n            }\n        }\n        // Cache HIT.\n        else {\n            assembly (\"memory-safe\") {\n                mstore(stackTop, value)\n            }\n        }\n\n        return stackTop;\n    }\n\n    function referenceFn(InterpreterStateNP memory state, Operand, uint256[] memory inputs)\n        internal\n        view\n        returns (uint256[] memory)\n    {\n        uint256 key = inputs[0];\n        (uint256 exists, MemoryKVVal value) = state.stateKV.get(MemoryKVKey.wrap(key));\n        uint256[] memory outputs = new uint256[](1);\n        // Cache MISS, get from external store.\n        if (exists == 0) {\n            uint256 storeValue = state.store.get(state.namespace, key);\n\n            // Push fetched value to memory to make subsequent lookups on the\n            // same key find a cache HIT.\n            state.stateKV = state.stateKV.set(MemoryKVKey.wrap(key), MemoryKVVal.wrap(storeValue));\n\n            outputs[0] = storeValue;\n        }\n        // Cache HIT.\n        else {\n            outputs[0] = MemoryKVVal.unwrap(value);\n        }\n\n        return outputs;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/store/LibOpSetNP.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {MemoryKV, MemoryKVKey, MemoryKVVal, LibMemoryKV} from \"rain.lib.memkv/lib/LibMemoryKV.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\n\n/// @title LibOpSetNP\n/// @notice Opcode for recording k/v state changes to be set in storage.\nlibrary LibOpSetNP {\n    using LibMemoryKV for MemoryKV;\n\n    function integrity(IntegrityCheckStateNP memory, Operand) internal pure returns (uint256, uint256) {\n        // Always 2 inputs. The key and the value. `hash()` is recommended to\n        // build compound keys.\n        return (2, 0);\n    }\n\n    function run(InterpreterStateNP memory state, Operand, Pointer stackTop) internal pure returns (Pointer) {\n        unchecked {\n            uint256 key;\n            uint256 value;\n            assembly {\n                key := mload(stackTop)\n                value := mload(add(stackTop, 0x20))\n                stackTop := add(stackTop, 0x40)\n            }\n\n            state.stateKV = state.stateKV.set(MemoryKVKey.wrap(key), MemoryKVVal.wrap(value));\n            return stackTop;\n        }\n    }\n\n    function referenceFn(InterpreterStateNP memory state, Operand, uint256[] memory inputs)\n        internal\n        pure\n        returns (uint256[] memory)\n    {\n        uint256 key = inputs[0];\n        uint256 value = inputs[1];\n        state.stateKV = state.stateKV.set(MemoryKVKey.wrap(key), MemoryKVVal.wrap(value));\n        return new uint256[](0);\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/uniswap/LibOpUniswapV2AmountIn.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\nimport {LibUniswapV2} from \"../../uniswap/LibUniswapV2.sol\";\n\n/// @title LibOpUniswapV2AmountIn\n/// @notice Opcode to calculate the amount in for a Uniswap V2 pair.\nlibrary LibOpUniswapV2AmountIn {\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        unchecked {\n            // Outputs is 1 if we don't want the timestamp (operand 0) or 2 if we\n            // do (operand 1).\n            uint256 outputs = 1 + (Operand.unwrap(operand) & 1);\n            return (4, outputs);\n        }\n    }\n\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal view returns (Pointer) {\n        uint256 factory;\n        uint256 amountOut;\n        uint256 tokenIn;\n        uint256 tokenOut;\n        assembly (\"memory-safe\") {\n            factory := mload(stackTop)\n            amountOut := mload(add(stackTop, 0x20))\n            tokenIn := mload(add(stackTop, 0x40))\n            tokenOut := mload(add(stackTop, 0x60))\n            stackTop := add(stackTop, add(0x40, mul(0x20, iszero(and(operand, 1)))))\n        }\n        (uint256 amountIn, uint256 reserveTimestamp) = LibUniswapV2.getAmountInByTokenWithTime(\n            address(uint160(factory)), address(uint160(tokenIn)), address(uint160(tokenOut)), amountOut\n        );\n\n        assembly (\"memory-safe\") {\n            mstore(stackTop, amountIn)\n            if and(operand, 1) { mstore(add(stackTop, 0x20), reserveTimestamp) }\n        }\n        return stackTop;\n    }\n\n    function referenceFn(InterpreterStateNP memory, Operand operand, uint256[] memory inputs)\n        internal\n        view\n        returns (uint256[] memory outputs)\n    {\n        uint256 factory = inputs[0];\n        uint256 amountOut = inputs[1];\n        uint256 tokenIn = inputs[2];\n        uint256 tokenOut = inputs[3];\n        (uint256 amountIn, uint256 reserveTimestamp) = LibUniswapV2.getAmountInByTokenWithTime(\n            address(uint160(factory)), address(uint160(tokenIn)), address(uint160(tokenOut)), amountOut\n        );\n        outputs = new uint256[](1 + (Operand.unwrap(operand) & 1));\n        outputs[0] = amountIn;\n        if (Operand.unwrap(operand) & 1 == 1) outputs[1] = reserveTimestamp;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/op/uniswap/LibOpUniswapV2AmountOut.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {LibUniswapV2} from \"../../uniswap/LibUniswapV2.sol\";\nimport {IntegrityCheckStateNP} from \"../../integrity/LibIntegrityCheckNP.sol\";\nimport {Operand} from \"../../../interface/IInterpreterV1.sol\";\nimport {InterpreterStateNP} from \"../../state/LibInterpreterStateNP.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\n\n/// @title LibOpUniswapV2AmountOut\n/// @notice Opcode to calculate the amount out for a Uniswap V2 pair.\nlibrary LibOpUniswapV2AmountOut {\n    function integrity(IntegrityCheckStateNP memory, Operand operand) internal pure returns (uint256, uint256) {\n        unchecked {\n            // Outputs is 1 if we don't want the timestamp (operand 0) or 2 if we\n            // do (operand 1).\n            uint256 outputs = 1 + (Operand.unwrap(operand) & 1);\n            return (4, outputs);\n        }\n    }\n\n    function run(InterpreterStateNP memory, Operand operand, Pointer stackTop) internal view returns (Pointer) {\n        uint256 factory;\n        uint256 amountIn;\n        uint256 tokenIn;\n        uint256 tokenOut;\n        assembly (\"memory-safe\") {\n            factory := mload(stackTop)\n            amountIn := mload(add(stackTop, 0x20))\n            tokenIn := mload(add(stackTop, 0x40))\n            tokenOut := mload(add(stackTop, 0x60))\n            stackTop := add(stackTop, add(0x40, mul(0x20, iszero(and(operand, 1)))))\n        }\n        (uint256 amountOut, uint256 reserveTimestamp) = LibUniswapV2.getAmountOutByTokenWithTime(\n            address(uint160(factory)), address(uint160(tokenIn)), address(uint160(tokenOut)), amountIn\n        );\n\n        assembly (\"memory-safe\") {\n            mstore(stackTop, amountOut)\n            if and(operand, 1) { mstore(add(stackTop, 0x20), reserveTimestamp) }\n        }\n        return stackTop;\n    }\n\n    function referenceFn(InterpreterStateNP memory, Operand operand, uint256[] memory inputs)\n        internal\n        view\n        returns (uint256[] memory outputs)\n    {\n        uint256 factory = inputs[0];\n        uint256 amountIn = inputs[1];\n        uint256 tokenIn = inputs[2];\n        uint256 tokenOut = inputs[3];\n        (uint256 amountOut, uint256 reserveTimestamp) = LibUniswapV2.getAmountOutByTokenWithTime(\n            address(uint160(factory)), address(uint160(tokenIn)), address(uint160(tokenOut)), amountIn\n        );\n        outputs = new uint256[](1 + (Operand.unwrap(operand) & 1));\n        outputs[0] = amountOut;\n        if (Operand.unwrap(operand) & 1 == 1) outputs[1] = reserveTimestamp;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/rain.solmem/src/lib/LibMemory.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nlibrary LibMemory {\n    /// Returns true if the free memory pointer is pointing at a multiple of 32\n    /// bytes, false otherwise. If all memory allocations are handled by Solidity\n    /// then this will always be true, but assembly blocks can violate this, so\n    /// this is a useful tool to test compliance of a custom assembly block with\n    /// the solidity allocator.\n    /// @return isAligned true if the memory is currently aligned to 32 bytes.\n    function memoryIsAligned() internal pure returns (bool isAligned) {\n        assembly (\"memory-safe\") {\n            isAligned := iszero(mod(mload(0x40), 0x20))\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/interface/IInterpreterStoreV1.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"./IInterpreterV1.sol\";\n\n/// A fully qualified namespace includes the interpreter's own namespacing logic\n/// IN ADDITION to the calling contract's requested `StateNamespace`. Typically\n/// this involves hashing the `msg.sender` into the `StateNamespace` so that each\n/// caller operates within its own disjoint state universe. Intepreters MUST NOT\n/// allow either the caller nor any expression/word to modify this directly on\n/// pain of potential key collisions on writes to the interpreter's own storage.\ntype FullyQualifiedNamespace is uint256;\n\nIInterpreterStoreV1 constant NO_STORE = IInterpreterStoreV1(address(0));\n\n/// @title IInterpreterStoreV1\n/// @notice Tracks state changes on behalf of an interpreter. A single store can\n/// handle state changes for many calling contracts, many interpreters and many\n/// expressions. The store is responsible for ensuring that applying these state\n/// changes is safe from key collisions with calls to `set` from different\n/// `msg.sender` callers. I.e. it MUST NOT be possible for a caller to modify the\n/// state changes associated with some other caller.\n///\n/// The store defines the shape of its own state changes, which is opaque to the\n/// calling contract. For example, some store may treat the list of state changes\n/// as a pairwise key/value set, and some other store may treat it as a literal\n/// list to be stored as-is.\n///\n/// Each interpreter decides for itself which store to use based on the\n/// compatibility of its own opcodes.\n///\n/// The store MUST assume the state changes have been corrupted by the calling\n/// contract due to bugs or malicious intent, and enforce state isolation between\n/// callers despite arbitrarily invalid state changes. The store MUST revert if\n/// it can detect invalid state changes, such as a key/value list having an odd\n/// number of items, but this MAY NOT be possible if the corruption is\n/// undetectable.\ninterface IInterpreterStoreV1 {\n    /// Mutates the interpreter store in bulk. The bulk values are provided in\n    /// the form of a `uint256[]` which can be treated e.g. as pairwise keys and\n    /// values to be stored in a Solidity mapping. The `IInterpreterStoreV1`\n    /// defines the meaning of the `uint256[]` for its own storage logic.\n    ///\n    /// @param namespace The unqualified namespace for the set that MUST be\n    /// fully qualified by the `IInterpreterStoreV1` to prevent key collisions\n    /// between callers. The fully qualified namespace forms a compound key with\n    /// the keys for each value to set.\n    /// @param kvs The list of changes to apply to the store's internal state.\n    function set(StateNamespace namespace, uint256[] calldata kvs) external;\n\n    /// Given a fully qualified namespace and key, return the associated value.\n    /// Ostensibly the interpreter can use this to implement opcodes that read\n    /// previously set values. The interpreter MUST apply the same qualification\n    /// logic as the store that it uses to guarantee consistent round tripping of\n    /// data and prevent malicious behaviours. Technically also allows onchain\n    /// reads of any set value from any contract, not just interpreters, but in\n    /// this case readers MUST be aware and handle inconsistencies between get\n    /// and set while the state changes are still in memory in the calling\n    /// context and haven't yet been persisted to the store.\n    ///\n    /// `IInterpreterStoreV1` uses the same fallback behaviour for unset keys as\n    /// Solidity. Specifically, any UNSET VALUES SILENTLY FALLBACK TO `0`.\n    /// @param namespace The fully qualified namespace to get a single value for.\n    /// @param key The key to get the value for within the namespace.\n    /// @return The value OR ZERO IF NOT SET.\n    function get(FullyQualifiedNamespace namespace, uint256 key) external view returns (uint256);\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/bitwise/LibCtPop.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// @dev 010101... for ctpop\nuint256 constant CTPOP_M1 = 0x5555555555555555555555555555555555555555555555555555555555555555;\n/// @dev 00110011.. for ctpop\nuint256 constant CTPOP_M2 = 0x3333333333333333333333333333333333333333333333333333333333333333;\n/// @dev 4 bits alternating for ctpop\nuint256 constant CTPOP_M4 = 0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F;\n/// @dev 8 bits alternating for ctpop\nuint256 constant CTPOP_M8 = 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF;\n/// @dev 16 bits alternating for ctpop\nuint256 constant CTPOP_M16 = 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF;\n/// @dev 32 bits alternating for ctpop\nuint256 constant CTPOP_M32 = 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF;\n/// @dev 64 bits alternating for ctpop\nuint256 constant CTPOP_M64 = 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF;\n/// @dev 128 bits alternating for ctpop\nuint256 constant CTPOP_M128 = 0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n/// @dev 1 bytes for ctpop\nuint256 constant CTPOP_H01 = 0x0101010101010101010101010101010101010101010101010101010101010101;\n\nlibrary LibCtPop {\n    /// Optimised version of ctpop.\n    /// https://en.wikipedia.org/wiki/Hamming_weight\n    function ctpop(uint256 x) internal pure returns (uint256) {\n        // This edge case is not handled by the algorithm below.\n        if (x == type(uint256).max) {\n            return 256;\n        }\n        unchecked {\n            x -= (x >> 1) & CTPOP_M1;\n            x = (x & CTPOP_M2) + ((x >> 2) & CTPOP_M2);\n            x = (x + (x >> 4)) & CTPOP_M4;\n            x = (x * CTPOP_H01) >> 248;\n        }\n        return x;\n    }\n\n    /// This is the slowest possible implementation of ctpop. It is used to\n    /// verify the correctness of the optimized implementation in LibCtPop.\n    /// It should be obviously correct by visual inspection, referencing the\n    /// wikipedia article.\n    /// https://en.wikipedia.org/wiki/Hamming_weight\n    function ctpopSlow(uint256 x) internal pure returns (uint256) {\n        unchecked {\n            x = (x & CTPOP_M1) + ((x >> 1) & CTPOP_M1);\n            x = (x & CTPOP_M2) + ((x >> 2) & CTPOP_M2);\n            x = (x & CTPOP_M4) + ((x >> 4) & CTPOP_M4);\n            x = (x & CTPOP_M8) + ((x >> 8) & CTPOP_M8);\n            x = (x & CTPOP_M16) + ((x >> 16) & CTPOP_M16);\n            x = (x & CTPOP_M32) + ((x >> 32) & CTPOP_M32);\n            x = (x & CTPOP_M64) + ((x >> 64) & CTPOP_M64);\n            x = (x & CTPOP_M128) + ((x >> 128) & CTPOP_M128);\n        }\n        return x;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/parse/LibParseCMask.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// @dev ASCII null\nuint128 constant CMASK_NULL = uint128(1) << uint128(uint8(bytes1(\"\\x00\")));\n\n/// @dev ASCII start of heading\nuint128 constant CMASK_START_OF_HEADING = uint128(1) << uint128(uint8(bytes1(\"\\x01\")));\n\n/// @dev ASCII start of text\nuint128 constant CMASK_START_OF_TEXT = uint128(1) << uint128(uint8(bytes1(\"\\x02\")));\n\n/// @dev ASCII end of text\nuint128 constant CMASK_END_OF_TEXT = uint128(1) << uint128(uint8(bytes1(\"\\x03\")));\n\n/// @dev ASCII end of transmission\nuint128 constant CMASK_END_OF_TRANSMISSION = uint128(1) << uint128(uint8(bytes1(\"\\x04\")));\n\n/// @dev ASCII enquiry\nuint128 constant CMASK_ENQUIRY = uint128(1) << uint128(uint8(bytes1(\"\\x05\")));\n\n/// @dev ASCII acknowledge\nuint128 constant CMASK_ACKNOWLEDGE = uint128(1) << uint128(uint8(bytes1(\"\\x06\")));\n\n/// @dev ASCII bell\nuint128 constant CMASK_BELL = uint128(1) << uint128(uint8(bytes1(\"\\x07\")));\n\n/// @dev ASCII backspace\nuint128 constant CMASK_BACKSPACE = uint128(1) << uint128(uint8(bytes1(\"\\x08\")));\n\n/// @dev ASCII horizontal tab\nuint128 constant CMASK_HORIZONTAL_TAB = uint128(1) << uint128(uint8(bytes1(\"\\t\")));\n\n/// @dev ASCII line feed\nuint128 constant CMASK_LINE_FEED = uint128(1) << uint128(uint8(bytes1(\"\\n\")));\n\n/// @dev ASCII vertical tab\nuint128 constant CMASK_VERTICAL_TAB = uint128(1) << uint128(uint8(bytes1(\"\\x0B\")));\n\n/// @dev ASCII form feed\nuint128 constant CMASK_FORM_FEED = uint128(1) << uint128(uint8(bytes1(\"\\x0C\")));\n\n/// @dev ASCII carriage return\nuint128 constant CMASK_CARRIAGE_RETURN = uint128(1) << uint128(uint8(bytes1(\"\\r\")));\n\n/// @dev ASCII shift out\nuint128 constant CMASK_SHIFT_OUT = uint128(1) << uint128(uint8(bytes1(\"\\x0E\")));\n\n/// @dev ASCII shift in\nuint128 constant CMASK_SHIFT_IN = uint128(1) << uint128(uint8(bytes1(\"\\x0F\")));\n\n/// @dev ASCII data link escape\nuint128 constant CMASK_DATA_LINK_ESCAPE = uint128(1) << uint128(uint8(bytes1(\"\\x10\")));\n\n/// @dev ASCII device control 1\nuint128 constant CMASK_DEVICE_CONTROL_1 = uint128(1) << uint128(uint8(bytes1(\"\\x11\")));\n\n/// @dev ASCII device control 2\nuint128 constant CMASK_DEVICE_CONTROL_2 = uint128(1) << uint128(uint8(bytes1(\"\\x12\")));\n\n/// @dev ASCII device control 3\nuint128 constant CMASK_DEVICE_CONTROL_3 = uint128(1) << uint128(uint8(bytes1(\"\\x13\")));\n\n/// @dev ASCII device control 4\nuint128 constant CMASK_DEVICE_CONTROL_4 = uint128(1) << uint128(uint8(bytes1(\"\\x14\")));\n\n/// @dev ASCII negative acknowledge\nuint128 constant CMASK_NEGATIVE_ACKNOWLEDGE = uint128(1) << uint128(uint8(bytes1(\"\\x15\")));\n\n/// @dev ASCII synchronous idle\nuint128 constant CMASK_SYNCHRONOUS_IDLE = uint128(1) << uint128(uint8(bytes1(\"\\x16\")));\n\n/// @dev ASCII end of transmission block\nuint128 constant CMASK_END_OF_TRANSMISSION_BLOCK = uint128(1) << uint128(uint8(bytes1(\"\\x17\")));\n\n/// @dev ASCII cancel\nuint128 constant CMASK_CANCEL = uint128(1) << uint128(uint8(bytes1(\"\\x18\")));\n\n/// @dev ASCII end of medium\nuint128 constant CMASK_END_OF_MEDIUM = uint128(1) << uint128(uint8(bytes1(\"\\x19\")));\n\n/// @dev ASCII substitute\nuint128 constant CMASK_SUBSTITUTE = uint128(1) << uint128(uint8(bytes1(\"\\x1A\")));\n\n/// @dev ASCII escape\nuint128 constant CMASK_ESCAPE = uint128(1) << uint128(uint8(bytes1(\"\\x1B\")));\n\n/// @dev ASCII file separator\nuint128 constant CMASK_FILE_SEPARATOR = uint128(1) << uint128(uint8(bytes1(\"\\x1C\")));\n\n/// @dev ASCII group separator\nuint128 constant CMASK_GROUP_SEPARATOR = uint128(1) << uint128(uint8(bytes1(\"\\x1D\")));\n\n/// @dev ASCII record separator\nuint128 constant CMASK_RECORD_SEPARATOR = uint128(1) << uint128(uint8(bytes1(\"\\x1E\")));\n\n/// @dev ASCII unit separator\nuint128 constant CMASK_UNIT_SEPARATOR = uint128(1) << uint128(uint8(bytes1(\"\\x1F\")));\n\n/// @dev ASCII space\nuint128 constant CMASK_SPACE = uint128(1) << uint128(uint8(bytes1(\" \")));\n\n/// @dev ASCII !\nuint128 constant CMASK_EXCLAMATION_MARK = uint128(1) << uint128(uint8(bytes1(\"!\")));\n\n/// @dev ASCII \"\nuint128 constant CMASK_QUOTATION_MARK = uint128(1) << uint128(uint8(bytes1(\"\\\"\")));\n\n/// @dev ASCII #\nuint128 constant CMASK_NUMBER_SIGN = uint128(1) << uint128(uint8(bytes1(\"#\")));\n\n/// @dev ASCII $\nuint128 constant CMASK_DOLLAR_SIGN = uint128(1) << uint128(uint8(bytes1(\"$\")));\n\n/// @dev ASCII %\nuint128 constant CMASK_PERCENT_SIGN = uint128(1) << uint128(uint8(bytes1(\"%\")));\n\n/// @dev ASCII &\nuint128 constant CMASK_AMPERSAND = uint128(1) << uint128(uint8(bytes1(\"&\")));\n\n/// @dev ASCII '\nuint128 constant CMASK_APOSTROPHE = uint128(1) << uint128(uint8(bytes1(\"'\")));\n\n/// @dev ASCII (\nuint128 constant CMASK_LEFT_PAREN = uint128(1) << uint128(uint8(bytes1(\"(\")));\n\n/// @dev ASCII )\nuint128 constant CMASK_RIGHT_PAREN = uint128(1) << uint128(uint8(bytes1(\")\")));\n\n/// @dev ASCII *\nuint128 constant CMASK_ASTERISK = uint128(1) << uint128(uint8(bytes1(\"*\")));\n\n/// @dev ASCII +\nuint128 constant CMASK_PLUS_SIGN = uint128(1) << uint128(uint8(bytes1(\"+\")));\n\n/// @dev ASCII ,\nuint128 constant CMASK_COMMA = uint128(1) << uint128(uint8(bytes1(\",\")));\n\n/// @dev ASCII -\nuint128 constant CMASK_DASH = uint128(1) << uint128(uint8(bytes1(\"-\")));\n\n/// @dev ASCII .\nuint128 constant CMASK_FULL_STOP = uint128(1) << uint128(uint8(bytes1(\".\")));\n\n/// @dev ASCII /\nuint128 constant CMASK_SLASH = uint128(1) << uint128(uint8(bytes1(\"/\")));\n\n/// @dev ASCII 0\nuint128 constant CMASK_ZERO = uint128(1) << uint128(uint8(bytes1(\"0\")));\n\n/// @dev ASCII 1\nuint128 constant CMASK_ONE = uint128(1) << uint128(uint8(bytes1(\"1\")));\n\n/// @dev ASCII 2\nuint128 constant CMASK_TWO = uint128(1) << uint128(uint8(bytes1(\"2\")));\n\n/// @dev ASCII 3\nuint128 constant CMASK_THREE = uint128(1) << uint128(uint8(bytes1(\"3\")));\n\n/// @dev ASCII 4\nuint128 constant CMASK_FOUR = uint128(1) << uint128(uint8(bytes1(\"4\")));\n\n/// @dev ASCII 5\nuint128 constant CMASK_FIVE = uint128(1) << uint128(uint8(bytes1(\"5\")));\n\n/// @dev ASCII 6\nuint128 constant CMASK_SIX = uint128(1) << uint128(uint8(bytes1(\"6\")));\n\n/// @dev ASCII 7\nuint128 constant CMASK_SEVEN = uint128(1) << uint128(uint8(bytes1(\"7\")));\n\n/// @dev ASCII 8\nuint128 constant CMASK_EIGHT = uint128(1) << uint128(uint8(bytes1(\"8\")));\n\n/// @dev ASCII 9\nuint128 constant CMASK_NINE = uint128(1) << uint128(uint8(bytes1(\"9\")));\n\n/// @dev ASCII :\nuint128 constant CMASK_COLON = uint128(1) << uint128(uint8(bytes1(\":\")));\n\n/// @dev ASCII ;\nuint128 constant CMASK_SEMICOLON = uint128(1) << uint128(uint8(bytes1(\";\")));\n\n/// @dev ASCII <\nuint128 constant CMASK_LESS_THAN_SIGN = uint128(1) << uint128(uint8(bytes1(\"<\")));\n\n/// @dev ASCII =\nuint128 constant CMASK_EQUALS_SIGN = uint128(1) << uint128(uint8(bytes1(\"=\")));\n\n/// @dev ASCII >\nuint128 constant CMASK_GREATER_THAN_SIGN = uint128(1) << uint128(uint8(bytes1(\">\")));\n\n/// @dev ASCII ?\nuint128 constant CMASK_QUESTION_MARK = uint128(1) << uint128(uint8(bytes1(\"?\")));\n\n/// @dev ASCII @\nuint128 constant CMASK_AT_SIGN = uint128(1) << uint128(uint8(bytes1(\"@\")));\n\n/// @dev ASCII A\nuint128 constant CMASK_UPPER_A = uint128(1) << uint128(uint8(bytes1(\"A\")));\n\n/// @dev ASCII B\nuint128 constant CMASK_UPPER_B = uint128(1) << uint128(uint8(bytes1(\"B\")));\n\n/// @dev ASCII C\nuint128 constant CMASK_UPPER_C = uint128(1) << uint128(uint8(bytes1(\"C\")));\n\n/// @dev ASCII D\nuint128 constant CMASK_UPPER_D = uint128(1) << uint128(uint8(bytes1(\"D\")));\n\n/// @dev ASCII E\nuint128 constant CMASK_UPPER_E = uint128(1) << uint128(uint8(bytes1(\"E\")));\n\n/// @dev ASCII F\nuint128 constant CMASK_UPPER_F = uint128(1) << uint128(uint8(bytes1(\"F\")));\n\n/// @dev ASCII G\nuint128 constant CMASK_UPPER_G = uint128(1) << uint128(uint8(bytes1(\"G\")));\n\n/// @dev ASCII H\nuint128 constant CMASK_UPPER_H = uint128(1) << uint128(uint8(bytes1(\"H\")));\n\n/// @dev ASCII I\nuint128 constant CMASK_UPPER_I = uint128(1) << uint128(uint8(bytes1(\"I\")));\n\n/// @dev ASCII J\nuint128 constant CMASK_UPPER_J = uint128(1) << uint128(uint8(bytes1(\"J\")));\n\n/// @dev ASCII K\nuint128 constant CMASK_UPPER_K = uint128(1) << uint128(uint8(bytes1(\"K\")));\n\n/// @dev ASCII L\nuint128 constant CMASK_UPPER_L = uint128(1) << uint128(uint8(bytes1(\"L\")));\n\n/// @dev ASCII M\nuint128 constant CMASK_UPPER_M = uint128(1) << uint128(uint8(bytes1(\"M\")));\n\n/// @dev ASCII N\nuint128 constant CMASK_UPPER_N = uint128(1) << uint128(uint8(bytes1(\"N\")));\n\n/// @dev ASCII O\nuint128 constant CMASK_UPPER_O = uint128(1) << uint128(uint8(bytes1(\"O\")));\n\n/// @dev ASCII P\nuint128 constant CMASK_UPPER_P = uint128(1) << uint128(uint8(bytes1(\"P\")));\n\n/// @dev ASCII Q\nuint128 constant CMASK_UPPER_Q = uint128(1) << uint128(uint8(bytes1(\"Q\")));\n\n/// @dev ASCII R\nuint128 constant CMASK_UPPER_R = uint128(1) << uint128(uint8(bytes1(\"R\")));\n\n/// @dev ASCII S\nuint128 constant CMASK_UPPER_S = uint128(1) << uint128(uint8(bytes1(\"S\")));\n\n/// @dev ASCII T\nuint128 constant CMASK_UPPER_T = uint128(1) << uint128(uint8(bytes1(\"T\")));\n\n/// @dev ASCII U\nuint128 constant CMASK_UPPER_U = uint128(1) << uint128(uint8(bytes1(\"U\")));\n\n/// @dev ASCII V\nuint128 constant CMASK_UPPER_V = uint128(1) << uint128(uint8(bytes1(\"V\")));\n\n/// @dev ASCII W\nuint128 constant CMASK_UPPER_W = uint128(1) << uint128(uint8(bytes1(\"W\")));\n\n/// @dev ASCII X\nuint128 constant CMASK_UPPER_X = uint128(1) << uint128(uint8(bytes1(\"X\")));\n\n/// @dev ASCII Y\nuint128 constant CMASK_UPPER_Y = uint128(1) << uint128(uint8(bytes1(\"Y\")));\n\n/// @dev ASCII Z\nuint128 constant CMASK_UPPER_Z = uint128(1) << uint128(uint8(bytes1(\"Z\")));\n\n/// @dev ASCII [\nuint128 constant CMASK_LEFT_SQUARE_BRACKET = uint128(1) << uint128(uint8(bytes1(\"[\")));\n\n/// @dev ASCII \\\nuint128 constant CMASK_BACKSLASH = uint128(1) << uint128(uint8(bytes1(\"\\\\\")));\n\n/// @dev ASCII ]\nuint128 constant CMASK_RIGHT_SQUARE_BRACKET = uint128(1) << uint128(uint8(bytes1(\"]\")));\n\n/// @dev ASCII ^\nuint128 constant CMASK_CIRCUMFLEX_ACCENT = uint128(1) << uint128(uint8(bytes1(\"^\")));\n\n/// @dev ASCII _\nuint128 constant CMASK_UNDERSCORE = uint128(1) << uint128(uint8(bytes1(\"_\")));\n\n/// @dev ASCII `\nuint128 constant CMASK_GRAVE_ACCENT = uint128(1) << uint128(uint8(bytes1(\"`\")));\n\n/// @dev ASCII a\nuint128 constant CMASK_LOWER_A = uint128(1) << uint128(uint8(bytes1(\"a\")));\n\n/// @dev ASCII b\nuint128 constant CMASK_LOWER_B = uint128(1) << uint128(uint8(bytes1(\"b\")));\n\n/// @dev ASCII c\nuint128 constant CMASK_LOWER_C = uint128(1) << uint128(uint8(bytes1(\"c\")));\n\n/// @dev ASCII d\nuint128 constant CMASK_LOWER_D = uint128(1) << uint128(uint8(bytes1(\"d\")));\n\n/// @dev ASCII e\nuint128 constant CMASK_LOWER_E = uint128(1) << uint128(uint8(bytes1(\"e\")));\n\n/// @dev ASCII f\nuint128 constant CMASK_LOWER_F = uint128(1) << uint128(uint8(bytes1(\"f\")));\n\n/// @dev ASCII g\nuint128 constant CMASK_LOWER_G = uint128(1) << uint128(uint8(bytes1(\"g\")));\n\n/// @dev ASCII h\nuint128 constant CMASK_LOWER_H = uint128(1) << uint128(uint8(bytes1(\"h\")));\n\n/// @dev ASCII i\nuint128 constant CMASK_LOWER_I = uint128(1) << uint128(uint8(bytes1(\"i\")));\n\n/// @dev ASCII j\nuint128 constant CMASK_LOWER_J = uint128(1) << uint128(uint8(bytes1(\"j\")));\n\n/// @dev ASCII k\nuint128 constant CMASK_LOWER_K = uint128(1) << uint128(uint8(bytes1(\"k\")));\n\n/// @dev ASCII l\nuint128 constant CMASK_LOWER_L = uint128(1) << uint128(uint8(bytes1(\"l\")));\n\n/// @dev ASCII m\nuint128 constant CMASK_LOWER_M = uint128(1) << uint128(uint8(bytes1(\"m\")));\n\n/// @dev ASCII n\nuint128 constant CMASK_LOWER_N = uint128(1) << uint128(uint8(bytes1(\"n\")));\n\n/// @dev ASCII o\nuint128 constant CMASK_LOWER_O = uint128(1) << uint128(uint8(bytes1(\"o\")));\n\n/// @dev ASCII p\nuint128 constant CMASK_LOWER_P = uint128(1) << uint128(uint8(bytes1(\"p\")));\n\n/// @dev ASCII q\nuint128 constant CMASK_LOWER_Q = uint128(1) << uint128(uint8(bytes1(\"q\")));\n\n/// @dev ASCII r\nuint128 constant CMASK_LOWER_R = uint128(1) << uint128(uint8(bytes1(\"r\")));\n\n/// @dev ASCII s\nuint128 constant CMASK_LOWER_S = uint128(1) << uint128(uint8(bytes1(\"s\")));\n\n/// @dev ASCII t\nuint128 constant CMASK_LOWER_T = uint128(1) << uint128(uint8(bytes1(\"t\")));\n\n/// @dev ASCII u\nuint128 constant CMASK_LOWER_U = uint128(1) << uint128(uint8(bytes1(\"u\")));\n\n/// @dev ASCII v\nuint128 constant CMASK_LOWER_V = uint128(1) << uint128(uint8(bytes1(\"v\")));\n\n/// @dev ASCII w\nuint128 constant CMASK_LOWER_W = uint128(1) << uint128(uint8(bytes1(\"w\")));\n\n/// @dev ASCII x\nuint128 constant CMASK_LOWER_X = uint128(1) << uint128(uint8(bytes1(\"x\")));\n\n/// @dev ASCII y\nuint128 constant CMASK_LOWER_Y = uint128(1) << uint128(uint8(bytes1(\"y\")));\n\n/// @dev ASCII z\nuint128 constant CMASK_LOWER_Z = uint128(1) << uint128(uint8(bytes1(\"z\")));\n\n/// @dev ASCII {\nuint128 constant CMASK_LEFT_CURLY_BRACKET = uint128(1) << uint128(uint8(bytes1(\"{\")));\n\n/// @dev ASCII |\nuint128 constant CMASK_VERTICAL_BAR = uint128(1) << uint128(uint8(bytes1(\"|\")));\n\n/// @dev ASCII }\nuint128 constant CMASK_RIGHT_CURLY_BRACKET = uint128(1) << uint128(uint8(bytes1(\"}\")));\n\n/// @dev ASCII ~\nuint128 constant CMASK_TILDE = uint128(1) << uint128(uint8(bytes1(\"~\")));\n\n/// @dev ASCII delete\nuint128 constant CMASK_DELETE = uint128(1) << uint128(uint8(bytes1(\"\\x7F\")));\n\n/// @dev numeric 0-9\nuint128 constant CMASK_NUMERIC_0_9 = CMASK_ZERO | CMASK_ONE | CMASK_TWO | CMASK_THREE | CMASK_FOUR | CMASK_FIVE\n    | CMASK_SIX | CMASK_SEVEN | CMASK_EIGHT | CMASK_NINE;\n\n/// @dev e notation eE\nuint128 constant CMASK_E_NOTATION = CMASK_LOWER_E | CMASK_UPPER_E;\n\n/// @dev lower alpha a-z\nuint128 constant CMASK_LOWER_ALPHA_A_Z = CMASK_LOWER_A | CMASK_LOWER_B | CMASK_LOWER_C | CMASK_LOWER_D | CMASK_LOWER_E\n    | CMASK_LOWER_F | CMASK_LOWER_G | CMASK_LOWER_H | CMASK_LOWER_I | CMASK_LOWER_J | CMASK_LOWER_K | CMASK_LOWER_L\n    | CMASK_LOWER_M | CMASK_LOWER_N | CMASK_LOWER_O | CMASK_LOWER_P | CMASK_LOWER_Q | CMASK_LOWER_R | CMASK_LOWER_S\n    | CMASK_LOWER_T | CMASK_LOWER_U | CMASK_LOWER_V | CMASK_LOWER_W | CMASK_LOWER_X | CMASK_LOWER_Y | CMASK_LOWER_Z;\n\n/// @dev upper alpha A-Z\nuint128 constant CMASK_UPPER_ALPHA_A_Z = CMASK_UPPER_A | CMASK_UPPER_B | CMASK_UPPER_C | CMASK_UPPER_D | CMASK_UPPER_E\n    | CMASK_UPPER_F | CMASK_UPPER_G | CMASK_UPPER_H | CMASK_UPPER_I | CMASK_UPPER_J | CMASK_UPPER_K | CMASK_UPPER_L\n    | CMASK_UPPER_M | CMASK_UPPER_N | CMASK_UPPER_O | CMASK_UPPER_P | CMASK_UPPER_Q | CMASK_UPPER_R | CMASK_UPPER_S\n    | CMASK_UPPER_T | CMASK_UPPER_U | CMASK_UPPER_V | CMASK_UPPER_W | CMASK_UPPER_X | CMASK_UPPER_Y | CMASK_UPPER_Z;\n\n/// @dev lower alpha a-f (hex)\nuint128 constant CMASK_LOWER_ALPHA_A_F =\n    CMASK_LOWER_A | CMASK_LOWER_B | CMASK_LOWER_C | CMASK_LOWER_D | CMASK_LOWER_E | CMASK_LOWER_F;\n\n/// @dev upper alpha A-F (hex)\nuint128 constant CMASK_UPPER_ALPHA_A_F =\n    CMASK_UPPER_A | CMASK_UPPER_B | CMASK_UPPER_C | CMASK_UPPER_D | CMASK_UPPER_E | CMASK_UPPER_F;\n\n/// @dev hex 0-9 a-f A-F\nuint128 constant CMASK_HEX = CMASK_NUMERIC_0_9 | CMASK_LOWER_ALPHA_A_F | CMASK_UPPER_ALPHA_A_F;\n\n/// @dev Rainlang end of line is ,\nuint128 constant CMASK_EOL = CMASK_COMMA;\n\n/// @dev Rainlang LHS/RHS delimiter is :\nuint128 constant CMASK_LHS_RHS_DELIMITER = CMASK_COLON;\n\n/// @dev Rainlang end of source is ;\nuint128 constant CMASK_EOS = CMASK_SEMICOLON;\n\n/// @dev Rainlang stack head is lower alpha and underscore a-z _\nuint128 constant CMASK_LHS_STACK_HEAD = CMASK_LOWER_ALPHA_A_Z | CMASK_UNDERSCORE;\n\n/// @dev Rainlang identifier head is lower alpha a-z\nuint128 constant CMASK_IDENTIFIER_HEAD = CMASK_LOWER_ALPHA_A_Z;\nuint128 constant CMASK_RHS_WORD_HEAD = CMASK_IDENTIFIER_HEAD;\n\n/// @dev Rainlang stack/identifier tail is lower alphanumeric kebab a-z 0-9 -\nuint128 constant CMASK_IDENTIFIER_TAIL = CMASK_IDENTIFIER_HEAD | CMASK_NUMERIC_0_9 | CMASK_DASH;\nuint128 constant CMASK_LHS_STACK_TAIL = CMASK_IDENTIFIER_TAIL;\nuint128 constant CMASK_RHS_WORD_TAIL = CMASK_IDENTIFIER_TAIL;\n\n/// @dev Rainlang operand start is <\nuint128 constant CMASK_OPERAND_START = CMASK_LESS_THAN_SIGN;\n\n/// @dev Rainlang operand end is >\nuint128 constant CMASK_OPERAND_END = CMASK_GREATER_THAN_SIGN;\n\n/// @dev NOT lower alphanumeric kebab\nuint128 constant CMASK_NOT_IDENTIFIER_TAIL = ~CMASK_IDENTIFIER_TAIL;\n\n/// @dev Rainlang whitespace is \\n \\r \\t space\nuint128 constant CMASK_WHITESPACE = CMASK_LINE_FEED | CMASK_CARRIAGE_RETURN | CMASK_HORIZONTAL_TAB | CMASK_SPACE;\n\n/// @dev Rainlang stack item delimiter is whitespace\nuint128 constant CMASK_LHS_STACK_DELIMITER = CMASK_WHITESPACE;\n\n/// @dev Rainlang supports numeric literals as anything starting with 0-9\nuint128 constant CMASK_NUMERIC_LITERAL_HEAD = CMASK_NUMERIC_0_9;\n\n/// @dev Rainlang literal head\nuint128 constant CMASK_LITERAL_HEAD = CMASK_NUMERIC_LITERAL_HEAD;\n\n/// @dev Rainlang comment head is /\nuint128 constant CMASK_COMMENT_HEAD = CMASK_SLASH;\n\n/// @dev Rainlang comment starting sequence is /*\nuint256 constant COMMENT_START_SEQUENCE = uint256(uint16(bytes2(\"/*\")));\n\n/// @dev Rainlang comment ending sequence is */\nuint256 constant COMMENT_END_SEQUENCE = uint256(uint16(bytes2(\"*/\")));\n\n/// @dev Rainlang literal hexadecimal dispatch is 0x\n/// We compare the head and dispatch together to avoid a second comparison.\n/// This is safe because the head is prefiltered to be 0-9 due to the numeric\n/// literal head, therefore the only possible match is 0x (not x0).\nuint128 constant CMASK_LITERAL_HEX_DISPATCH = CMASK_ZERO | CMASK_LOWER_X;\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/parse/LibParse.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"rain.solmem/lib/LibPointer.sol\";\nimport \"rain.solmem/lib/LibMemCpy.sol\";\n\nimport \"../bitwise/LibCtPop.sol\";\nimport \"./LibParseMeta.sol\";\nimport \"./LibParseCMask.sol\";\nimport \"./LibParseLiteral.sol\";\nimport \"./LibParseOperand.sol\";\nimport \"../../interface/IInterpreterV1.sol\";\nimport \"./LibParseStackName.sol\";\n\n/// The expression does not finish with a semicolon (EOF).\nerror MissingFinalSemi(uint256 offset);\n\n/// Enountered an unexpected character on the LHS.\nerror UnexpectedLHSChar(uint256 offset);\n\n/// Encountered an unexpected character on the RHS.\nerror UnexpectedRHSChar(uint256 offset);\n\n/// More specific version of UnexpectedRHSChar where we specifically expected\n/// a left paren but got some other char.\nerror ExpectedLeftParen(uint256 offset);\n\n/// Encountered a right paren without a matching left paren.\nerror UnexpectedRightParen(uint256 offset);\n\n/// Encountered an unclosed left paren.\nerror UnclosedLeftParen(uint256 offset);\n\n/// Encountered a comment outside the interstitial space between lines.\nerror UnexpectedComment(uint256 offset);\n\n/// Encountered a comment start sequence that is malformed.\nerror MalformedCommentStart(uint256 offset);\n\n/// @dev Thrown when a stack name is duplicated. Shadowing in all forms is\n/// disallowed in Rainlang.\nerror DuplicateLHSItem(uint256 errorOffset);\n\n/// Encountered too many LHS items.\nerror ExcessLHSItems(uint256 offset);\n\n/// Encountered inputs where they can't be handled.\nerror NotAcceptingInputs(uint256 offset);\n\n/// Encountered too many RHS items.\nerror ExcessRHSItems(uint256 offset);\n\n/// Encountered a word that is longer than 32 bytes.\nerror WordSize(string word);\n\n/// Parsed a word that is not in the meta.\nerror UnknownWord(uint256 offset);\n\n/// The parser exceeded the maximum number of sources that it can build.\nerror MaxSources();\n\n/// The parser encountered a dangling source. This is a bug in the parser.\nerror DanglingSource();\n\n/// The parser moved past the end of the data.\nerror ParserOutOfBounds();\n\n/// The parser encountered a stack deeper than it can process in the memory\n/// region allocated for stack names.\nerror StackOverflow();\n\n/// The parser encountered a stack underflow.\nerror StackUnderflow();\n\n/// The parser encountered a paren group deeper than it can process in the\n/// memory region allocated for paren tracking.\nerror ParenOverflow();\n\nuint256 constant NOT_LOW_16_BIT_MASK = ~uint256(0xFFFF);\nuint256 constant ACTIVE_SOURCE_MASK = NOT_LOW_16_BIT_MASK;\n\nuint256 constant FSM_RHS_MASK = 1;\nuint256 constant FSM_YANG_MASK = 1 << 1;\nuint256 constant FSM_WORD_END_MASK = 1 << 2;\nuint256 constant FSM_ACCEPTING_INPUTS_MASK = 1 << 3;\n\n/// @dev The space between lines where comments and whitespace is allowed.\n/// The first LHS item breaks us out of the interstitial.\nuint256 constant FSM_INTERSTITIAL_MASK = 1 << 4;\n\n/// @dev If a source is active we cannot finish parsing without a semi to trigger\n/// finalisation.\nuint256 constant FSM_ACTIVE_SOURCE_MASK = 1 << 5;\n\n/// @dev fsm default state is:\n/// - LHS\n/// - yin\n/// - not word end\n/// - accepting inputs\n/// - interstitial\nuint256 constant FSM_DEFAULT = FSM_ACCEPTING_INPUTS_MASK | FSM_INTERSTITIAL_MASK;\n\nuint256 constant EMPTY_ACTIVE_SOURCE = 0x20;\n\n/// @dev The opcode that will be used in the source to represent a stack copy\n/// implied by named LHS stack items.\n/// @dev @todo support the meta defining the opcode.\nuint256 constant OPCODE_STACK = 0;\n\n/// @dev The opcode that will be used in the source to read a constant.\n/// @dev @todo support the meta defining the opcode.\nuint256 constant OPCODE_CONSTANT = 1;\n\ntype StackTracker is uint256;\n\n/// The parser is stateful. This struct keeps track of the entire state.\n/// @param activeSourcePtr The pointer to the current source being built.\n/// The active source being pointed to is:\n/// - low 16 bits: bitwise offset into the source for the next word to be\n///   written. Starts at 0x20. Once a source is no longer the active source, i.e.\n///   it is full and a member of the LL tail, the offset is replaced with a\n///   pointer to the next source (towards the head) to build a doubly linked\n///   list.\n/// - mid 16 bits: pointer to the previous active source (towards the tail). This\n///   is a linked list of sources that are built RTL and then reversed to LTR to\n///   eval.\n/// - high bits: 4 byte opcodes and operand pairs.\n/// @param sourcesBuilder A builder for the sources array. This is a 256 bit\n/// integer where each 16 bits is a literal memory pointer to a source.\n/// @param fsm The finite state machine representation of the parser.\n/// - bit 0: LHS/RHS => 0 = LHS, 1 = RHS\n/// - bit 1: yang/yin => 0 = yin, 1 = yang\n/// - bit 2: word end => 0 = not end, 1 = end\n/// - bit 3: accepting inputs => 0 = not accepting, 1 = accepting\n/// - bit 4: interstitial => 0 = not interstitial, 1 = interstitial\n/// @param topLevel0 Memory region for stack word counters. The first byte is a\n/// counter/offset into the region, which increments for every top level item\n/// parsed on the RHS. The remaining 31 bytes are the word counters for each\n/// stack item, which are incremented for every op pushed to the source. This is\n/// reset to 0 for every new source.\n/// @param topLevel1 31 additional bytes of stack words, allowing for 62 top\n/// level stack items total per source. The final byte is used to count the\n/// stack height according to the LHS for the current source. This is reset to 0\n/// for every new source.\n/// @param parenTracker0 Memory region for tracking pointers to words in the\n/// source, and counters for the number of words in each paren group. The first\n/// byte is a counter/offset into the region. The second byte is a phantom\n/// counter for the root level, the remaining 30 bytes are the paren group words.\n/// @param parenTracker1 32 additional bytes of paren group words.\n/// @param lineTracker A 32 byte memory region for tracking the current line.\n/// Will be partially reset for each line when `balanceLine` is called. Fully\n/// reset when a new source is started.\n/// Bytes from low to high:\n/// - byte 0: Lowest byte is the number of LHS items parsed. This is the low\n/// byte so that a simple ++ is a valid operation on the line tracker while\n/// parsing the LHS. This is reset to 0 for each new line.\n/// - byte 1: A snapshot of the first high byte of `topLevel0`, i.e. the offset\n/// of top level items as at the beginning of the line. This is reset to the high\n/// byte of `topLevel0` on each new line.\n/// - bytes 2+: A sequence of 2 byte pointers to before the start of each top\n/// level item, which is implictly after the end of the previous top level item.\n/// Allows us to quickly find the start of the RHS source for each top level\n/// item.\n/// @param stackNames A linked list of stack names. As the parser encounters\n/// named stack items it pushes them onto this linked list. The linked list is\n/// in FILO order, so the first item on the stack is the last item in the list.\n/// This makes it more efficient to reference more recent stack names on the RHS.\n/// @param literalBloom A bloom filter of all the literals that have been\n/// encountered so far. This is used to quickly dedupe literals.\n/// @param constantsBuilder A builder for the constants array.\n/// @param literalParsers A 256 bit integer where each 16 bits is a function\n/// pointer to a literal parser.\nstruct ParseState {\n    /// @dev START things that are referenced directly in assembly by hardcoded\n    /// offsets. E.g.\n    /// - `pushOpToSource`\n    /// - `snapshotSourceHeadToLineTracker`\n    /// - `newSource`\n    uint256 activeSourcePtr;\n    uint256 topLevel0;\n    uint256 topLevel1;\n    uint256 parenTracker0;\n    uint256 parenTracker1;\n    uint256 lineTracker;\n    /// @dev END things that are referenced directly in assembly by hardcoded\n    /// offsets.\n    uint256 sourcesBuilder;\n    uint256 fsm;\n    uint256 stackNames;\n    uint256 stackNameBloom;\n    uint256 literalBloom;\n    uint256 constantsBuilder;\n    uint256 literalParsers;\n    uint256 operandParsers;\n    StackTracker stackTracker;\n}\n\nlibrary LibStackTracker {\n    using LibStackTracker for StackTracker;\n\n    /// Pushing inputs requires special handling as the inputs need to be tallied\n    /// separately and in addition to the regular stack pushes.\n    function pushInputs(StackTracker tracker, uint256 n) internal pure returns (StackTracker) {\n        unchecked {\n            tracker = tracker.push(n);\n            uint256 inputs = (StackTracker.unwrap(tracker) >> 8) & 0xFF;\n            inputs += n;\n            return StackTracker.wrap((StackTracker.unwrap(tracker) & ~uint256(0xFF00)) | (inputs << 8));\n        }\n    }\n\n    function push(StackTracker tracker, uint256 n) internal pure returns (StackTracker) {\n        unchecked {\n            uint256 current = StackTracker.unwrap(tracker) & 0xFF;\n            uint256 inputs = (StackTracker.unwrap(tracker) >> 8) & 0xFF;\n            uint256 max = StackTracker.unwrap(tracker) >> 0x10;\n            current += n;\n            if (current > max) {\n                max = current;\n            }\n            return StackTracker.wrap(current | (inputs << 8) | (max << 0x10));\n        }\n    }\n\n    function pop(StackTracker tracker, uint256 n) internal pure returns (StackTracker) {\n        unchecked {\n            uint256 current = StackTracker.unwrap(tracker) & 0xFF;\n            if (current < n) {\n                revert StackUnderflow();\n            }\n            return StackTracker.wrap(StackTracker.unwrap(tracker) - n);\n        }\n    }\n}\n\nlibrary LibParseState {\n    using LibParseState for ParseState;\n    using LibStackTracker for StackTracker;\n\n    function resetSource(ParseState memory state) internal pure {\n        uint256 activeSourcePtr;\n        uint256 emptyActiveSource = EMPTY_ACTIVE_SOURCE;\n        assembly (\"memory-safe\") {\n            activeSourcePtr := mload(0x40)\n            mstore(activeSourcePtr, emptyActiveSource)\n            mstore(0x40, add(activeSourcePtr, 0x20))\n        }\n        state.activeSourcePtr = activeSourcePtr;\n        state.topLevel0 = 0;\n        state.topLevel1 = 0;\n        state.parenTracker0 = 0;\n        state.parenTracker1 = 0;\n        state.lineTracker = 0;\n        state.stackNames = 0;\n        state.stackNameBloom = 0;\n        state.stackTracker = StackTracker.wrap(0);\n    }\n\n    function newState() internal pure returns (ParseState memory) {\n        ParseState memory state = ParseState(\n            // activeSource\n            // (will be built in `newActiveSource`)\n            0,\n            // topLevel0\n            0,\n            // topLevel1\n            0,\n            // parenTracker0\n            0,\n            // parenTracker1\n            0,\n            // lineTracker\n            // (will be built in `newActiveSource`)\n            0,\n            // sourcesBuilder\n            0,\n            // fsm\n            FSM_DEFAULT,\n            // stackNames\n            0,\n            // stackNameBloom\n            0,\n            // literalBloom\n            0,\n            // constantsBuilder\n            0,\n            // literalParsers\n            LibParseLiteral.buildLiteralParsers(),\n            // operandParsers\n            LibParseOperand.buildOperandParsers(),\n            // stackTracker\n            StackTracker.wrap(0)\n        );\n        state.resetSource();\n        return state;\n    }\n\n    // Find the pointer to the first opcode in the source LL. Put it in the line\n    // tracker at the appropriate offset.\n    function snapshotSourceHeadToLineTracker(ParseState memory state) internal pure {\n        assembly (\"memory-safe\") {\n            let topLevel0Pointer := add(state, 0x20)\n            let totalRHSTopLevel := byte(0, mload(topLevel0Pointer))\n            // Only do stuff if the current word counter is zero.\n            if iszero(byte(0, mload(add(topLevel0Pointer, add(totalRHSTopLevel, 1))))) {\n                let sourceHead := mload(state)\n                let byteOffset := div(and(mload(sourceHead), 0xFFFF), 8)\n                sourceHead := add(sourceHead, sub(0x20, byteOffset))\n\n                let lineTracker := mload(add(state, 0xa0))\n                let lineRHSTopLevel := sub(totalRHSTopLevel, byte(30, lineTracker))\n                let offset := mul(0x10, add(lineRHSTopLevel, 1))\n                lineTracker := or(lineTracker, shl(offset, sourceHead))\n                mstore(add(state, 0xa0), lineTracker)\n            }\n        }\n    }\n\n    function endLine(ParseState memory state, bytes memory data, uint256 cursor) internal pure {\n        unchecked {\n            {\n                uint256 parenOffset;\n                assembly (\"memory-safe\") {\n                    parenOffset := byte(0, mload(add(state, 0x60)))\n                }\n                if (parenOffset > 0) {\n                    revert UnclosedLeftParen(LibParse.parseErrorOffset(data, cursor));\n                }\n            }\n\n            // This will snapshot the current head of the source, which will be\n            // the start of where we want to read for the final line RHS item,\n            // if it exists.\n            state.snapshotSourceHeadToLineTracker();\n\n            // Preserve the accepting inputs flag but set\n            // everything else back to defaults. Also set that\n            // there is an active source.\n            state.fsm = (FSM_DEFAULT & ~FSM_ACCEPTING_INPUTS_MASK) | (state.fsm & FSM_ACCEPTING_INPUTS_MASK)\n                | FSM_ACTIVE_SOURCE_MASK;\n\n            uint256 lineLHSItems = state.lineTracker & 0xFF;\n            // Total number of RHS at top level is the top byte of topLevel0.\n            uint256 totalRHSTopLevel = state.topLevel0 >> 0xf8;\n            // Snapshot for RHS from start of line is second low byte of\n            // lineTracker.\n            uint256 lineRHSTopLevel = totalRHSTopLevel - ((state.lineTracker >> 8) & 0xFF);\n\n            // If:\n            // - we are accepting inputs\n            // - the RHS on this line is empty\n            // Then we treat the LHS items as inputs to the source. This means that\n            // we need to move the RHS offset to the end of the LHS items. There MAY\n            // be 0 LHS items, e.g. if the entire source is empty. This can only\n            // happen at the start of the source, as any RHS item immediately flips\n            // the FSM to not accepting inputs.\n            if (lineRHSTopLevel == 0) {\n                if (state.fsm & FSM_ACCEPTING_INPUTS_MASK == 0) {\n                    revert NotAcceptingInputs(LibParse.parseErrorOffset(data, cursor));\n                } else {\n                    // As there are no RHS opcodes yet we can simply set topLevel0 directly.\n                    // This is the only case where we defer to the LHS to tell\n                    // us how many top level items there are.\n                    totalRHSTopLevel += lineLHSItems;\n                    state.topLevel0 = totalRHSTopLevel << 0xf8;\n\n                    // Push the inputs onto the stack tracker.\n                    state.stackTracker = state.stackTracker.pushInputs(lineLHSItems);\n                }\n            }\n            // If:\n            // - there are multiple RHS items on this line\n            // Then there must be the same number of LHS items. Multi or zero output\n            // RHS top level items are NOT supported unless they are the only RHS\n            // item on that line.\n            else if (lineRHSTopLevel > 1) {\n                if (lineLHSItems < lineRHSTopLevel) {\n                    revert ExcessRHSItems(LibParse.parseErrorOffset(data, cursor));\n                } else if (lineLHSItems > lineRHSTopLevel) {\n                    revert ExcessLHSItems(LibParse.parseErrorOffset(data, cursor));\n                }\n            }\n\n            // Follow pointers to the start of the RHS item.\n            uint256 topLevelOffset = 1 + totalRHSTopLevel - lineRHSTopLevel;\n            uint256 end = (0x10 * lineRHSTopLevel) + 0x20;\n            for (uint256 offset = 0x20; offset < end; offset += 0x10) {\n                uint256 itemSourceHead = (state.lineTracker >> offset) & 0xFFFF;\n                uint256 opsDepth;\n                assembly (\"memory-safe\") {\n                    opsDepth := byte(0, mload(add(state, add(0x20, topLevelOffset))))\n                }\n                for (uint256 i = 1; i <= opsDepth; i++) {\n                    {\n                        // We've hit the end of a LL item so have to jump towards the\n                        // tail to keep going.\n                        if (itemSourceHead % 0x20 == 0x1c) {\n                            assembly (\"memory-safe\") {\n                                itemSourceHead := shr(0xf0, mload(itemSourceHead))\n                            }\n                        }\n                        uint256 opInputs;\n                        assembly (\"memory-safe\") {\n                            opInputs := byte(1, mload(itemSourceHead))\n                        }\n                        state.stackTracker = state.stackTracker.pop(opInputs);\n                        // Nested multi or zero output RHS items are NOT\n                        // supported. If the top level RHS item is the ONLY RHS\n                        // item on the line then it MAY have multiple or zero\n                        // outputs. In this case we defer to the LHS to tell us\n                        // how many outputs there are. If the LHS is wrong then\n                        // later integrity checks will need to flag it.\n                        state.stackTracker =\n                            state.stackTracker.push(i == opsDepth && lineRHSTopLevel == 1 ? lineLHSItems : 1);\n                    }\n                    itemSourceHead += 4;\n                }\n                topLevelOffset++;\n            }\n\n            state.lineTracker = totalRHSTopLevel << 8;\n        }\n    }\n\n    /// We potentially just closed out some group of arbitrarily nested parens\n    /// OR a lone literal value at the top level. IF we are at the top level we\n    /// move the immutable stack highwater mark forward 1 item, which moves the\n    /// RHS offset forward 1 byte to start a new word counter.\n    function highwater(ParseState memory state) internal pure {\n        uint256 parenOffset;\n        assembly (\"memory-safe\") {\n            parenOffset := byte(0, mload(add(state, 0x60)))\n        }\n        if (parenOffset == 0) {\n            uint256 newStackRHSOffset;\n            assembly (\"memory-safe\") {\n                let stackRHSOffsetPtr := add(state, 0x20)\n                newStackRHSOffset := add(byte(0, mload(stackRHSOffsetPtr)), 1)\n                mstore8(stackRHSOffsetPtr, newStackRHSOffset)\n            }\n            if (newStackRHSOffset == 0x3f) {\n                revert StackOverflow();\n            }\n        }\n    }\n\n    function pushLiteral(ParseState memory state, bytes memory data, uint256 cursor) internal pure returns (uint256) {\n        unchecked {\n            (\n                function(bytes memory, uint256, uint256) pure returns (uint256) parser,\n                uint256 innerStart,\n                uint256 innerEnd,\n                uint256 outerEnd\n            ) = LibParseLiteral.boundLiteral(state.literalParsers, data, cursor);\n            uint256 fingerprint;\n            uint256 fingerprintBloom;\n            assembly (\"memory-safe\") {\n                fingerprint := and(keccak256(cursor, sub(outerEnd, cursor)), not(0xFFFF))\n                //slither-disable-next-line incorrect-shift\n                fingerprintBloom := shl(byte(0, fingerprint), 1)\n            }\n\n            // Whether the literal is a duplicate.\n            bool exists = false;\n\n            // The index of the literal in the linked list of literals. This is\n            // starting from the top of the linked list, so the final index is\n            // the height of the linked list minus this value.\n            uint256 t = 1;\n\n            // If the literal is in the bloom filter, then it MAY be a duplicate.\n            // Try to find the literal in the linked list of literals using the\n            // full fingerprint for better collision resistance than the bloom.\n            //\n            // If the literal is NOT in the bloom filter, then it is definitely\n            // NOT a duplicate, so avoid traversing the linked list.\n            //\n            // Worst case is a false positive in the bloom filter, which means\n            // we traverse the linked list and find no match. This is O(1) for\n            // the bloom filter and O(n) for the linked list traversal, then\n            // O(m) for the per-char literal parsing. The bloom filter is\n            // 256 bits, so the chance of there being at least one false positive\n            // over 10 literals is ~15% due to the birthday paradox.\n            if (state.literalBloom & fingerprintBloom != 0) {\n                uint256 tailPtr = state.constantsBuilder >> 0x10;\n                while (tailPtr != 0) {\n                    uint256 tailKey;\n                    assembly (\"memory-safe\") {\n                        tailKey := mload(tailPtr)\n                    }\n                    // If the fingerprint  matches, then the literal IS a duplicate,\n                    // with 240 bits of collision resistance. The value sits alongside\n                    // the key in memory.\n                    if (fingerprint == (tailKey & ~uint256(0xFFFF))) {\n                        exists = true;\n                        break;\n                    }\n\n                    assembly (\"memory-safe\") {\n                        // Tail pointer is the low 16 bits of the key.\n                        tailPtr := and(mload(tailPtr), 0xFFFF)\n                    }\n                    t++;\n                }\n            }\n\n            // Push the literal opcode to the source.\n            // The index is either the height of the constants, if the literal\n            // is NOT a duplicate, or the height minus the index of the\n            // duplicate. This is because the final constants array is built\n            // 0 indexed from the bottom of the linked list to the top.\n            {\n                uint256 constantsHeight = state.constantsBuilder & 0xFFFF;\n                state.pushOpToSource(OPCODE_CONSTANT, Operand.wrap(exists ? constantsHeight - t : constantsHeight));\n            }\n\n            // If the literal is not a duplicate, then we need to add it to the\n            // linked list of literals so that `t` can point to it, and we can\n            // build the constants array from the values in the linked list\n            // later.\n            if (!exists) {\n                uint256 ptr;\n                assembly (\"memory-safe\") {\n                    // Allocate two words.\n                    ptr := mload(0x40)\n                    mstore(0x40, add(ptr, 0x40))\n                }\n                // First word is the key.\n                {\n                    // tail key is the fingerprint with the low 16 bits set to\n                    // the pointer to the next item in the linked list. If there\n                    // is no next item then the pointer is 0.\n                    uint256 tailKey = state.constantsBuilder >> 0x10 | fingerprint;\n                    assembly (\"memory-safe\") {\n                        mstore(ptr, tailKey)\n                    }\n                }\n                // Second word is the value.\n                {\n                    uint256 tailValue = parser(data, innerStart, innerEnd);\n\n                    assembly (\"memory-safe\") {\n                        // Second word is the value\n                        mstore(add(ptr, 0x20), tailValue)\n                    }\n                }\n\n                state.constantsBuilder = ((state.constantsBuilder & 0xFFFF) + 1) | (ptr << 0x10);\n                state.literalBloom |= fingerprintBloom;\n            }\n\n            return outerEnd;\n        }\n    }\n\n    function pushOpToSource(ParseState memory state, uint256 opcode, Operand operand) internal pure {\n        unchecked {\n            // This might be a top level item so try to snapshot its pointer to\n            // the line tracker before writing the stack counter.\n            state.snapshotSourceHeadToLineTracker();\n\n            // As soon as we push an op to source we can no longer accept inputs.\n            state.fsm &= ~FSM_ACCEPTING_INPUTS_MASK;\n            // We also have an active source;\n            state.fsm |= FSM_ACTIVE_SOURCE_MASK;\n\n            // Increment the top level stack counter for the current top level\n            // word. MAY be setting 0 to 1 if this is the top level.\n            assembly (\"memory-safe\") {\n                // Hardcoded offset into the state struct.\n                let counterOffset := add(state, 0x20)\n                let counterPointer := add(counterOffset, add(byte(0, mload(counterOffset)), 1))\n                // Increment the counter.\n                mstore8(counterPointer, add(byte(0, mload(counterPointer)), 1))\n            }\n\n            uint256 activeSource;\n            uint256 offset;\n            assembly (\"memory-safe\") {\n                let activeSourcePointer := mload(state)\n                activeSource := mload(activeSourcePointer)\n                // The low 16 bits of the active source is the current offset.\n                offset := and(activeSource, 0xFFFF)\n\n                // The offset is in bits so for a byte pointer we need to divide\n                // by 8, then add 4 to move to the operand low byte.\n                let inputsBytePointer := sub(add(activeSourcePointer, 0x20), add(div(offset, 8), 4))\n\n                // Increment the paren input counter. The input counter is for the paren\n                // group that is currently being built. This means the counter is for\n                // the paren group that is one level above the current paren offset.\n                // Assumes that every word has exactly 1 output, therefore the input\n                // counter always increases by 1.\n                // Hardcoded offset into the state struct.\n                let inputCounterPos := add(state, 0x60)\n                inputCounterPos :=\n                    add(\n                        add(\n                            inputCounterPos,\n                            // the offset\n                            byte(0, mload(inputCounterPos))\n                        ),\n                        // +2 for the reserved bytes -1 to move back to the counter\n                        // for the previous paren group.\n                        1\n                    )\n                // Increment the parent counter.\n                mstore8(inputCounterPos, add(byte(0, mload(inputCounterPos)), 1))\n                // Zero out the current counter.\n                mstore8(add(inputCounterPos, 3), 0)\n\n                // Write the operand low byte pointer into the paren tracker.\n                // Move 3 bytes after the input counter pos, then shift down 32\n                // bytes to accomodate the full mload.\n                let parenTrackerPointer := sub(inputCounterPos, 29)\n                mstore(parenTrackerPointer, or(and(mload(parenTrackerPointer), not(0xFFFF)), inputsBytePointer))\n            }\n\n            // We write sources RTL so they can run LTR.\n            activeSource =\n            // increment offset. We have 16 bits allocated to the offset and stop\n            // processing at 0x100 so this never overflows into the actual source\n            // data.\n            activeSource + 0x20\n            // include the operand. The operand is assumed to be 16 bits, so we shift\n            // it into the correct position.\n            | Operand.unwrap(operand) << offset\n            // include new op. The opcode is assumed to be 8 bits, so we shift it\n            // into the correct position, beyond the operand.\n            | opcode << (offset + 0x18);\n            assembly (\"memory-safe\") {\n                mstore(mload(state), activeSource)\n            }\n\n            // We have filled the current source slot. Need to create a new active\n            // source and fulfill the doubly linked list.\n            if (offset == 0xe0) {\n                // Pointer to a newly allocated active source.\n                uint256 newTailPtr;\n                // Pointer to the old head of the LL tail.\n                uint256 oldTailPtr;\n                uint256 emptyActiveSource = EMPTY_ACTIVE_SOURCE;\n                assembly (\"memory-safe\") {\n                    oldTailPtr := mload(state)\n\n                    // Build the new tail head.\n                    newTailPtr := mload(0x40)\n                    mstore(state, newTailPtr)\n                    mstore(newTailPtr, or(emptyActiveSource, shl(0x10, oldTailPtr)))\n                    mstore(0x40, add(newTailPtr, 0x20))\n\n                    // The old tail head must now point back to the new tail head.\n                    mstore(oldTailPtr, or(and(mload(oldTailPtr), not(0xFFFF)), newTailPtr))\n                }\n            }\n        }\n    }\n\n    function endSource(ParseState memory state) internal pure {\n        uint256 sourcesBuilder = state.sourcesBuilder;\n        uint256 offset = sourcesBuilder >> 0xf0;\n\n        // End is the number of top level words in the source, which is the\n        // byte offset index + 1.\n        uint256 end;\n        assembly (\"memory-safe\") {\n            end := add(byte(0, mload(add(state, 0x20))), 1)\n        }\n\n        if (offset == 0xf0) {\n            revert MaxSources();\n        }\n        // Follow the word counters to build the source with the correct\n        // combination of LTR and RTL words. The stack needs to be built\n        // LTR at the top level, so that as the evaluation proceeds LTR it\n        // can reference previous items in subsequent items. However, the\n        // stack is built RTL within each item, so that nested parens are\n        // evaluated correctly similar to reverse polish notation.\n        else {\n            uint256 source;\n            StackTracker stackTracker = state.stackTracker;\n            assembly (\"memory-safe\") {\n                // find the end of the LL tail.\n                let cursor := mload(state)\n\n                let tailPointer := and(shr(0x10, mload(cursor)), 0xFFFF)\n                for {} iszero(iszero(tailPointer)) {} {\n                    cursor := tailPointer\n                    tailPointer := and(shr(0x10, mload(cursor)), 0xFFFF)\n                }\n\n                // Move cursor to the end of the end of the LL tail item.\n                // This is 4 bytes from the end of the EVM word, to compensate\n                // for the offset and pointer positions.\n                tailPointer := cursor\n                cursor := add(cursor, 0x1C)\n                // leave space for the source prefix in the bytecode output.\n                let length := 4\n                source := mload(0x40)\n                // Move over the source 32 byte length and the 4 byte prefix.\n                let writeCursor := add(source, 0x20)\n                writeCursor := add(writeCursor, 4)\n\n                let counterCursor := add(state, 0x21)\n                for {\n                    let i := 0\n                    let wordsTotal := byte(0, mload(counterCursor))\n                    let wordsRemaining := wordsTotal\n                } lt(i, end) {\n                    i := add(i, 1)\n                    counterCursor := add(counterCursor, 1)\n                    wordsTotal := byte(0, mload(counterCursor))\n                    wordsRemaining := wordsTotal\n                } {\n                    length := add(length, mul(wordsTotal, 4))\n                    {\n                        // 4 bytes per source word.\n                        let tailItemWordsRemaining := div(sub(cursor, tailPointer), 4)\n                        // loop to the tail item that contains the start of the words\n                        // that we need to copy.\n                        for {} gt(wordsRemaining, tailItemWordsRemaining) {} {\n                            wordsRemaining := sub(wordsRemaining, tailItemWordsRemaining)\n                            tailPointer := and(mload(tailPointer), 0xFFFF)\n                            tailItemWordsRemaining := 7\n                            cursor := add(tailPointer, 0x1C)\n                        }\n                    }\n\n                    // Now the words remaining is lte the words remaining in the\n                    // tail item. Move the cursor back to the start of the words\n                    // and copy the passed over bytes to the write cursor.\n                    {\n                        let forwardTailPointer := tailPointer\n                        let size := mul(wordsRemaining, 4)\n                        cursor := sub(cursor, size)\n                        mstore(writeCursor, mload(cursor))\n                        writeCursor := add(writeCursor, size)\n\n                        // Redefine wordsRemaining to be the number of words\n                        // left to copy.\n                        wordsRemaining := sub(wordsTotal, wordsRemaining)\n                        // Move over whole tail items.\n                        for {} gt(wordsRemaining, 7) {} {\n                            wordsRemaining := sub(wordsRemaining, 7)\n                            // Follow the forward tail pointer.\n                            forwardTailPointer := and(shr(0x10, mload(forwardTailPointer)), 0xFFFF)\n                            mstore(writeCursor, mload(forwardTailPointer))\n                            writeCursor := add(writeCursor, 0x1c)\n                        }\n                        // Move over the remaining words in the tail item.\n                        if gt(wordsRemaining, 0) {\n                            forwardTailPointer := and(shr(0x10, mload(forwardTailPointer)), 0xFFFF)\n                            mstore(writeCursor, mload(forwardTailPointer))\n                            writeCursor := add(writeCursor, mul(wordsRemaining, 4))\n                        }\n                    }\n                }\n                // Store the bytes length in the source.\n                mstore(source, length)\n                // Store the opcodes length and stack tracker in the source\n                // prefix.\n                let prefixWritePointer := add(source, 4)\n                mstore(\n                    prefixWritePointer,\n                    or(\n                        and(mload(prefixWritePointer), not(0xFFFFFFFF)),\n                        or(shl(0x18, sub(div(length, 4), 1)), stackTracker)\n                    )\n                )\n\n                // Round up to the nearest 32 bytes to realign memory.\n                mstore(0x40, and(add(writeCursor, 0x1f), not(0x1f)))\n            }\n\n            //slither-disable-next-line incorrect-shift\n            state.sourcesBuilder =\n                ((offset + 0x10) << 0xf0) | (source << offset) | (sourcesBuilder & ((1 << offset) - 1));\n\n            // Reset source as we're done with this one.\n            state.fsm &= ~FSM_ACTIVE_SOURCE_MASK;\n            state.resetSource();\n        }\n    }\n\n    function buildBytecode(ParseState memory state) internal pure returns (bytes memory bytecode) {\n        unchecked {\n            uint256 sourcesBuilder = state.sourcesBuilder;\n            uint256 offsetEnd = (sourcesBuilder >> 0xf0);\n\n            // Somehow the parser state for the active source was not reset\n            // correctly, or the finalised offset is dangling. This implies that\n            // we are building the overall sources array while still trying to\n            // build one of the individual sources. This is a bug in the parser.\n            uint256 activeSource;\n            assembly (\"memory-safe\") {\n                activeSource := mload(mload(state))\n            }\n            if (activeSource != EMPTY_ACTIVE_SOURCE) {\n                revert DanglingSource();\n            }\n\n            uint256 cursor;\n            uint256 sourcesCount;\n            uint256 sourcesStart;\n            assembly (\"memory-safe\") {\n                cursor := mload(0x40)\n                bytecode := cursor\n                // Move past the bytecode length, we will write this at the end.\n                cursor := add(cursor, 0x20)\n\n                // First byte is the number of sources.\n                sourcesCount := div(offsetEnd, 0x10)\n                mstore8(cursor, sourcesCount)\n                cursor := add(cursor, 1)\n\n                let pointersCursor := cursor\n\n                // Skip past the pointer space. We'll back fill it.\n                // Divide offsetEnd to convert from a bit to a byte shift.\n                cursor := add(cursor, div(offsetEnd, 8))\n                sourcesStart := cursor\n\n                // Write total bytes length into bytecode. We do ths and handle\n                // the allocation in this same assembly block for memory safety\n                // for the compiler optimiser.\n                let sourcesLength := 0\n                let sourcePointers := 0\n                for { let offset := 0 } lt(offset, offsetEnd) { offset := add(offset, 0x10) } {\n                    let currentSourcePointer := and(shr(offset, sourcesBuilder), 0xFFFF)\n                    // add 4 byte prefix to the length of the sources, all as\n                    // bytes.\n                    sourcePointers := or(sourcePointers, shl(sub(0xf0, offset), sourcesLength))\n                    let currentSourceLength := mload(currentSourcePointer)\n\n                    // Put the reference source pointer and length into the\n                    // prefix so that we can use them to copy the actual data\n                    // into the bytecode.\n                    let tmpPrefix := shl(0xe0, or(shl(0x10, currentSourcePointer), currentSourceLength))\n                    mstore(add(sourcesStart, sourcesLength), tmpPrefix)\n                    sourcesLength := add(sourcesLength, currentSourceLength)\n                }\n                mstore(pointersCursor, or(mload(pointersCursor), sourcePointers))\n                mstore(bytecode, add(sourcesLength, sub(sub(sourcesStart, 0x20), bytecode)))\n\n                // Round up to the nearest 32 bytes past cursor to realign and\n                // allocate memory.\n                mstore(0x40, and(add(add(add(0x20, mload(bytecode)), bytecode), 0x1f), not(0x1f)))\n            }\n\n            // Loop over the sources and write them into the bytecode. Perhaps\n            // there is a more efficient way to do this in the future that won't\n            // cause each source to be written twice in memory.\n            for (uint256 i = 0; i < sourcesCount; i++) {\n                Pointer sourcePointer;\n                uint256 length;\n                Pointer targetPointer;\n                assembly (\"memory-safe\") {\n                    let relativePointer := and(mload(add(bytecode, add(3, mul(i, 2)))), 0xFFFF)\n                    targetPointer := add(sourcesStart, relativePointer)\n                    let tmpPrefix := mload(targetPointer)\n                    sourcePointer := add(0x20, shr(0xf0, tmpPrefix))\n                    length := and(shr(0xe0, tmpPrefix), 0xFFFF)\n                }\n                LibMemCpy.unsafeCopyBytesTo(sourcePointer, targetPointer, length);\n            }\n        }\n    }\n\n    function buildConstants(ParseState memory state) internal pure returns (uint256[] memory constants) {\n        uint256 constantsHeight = state.constantsBuilder & 0xFFFF;\n        uint256 tailPtr = state.constantsBuilder >> 0x10;\n\n        assembly (\"memory-safe\") {\n            let cursor := mload(0x40)\n            constants := cursor\n            mstore(cursor, constantsHeight)\n            let end := cursor\n            // Move the cursor to the end of the array. Write in reverse order\n            // of the linked list traversal so that the constants are built\n            // according to the stable indexes in the source from the linked\n            // list base.\n            cursor := add(cursor, mul(constantsHeight, 0x20))\n            // Allocate one word past the cursor. This will be just after the\n            // length if the constants array is empty. Otherwise it will be\n            // just after the last constant.\n            mstore(0x40, add(cursor, 0x20))\n            // It MUST be equivalent to say that the cursor is above the end,\n            // and that we are following tail pointers until they point to 0,\n            // and that the cursor is moving as far as the constants height.\n            // This is ensured by the fact that the constants height is only\n            // incremented when a new constant is added to the linked list.\n            for {} gt(cursor, end) {\n                // Next item in the linked list.\n                cursor := sub(cursor, 0x20)\n                // tail pointer in tail keys is the low 16 bits under the\n                // fingerprint, which is different from the tail pointer in\n                // the constants builder, where it sits above the constants\n                // height.\n                tailPtr := and(mload(tailPtr), 0xFFFF)\n            } {\n                // Store the values not the keys.\n                mstore(cursor, mload(add(tailPtr, 0x20)))\n            }\n        }\n    }\n}\n\nlibrary LibParse {\n    using LibPointer for Pointer;\n    using LibParseState for ParseState;\n    using LibParseStackName for ParseState;\n\n    function parseErrorOffset(bytes memory data, uint256 cursor) internal pure returns (uint256 offset) {\n        assembly (\"memory-safe\") {\n            offset := sub(cursor, add(data, 0x20))\n        }\n    }\n\n    function parseWord(uint256 cursor, uint256 mask) internal pure returns (uint256, bytes32) {\n        bytes32 word;\n        uint256 i = 1;\n        assembly (\"memory-safe\") {\n            // word is head + tail\n            word := mload(cursor)\n            // loop over the tail\n            //slither-disable-next-line incorrect-shift\n            for {} and(lt(i, 0x20), iszero(and(shl(byte(i, word), 1), not(mask)))) { i := add(i, 1) } {}\n            let scrub := mul(sub(0x20, i), 8)\n            word := shl(scrub, shr(scrub, word))\n            cursor := add(cursor, i)\n        }\n        if (i == 0x20) {\n            revert WordSize(string(abi.encodePacked(word)));\n        }\n        return (cursor, word);\n    }\n\n    /// Skip an unlimited number of chars until we find one that is not in the\n    /// mask.\n    function skipMask(uint256 cursor, uint256 end, uint256 mask) internal pure returns (uint256) {\n        assembly (\"memory-safe\") {\n            //slither-disable-next-line incorrect-shift\n            for {} and(lt(cursor, end), gt(and(shl(byte(0, mload(cursor)), 1), mask), 0)) { cursor := add(cursor, 1) } {}\n        }\n        return cursor;\n    }\n\n    /// The cursor currently points at the head of a comment. We need to skip\n    /// over all data until we find the end of the comment. This MAY REVERT if\n    /// the comment is malformed, e.g. if the comment doesn't start with `/*`.\n    /// @param data The source data.\n    /// @param cursor The current cursor position.\n    /// @return The new cursor position.\n    function skipComment(bytes memory data, uint256 cursor) internal pure returns (uint256) {\n        // First check the comment opening sequence is not malformed.\n        uint256 startSequence;\n        assembly (\"memory-safe\") {\n            startSequence := shr(0xf0, mload(cursor))\n        }\n        if (startSequence != COMMENT_START_SEQUENCE) {\n            revert MalformedCommentStart(parseErrorOffset(data, cursor));\n        }\n        uint256 commentEndSequenceStart = COMMENT_END_SEQUENCE >> 8;\n        uint256 commentEndSequenceEnd = COMMENT_END_SEQUENCE & 0xFF;\n        uint256 max;\n        assembly (\"memory-safe\") {\n            // Move past the start sequence.\n            cursor := add(cursor, 2)\n            max := add(data, add(mload(data), 0x20))\n\n            // Loop until we find the end sequence.\n            let done := 0\n            for {} iszero(done) {} {\n                for {} and(iszero(eq(byte(0, mload(cursor)), commentEndSequenceStart)), lt(cursor, max)) {} {\n                    cursor := add(cursor, 1)\n                }\n                // We have found the start of the end sequence. Now check the\n                // end sequence is correct.\n                cursor := add(cursor, 1)\n                // Only exit the loop if the end sequence is correct. We don't\n                // move the cursor forward unless we haven exact match on the\n                // end byte. E.g. consider the sequence `/** comment **/`.\n                if or(eq(byte(0, mload(cursor)), commentEndSequenceEnd), iszero(lt(cursor, max))) {\n                    done := 1\n                    cursor := add(cursor, 1)\n                }\n            }\n        }\n        // If the cursor is past the max we either never even started an end\n        // sequence, or we started parsing an end sequence but couldn't complete\n        // it. Either way, the comment is malformed, and the parser is OOB.\n        if (cursor > max) {\n            revert ParserOutOfBounds();\n        }\n        return cursor;\n    }\n\n    //slither-disable-next-line cyclomatic-complexity\n    function parse(bytes memory data, bytes memory meta)\n        internal\n        pure\n        returns (bytes memory bytecode, uint256[] memory)\n    {\n        unchecked {\n            ParseState memory state = LibParseState.newState();\n            if (data.length > 0) {\n                bytes32 word;\n                uint256 cursor;\n                uint256 end;\n                uint256 char;\n                assembly (\"memory-safe\") {\n                    cursor := add(data, 0x20)\n                    end := add(cursor, mload(data))\n                }\n                while (cursor < end) {\n                    assembly (\"memory-safe\") {\n                        //slither-disable-next-line incorrect-shift\n                        char := shl(byte(0, mload(cursor)), 1)\n                    }\n\n                    // LHS\n                    if (state.fsm & FSM_RHS_MASK == 0) {\n                        if (char & CMASK_LHS_STACK_HEAD > 0) {\n                            // if yang we can't start new stack item\n                            if (state.fsm & FSM_YANG_MASK > 0) {\n                                revert UnexpectedLHSChar(parseErrorOffset(data, cursor));\n                            }\n\n                            // Named stack item.\n                            if (char & CMASK_IDENTIFIER_HEAD > 0) {\n                                (cursor, word) = parseWord(cursor, CMASK_LHS_STACK_TAIL);\n                                (bool exists, uint256 index) = state.pushStackName(word);\n                                (index);\n                                // If the stack name already exists, then we\n                                // revert as shadowing is not allowed.\n                                if (exists) {\n                                    revert DuplicateLHSItem(parseErrorOffset(data, cursor));\n                                }\n                            }\n                            // Anon stack item.\n                            else {\n                                cursor = skipMask(cursor + 1, end, CMASK_LHS_STACK_TAIL);\n                            }\n                            // Bump the index regardless of whether the stack\n                            // item is named or not.\n                            state.topLevel1++;\n                            state.lineTracker++;\n\n                            // Set yang as we are now building a stack item.\n                            // We are also no longer interstitial\n                            state.fsm = (state.fsm | FSM_YANG_MASK | FSM_ACTIVE_SOURCE_MASK) & ~FSM_INTERSTITIAL_MASK;\n                        } else if (char & CMASK_WHITESPACE != 0) {\n                            cursor = skipMask(cursor + 1, end, CMASK_WHITESPACE);\n                            // Set ying as we now open to possibilities.\n                            state.fsm &= ~FSM_YANG_MASK;\n                        } else if (char & CMASK_LHS_RHS_DELIMITER != 0) {\n                            // Set RHS and yin. Move out of the interstitial if\n                            // we haven't already.\n                            state.fsm = (state.fsm | FSM_RHS_MASK | FSM_ACTIVE_SOURCE_MASK)\n                                & ~(FSM_YANG_MASK | FSM_INTERSTITIAL_MASK);\n                            cursor++;\n                        } else if (char & CMASK_COMMENT_HEAD != 0) {\n                            if (state.fsm & FSM_INTERSTITIAL_MASK == 0) {\n                                revert UnexpectedComment(parseErrorOffset(data, cursor));\n                            }\n                            cursor = skipComment(data, cursor);\n                            // Set yang for comments to force a little breathing\n                            // room between comments and the next item.\n                            state.fsm |= FSM_YANG_MASK;\n                        } else {\n                            revert UnexpectedLHSChar(parseErrorOffset(data, cursor));\n                        }\n                    }\n                    // RHS\n                    else {\n                        if (char & CMASK_RHS_WORD_HEAD > 0) {\n                            // If yang we can't start a new word.\n                            if (state.fsm & FSM_YANG_MASK > 0) {\n                                revert UnexpectedRHSChar(parseErrorOffset(data, cursor));\n                            }\n\n                            (cursor, word) = parseWord(cursor, CMASK_RHS_WORD_TAIL);\n\n                            // First check if this word is in meta.\n                            (\n                                bool exists,\n                                uint256 opcodeIndex,\n                                function(uint256, bytes memory, uint256) pure returns (uint256, Operand) operandParser\n                            ) = LibParseMeta.lookupWord(meta, state.operandParsers, word);\n                            if (exists) {\n                                Operand operand;\n                                (cursor, operand) = operandParser(state.literalParsers, data, cursor);\n                                state.pushOpToSource(opcodeIndex, operand);\n                                // This is a real word so we expect to see parens\n                                // after it.\n                                state.fsm |= FSM_WORD_END_MASK;\n                            }\n                            // Fallback to LHS items.\n                            else {\n                                (exists, opcodeIndex) = LibParseStackName.stackNameIndex(state, word);\n                                if (exists) {\n                                    state.pushOpToSource(OPCODE_STACK, Operand.wrap(opcodeIndex));\n                                    // Need to process highwater here because we\n                                    // don't have any parens to open or close.\n                                    state.highwater();\n                                } else {\n                                    revert UnknownWord(parseErrorOffset(data, cursor));\n                                }\n                            }\n\n                            state.fsm |= FSM_YANG_MASK;\n                        }\n                        // If this is the end of a word we MUST start a paren.\n                        else if (state.fsm & FSM_WORD_END_MASK > 0) {\n                            if (char & CMASK_LEFT_PAREN == 0) {\n                                revert ExpectedLeftParen(parseErrorOffset(data, cursor));\n                            }\n                            // Increase the paren depth by 1.\n                            // i.e. move the byte offset by 3\n                            // There MAY be garbage at this new offset due to\n                            // a previous paren group being deallocated. The\n                            // deallocation process writes the input counter\n                            // to zero but leaves a garbage word in place, with\n                            // the expectation that it will be overwritten by\n                            // the next paren group.\n                            uint256 newParenOffset;\n                            assembly (\"memory-safe\") {\n                                newParenOffset := add(byte(0, mload(add(state, 0x60))), 3)\n                                mstore8(add(state, 0x60), newParenOffset)\n                            }\n                            // first 2 bytes are reserved, then remaining 62\n                            // bytes are for paren groups, so the offset MUST NOT\n                            // imply writing to the 63rd byte.\n                            if (newParenOffset > 59) {\n                                revert ParenOverflow();\n                            }\n                            cursor++;\n\n                            // We've moved past the paren, so we are no longer at\n                            // the end of a word and are yin.\n                            state.fsm &= ~(FSM_WORD_END_MASK | FSM_YANG_MASK);\n                        } else if (char & CMASK_RIGHT_PAREN > 0) {\n                            uint256 parenOffset;\n                            assembly (\"memory-safe\") {\n                                parenOffset := byte(0, mload(add(state, 0x60)))\n                            }\n                            if (parenOffset == 0) {\n                                revert UnexpectedRightParen(parseErrorOffset(data, cursor));\n                            }\n                            // Decrease the paren depth by 1.\n                            // i.e. move the byte offset by -3.\n                            // This effectively deallocates the paren group, so\n                            // write the input counter out to the operand pointed\n                            // to by the pointer we deallocated.\n                            assembly (\"memory-safe\") {\n                                // State field offset.\n                                let stateOffset := add(state, 0x60)\n                                parenOffset := sub(parenOffset, 3)\n                                mstore8(stateOffset, parenOffset)\n                                mstore8(\n                                    // Add 2 for the reserved bytes to the offset\n                                    // then read top 16 bits from the pointer.\n                                    // Add 1 to sandwitch the inputs byte between\n                                    // the opcode index byte and the operand low\n                                    // bytes.\n                                    add(1, shr(0xf0, mload(add(add(stateOffset, 2), parenOffset)))),\n                                    // Store the input counter, which is 2 bytes\n                                    // after the operand write pointer.\n                                    byte(0, mload(add(add(stateOffset, 4), parenOffset)))\n                                )\n                            }\n                            state.highwater();\n                            cursor++;\n                        } else if (char & CMASK_WHITESPACE > 0) {\n                            cursor = skipMask(cursor + 1, end, CMASK_WHITESPACE);\n                            // Set yin as we now open to possibilities.\n                            state.fsm &= ~FSM_YANG_MASK;\n                        }\n                        // Handle all literals.\n                        else if (char & CMASK_LITERAL_HEAD > 0) {\n                            cursor = state.pushLiteral(data, cursor);\n                            state.highwater();\n                            // We are yang now. Need the next char to release to\n                            // yin.\n                            state.fsm |= FSM_YANG_MASK;\n                        } else if (char & CMASK_EOL > 0) {\n                            state.endLine(data, cursor);\n                            cursor++;\n                        }\n                        // End of source.\n                        else if (char & CMASK_EOS > 0) {\n                            state.endLine(data, cursor);\n                            state.endSource();\n                            cursor++;\n\n                            state.fsm = FSM_DEFAULT;\n                        }\n                        // Comments aren't allowed in the RHS but we can give a\n                        // nicer error message than the default.\n                        else if (char & CMASK_COMMENT_HEAD != 0) {\n                            revert UnexpectedComment(parseErrorOffset(data, cursor));\n                        } else {\n                            revert UnexpectedRHSChar(parseErrorOffset(data, cursor));\n                        }\n                    }\n                }\n                if (cursor != end) {\n                    revert ParserOutOfBounds();\n                }\n                if (state.fsm & FSM_ACTIVE_SOURCE_MASK != 0) {\n                    revert MissingFinalSemi(parseErrorOffset(data, cursor));\n                }\n            }\n            return (state.buildBytecode(), state.buildConstants());\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/parse/LibParseLiteral.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"./LibParseCMask.sol\";\nimport \"./LibParse.sol\";\n\n/// The parser tried to bound an unsupported literal that we have no type for.\nerror UnsupportedLiteralType(uint256 offset);\n\n/// Encountered a literal that is larger than supported.\nerror HexLiteralOverflow(uint256 offset);\n\n/// Encountered a zero length hex literal.\nerror ZeroLengthHexLiteral(uint256 offset);\n\n/// Encountered an odd sized hex literal.\nerror OddLengthHexLiteral(uint256 offset);\n\n/// Encountered a hex literal with an invalid character.\nerror MalformedHexLiteral(uint256 offset);\n\n/// Encountered a decimal literal that is larger than supported.\nerror DecimalLiteralOverflow(uint256 offset);\n\n/// Encountered a decimal literal with an exponent that has too many or no\n/// digits.\nerror MalformedExponentDigits(uint256 offset);\n\n/// Encountered a zero length decimal literal.\nerror ZeroLengthDecimal(uint256 offset);\n\n/// @dev The type of a literal is both a unique value and a literal offset used\n/// to index into the literal parser array as a uint256.\nuint256 constant LITERAL_TYPE_INTEGER_HEX = 0;\n/// @dev The type of a literal is both a unique value and a literal offset used\n/// to index into the literal parser array as a uint256.\nuint256 constant LITERAL_TYPE_INTEGER_DECIMAL = 0x10;\n\nlibrary LibParseLiteral {\n    function buildLiteralParsers() internal pure returns (uint256 literalParsers) {\n        // Register all the literal parsers in the parse state. Each is a 16 bit\n        // function pointer so we can have up to 16 literal types. This needs to\n        // be done at runtime because the library code doesn't know the bytecode\n        // offsets of the literal parsers until it is compiled into a contract.\n        {\n            function(bytes memory, uint256, uint256) pure returns (uint256) literalParserHex =\n                LibParseLiteral.parseLiteralHex;\n            uint256 parseLiteralHexOffset = LITERAL_TYPE_INTEGER_HEX;\n            function(bytes memory, uint256, uint256) pure returns (uint256) literalParserDecimal =\n                LibParseLiteral.parseLiteralDecimal;\n            uint256 parseLiteralDecimalOffset = LITERAL_TYPE_INTEGER_DECIMAL;\n\n            assembly (\"memory-safe\") {\n                literalParsers :=\n                    or(shl(parseLiteralHexOffset, literalParserHex), shl(parseLiteralDecimalOffset, literalParserDecimal))\n            }\n        }\n    }\n\n    /// Find the bounds for some literal at the cursor. The caller is responsible\n    /// for checking that the cursor is at the start of a literal. As each\n    /// literal type has a different format, this function returns the bounds\n    /// for the literal and the type of the literal. The bounds are:\n    /// - innerStart: the start of the literal, e.g. after the 0x in 0x1234\n    /// - innerEnd: the end of the literal, e.g. after the 1234 in 0x1234\n    /// - outerEnd: the end of the literal including any suffixes, MAY be the\n    ///   same as innerEnd if there is no suffix.\n    /// The outerStart is the cursor, so it is not returned.\n    /// @param cursor The start of the literal.\n    /// @return The literal parser. This function can be called to convert the\n    /// bounds into a uint256 value.\n    /// @return The inner start.\n    /// @return The inner end.\n    /// @return The outer end.\n    function boundLiteral(uint256 literalParsers, bytes memory data, uint256 cursor)\n        internal\n        pure\n        returns (function(bytes memory, uint256, uint256) pure returns (uint256), uint256, uint256, uint256)\n    {\n        unchecked {\n            uint256 word;\n            uint256 head;\n            assembly (\"memory-safe\") {\n                word := mload(cursor)\n                //slither-disable-next-line incorrect-shift\n                head := shl(byte(0, word), 1)\n            }\n\n            // numeric literal head is 0-9\n            if (head & CMASK_NUMERIC_LITERAL_HEAD != 0) {\n                uint256 dispatch;\n                assembly (\"memory-safe\") {\n                    //slither-disable-next-line incorrect-shift\n                    dispatch := shl(byte(1, word), 1)\n                }\n\n                // hexadecimal literal dispatch is 0x\n                if ((head | dispatch) == CMASK_LITERAL_HEX_DISPATCH) {\n                    uint256 innerStart = cursor + 2;\n                    uint256 innerEnd = innerStart;\n                    {\n                        uint256 hexCharMask = CMASK_HEX;\n                        assembly (\"memory-safe\") {\n                            //slither-disable-next-line incorrect-shift\n                            for {} iszero(iszero(and(shl(byte(0, mload(innerEnd)), 1), hexCharMask))) {\n                                innerEnd := add(innerEnd, 1)\n                            } {}\n                        }\n                    }\n\n                    function(bytes memory, uint256, uint256) pure returns (uint256) parser;\n                    {\n                        uint256 p = (literalParsers >> LITERAL_TYPE_INTEGER_HEX) & 0xFFFF;\n                        assembly {\n                            parser := p\n                        }\n                    }\n                    {\n                        uint256 endHex;\n                        assembly (\"memory-safe\") {\n                            endHex := add(data, add(mload(data), 0x20))\n                        }\n                        if (innerEnd > endHex) {\n                            revert ParserOutOfBounds();\n                        }\n                    }\n                    return (parser, innerStart, innerEnd, innerEnd);\n                }\n                // decimal is the fallback as continuous numeric digits 0-9.\n                else {\n                    uint256 innerStart = cursor;\n                    // We know the head is a numeric so we can move past it.\n                    uint256 innerEnd = innerStart + 1;\n                    uint256 ePosition = 0;\n\n                    {\n                        uint256 decimalCharMask = CMASK_NUMERIC_0_9;\n                        uint256 eMask = CMASK_E_NOTATION;\n                        assembly (\"memory-safe\") {\n                            //slither-disable-next-line incorrect-shift\n                            for {} iszero(iszero(and(shl(byte(0, mload(innerEnd)), 1), decimalCharMask))) {\n                                innerEnd := add(innerEnd, 1)\n                            } {}\n\n                            // If we're now pointing at an e notation, then we need\n                            // to move past it. Negative exponents are not supported.\n                            //slither-disable-next-line incorrect-shift\n                            if iszero(iszero(and(shl(byte(0, mload(innerEnd)), 1), eMask))) {\n                                ePosition := innerEnd\n                                innerEnd := add(innerEnd, 1)\n\n                                // Move past the exponent digits.\n                                //slither-disable-next-line incorrect-shift\n                                for {} iszero(iszero(and(shl(byte(0, mload(innerEnd)), 1), decimalCharMask))) {\n                                    innerEnd := add(innerEnd, 1)\n                                } {}\n                            }\n                        }\n                    }\n                    if (ePosition != 0 && (innerEnd > ePosition + 3 || innerEnd == ePosition + 1)) {\n                        revert MalformedExponentDigits(LibParse.parseErrorOffset(data, ePosition));\n                    }\n\n                    function(bytes memory, uint256, uint256) pure returns (uint256) parser;\n                    {\n                        uint256 p = (literalParsers >> LITERAL_TYPE_INTEGER_DECIMAL) & 0xFFFF;\n                        assembly {\n                            parser := p\n                        }\n                    }\n                    {\n                        uint256 endDecimal;\n                        assembly (\"memory-safe\") {\n                            endDecimal := add(data, add(mload(data), 0x20))\n                        }\n                        if (innerEnd > endDecimal) {\n                            revert ParserOutOfBounds();\n                        }\n                    }\n                    return (parser, innerStart, innerEnd, innerEnd);\n                }\n            }\n\n            uint256 endUnknown;\n            assembly (\"memory-safe\") {\n                endUnknown := add(data, add(mload(data), 0x20))\n            }\n            if (cursor >= endUnknown) {\n                revert ParserOutOfBounds();\n            } else {\n                revert UnsupportedLiteralType(LibParse.parseErrorOffset(data, cursor));\n            }\n        }\n    }\n\n    /// Algorithm for parsing hexadecimal literals:\n    /// - start at the end of the literal\n    /// - for each character:\n    ///   - convert the character to a nybble\n    ///   - shift the nybble into the total at the correct position\n    ///     (4 bits per nybble)\n    /// - return the total\n    function parseLiteralHex(bytes memory data, uint256 start, uint256 end) internal pure returns (uint256 value) {\n        unchecked {\n            uint256 length = end - start;\n            if (length > 0x40) {\n                revert HexLiteralOverflow(LibParse.parseErrorOffset(data, start));\n            } else if (length == 0) {\n                revert ZeroLengthHexLiteral(LibParse.parseErrorOffset(data, start));\n            } else if (length % 2 == 1) {\n                revert OddLengthHexLiteral(LibParse.parseErrorOffset(data, start));\n            } else {\n                uint256 cursor = end - 1;\n                uint256 valueOffset = 0;\n                while (cursor >= start) {\n                    uint256 hexCharByte;\n                    assembly (\"memory-safe\") {\n                        hexCharByte := byte(0, mload(cursor))\n                    }\n                    //slither-disable-next-line incorrect-shift\n                    uint256 hexChar = 1 << hexCharByte;\n\n                    uint256 nybble;\n                    // 0-9\n                    if (hexChar & CMASK_NUMERIC_0_9 != 0) {\n                        nybble = hexCharByte - uint256(uint8(bytes1(\"0\")));\n                    }\n                    // a-f\n                    else if (hexChar & CMASK_LOWER_ALPHA_A_F != 0) {\n                        nybble = hexCharByte - uint256(uint8(bytes1(\"a\"))) + 10;\n                    }\n                    // A-F\n                    else if (hexChar & CMASK_UPPER_ALPHA_A_F != 0) {\n                        nybble = hexCharByte - uint256(uint8(bytes1(\"A\"))) + 10;\n                    } else {\n                        revert MalformedHexLiteral(LibParse.parseErrorOffset(data, cursor));\n                    }\n\n                    value |= nybble << valueOffset;\n                    valueOffset += 4;\n                    cursor--;\n                }\n            }\n        }\n    }\n\n    /// Algorithm for parsing decimal literals:\n    /// - start at the end of the literal\n    /// - for each digit:\n    ///   - multiply the digit by 10^digit position\n    ///   - add the result to the total\n    /// - return the total\n    ///\n    /// This algorithm is ONLY safe if the caller has already checked that the\n    /// start/end span a non-zero length of valid decimal chars. The caller\n    /// can most easily do this by using the `boundLiteral` function.\n    ///\n    /// Unsafe behavior is undefined and can easily result in out of bounds\n    /// reads as there are no checks that start/end are within `data`.\n    function parseLiteralDecimal(bytes memory data, uint256 start, uint256 end) internal pure returns (uint256 value) {\n        unchecked {\n            // Tracks which digit we're on.\n            uint256 cursor;\n            // The ASCII byte can be translated to a numeric digit by subtracting\n            // the digit offset.\n            uint256 digitOffset = uint256(uint8(bytes1(\"0\")));\n            // Tracks the exponent of the current digit. Can start above 0 if\n            // the literal is in e notation.\n            uint256 exponent;\n            {\n                uint256 word;\n                //slither-disable-next-line similar-names\n                uint256 decimalCharByte;\n                uint256 length = end - start;\n                assembly (\"memory-safe\") {\n                    word := mload(sub(end, 3))\n                    decimalCharByte := byte(0, word)\n                }\n                // If the last 3 bytes are e notation, then we need to parse\n                // the exponent as a 2 digit number.\n                //slither-disable-next-line incorrect-shift\n                if (length > 3 && ((1 << decimalCharByte) & CMASK_E_NOTATION) != 0) {\n                    cursor = end - 4;\n                    assembly (\"memory-safe\") {\n                        exponent := add(sub(byte(2, word), digitOffset), mul(sub(byte(1, word), digitOffset), 10))\n                    }\n                } else {\n                    assembly (\"memory-safe\") {\n                        decimalCharByte := byte(1, word)\n                    }\n                    // If the last 2 bytes are e notation, then we need to parse\n                    // the exponent as a 1 digit number.\n                    //slither-disable-next-line incorrect-shift\n                    if (length > 2 && ((1 << decimalCharByte) & CMASK_E_NOTATION) != 0) {\n                        cursor = end - 3;\n                        assembly (\"memory-safe\") {\n                            exponent := sub(byte(2, word), digitOffset)\n                        }\n                    }\n                    // Otherwise, we're not in e notation and we can start at the\n                    // end of the literal with 0 starting exponent.\n                    else if (length > 0) {\n                        cursor = end - 1;\n                        exponent = 0;\n                    } else {\n                        revert ZeroLengthDecimal(LibParse.parseErrorOffset(data, start));\n                    }\n                }\n            }\n\n            // Anything under 10^77 is safe to raise to its power of 10 without\n            // overflowing a uint256.\n            while (cursor >= start && exponent < 77) {\n                // We don't need to check the bounds of the byte because\n                // we know it is a decimal literal as long as the bounds\n                // are correct (calculated in `boundLiteral`).\n                assembly (\"memory-safe\") {\n                    value := add(value, mul(sub(byte(0, mload(cursor)), digitOffset), exp(10, exponent)))\n                }\n                exponent++;\n                cursor--;\n            }\n\n            // If we didn't consume the entire literal, then we have\n            // to check if the remaining digit is safe to multiply\n            // by 10 without overflowing a uint256.\n            if (cursor >= start) {\n                {\n                    uint256 digit;\n                    assembly (\"memory-safe\") {\n                        digit := sub(byte(0, mload(cursor)), digitOffset)\n                    }\n                    // If the digit is greater than 1, then we know that\n                    // multiplying it by 10^77 will overflow a uint256.\n                    if (digit > 1) {\n                        revert DecimalLiteralOverflow(LibParse.parseErrorOffset(data, cursor));\n                    } else {\n                        uint256 scaled = digit * (10 ** exponent);\n                        if (value + scaled < value) {\n                            revert DecimalLiteralOverflow(LibParse.parseErrorOffset(data, cursor));\n                        }\n                        value += scaled;\n                    }\n                    cursor--;\n                }\n\n                {\n                    // If we didn't consume the entire literal, then only\n                    // leading zeros are allowed.\n                    while (cursor >= start) {\n                        //slither-disable-next-line similar-names\n                        uint256 decimalCharByte;\n                        assembly (\"memory-safe\") {\n                            decimalCharByte := byte(0, mload(cursor))\n                        }\n                        if (decimalCharByte != uint256(uint8(bytes1(\"0\")))) {\n                            revert DecimalLiteralOverflow(LibParse.parseErrorOffset(data, cursor));\n                        }\n                        cursor--;\n                    }\n                }\n            }\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.factory/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n    /**\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n     */\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n     */\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of tokens in ``owner``'s account.\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n     * understand this adds an external call which potentially creates a reentrancy vulnerability.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the caller.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool approved) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
      },
      "lib/rain.flow/lib/rain.factory/lib/openzeppelin-contracts/contracts/utils/math/Math.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n     * with further edits by Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod0 := mul(x, y)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            require(denominator > prod1, \"Math: mulDiv overflow\");\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n            // See https://cs.stackexchange.com/q/138556/92363.\n\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 twos = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/UD60x18.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n/*\n\n██████╗ ██████╗ ██████╗ ███╗   ███╗ █████╗ ████████╗██╗  ██╗\n██╔══██╗██╔══██╗██╔══██╗████╗ ████║██╔══██╗╚══██╔══╝██║  ██║\n██████╔╝██████╔╝██████╔╝██╔████╔██║███████║   ██║   ███████║\n██╔═══╝ ██╔══██╗██╔══██╗██║╚██╔╝██║██╔══██║   ██║   ██╔══██║\n██║     ██║  ██║██████╔╝██║ ╚═╝ ██║██║  ██║   ██║   ██║  ██║\n╚═╝     ╚═╝  ╚═╝╚═════╝ ╚═╝     ╚═╝╚═╝  ╚═╝   ╚═╝   ╚═╝  ╚═╝\n\n██╗   ██╗██████╗  ██████╗  ██████╗ ██╗  ██╗ ██╗ █████╗\n██║   ██║██╔══██╗██╔════╝ ██╔═████╗╚██╗██╔╝███║██╔══██╗\n██║   ██║██║  ██║███████╗ ██║██╔██║ ╚███╔╝ ╚██║╚█████╔╝\n██║   ██║██║  ██║██╔═══██╗████╔╝██║ ██╔██╗  ██║██╔══██╗\n╚██████╔╝██████╔╝╚██████╔╝╚██████╔╝██╔╝ ██╗ ██║╚█████╔╝\n ╚═════╝ ╚═════╝  ╚═════╝  ╚═════╝ ╚═╝  ╚═╝ ╚═╝ ╚════╝\n\n*/\n\nimport \"./ud60x18/Casting.sol\";\nimport \"./ud60x18/Constants.sol\";\nimport \"./ud60x18/Conversions.sol\";\nimport \"./ud60x18/Errors.sol\";\nimport \"./ud60x18/Helpers.sol\";\nimport \"./ud60x18/Math.sol\";\nimport \"./ud60x18/ValueType.sol\";\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/rain.math.fixedpoint/src/lib/LibWillOverflow.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"./FixedPointDecimalConstants.sol\";\n\n/// @title LibWillOverflow\n/// @notice Often we want to know if some calculation is expected to overflow.\n/// Notably this is important for fuzzing as we have to be able to set\n/// expectations for arbitrary inputs over as broad a range of values as\n/// possible.\nlibrary LibWillOverflow {\n    /// Relevant logic taken direct from Open Zeppelin.\n    /// @param x As per Open Zeppelin.\n    /// @param y As per Open Zeppelin.\n    /// @param denominator As per Open Zeppelin.\n    /// @return True if mulDiv will overflow.\n    function mulDivWillOverflow(uint256 x, uint256 y, uint256 denominator) internal pure returns (bool) {\n        // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n        // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n        // variables such that product = prod1 * 2^256 + prod0.\n        uint256 prod0; // Least significant 256 bits of the product\n        uint256 prod1; // Most significant 256 bits of the product\n        assembly (\"memory-safe\") {\n            let mm := mulmod(x, y, not(0))\n            prod0 := mul(x, y)\n            prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n        }\n        return !(denominator > prod1);\n    }\n\n    /// True if `scaleUp` will overflow.\n    /// @param a The number to scale up.\n    /// @param scaleBy The number of orders of magnitude to scale up by.\n    /// @return True if `scaleUp` will overflow.\n    function scaleUpWillOverflow(uint256 a, uint256 scaleBy) internal pure returns (bool) {\n        unchecked {\n            if (a == 0) {\n                return false;\n            }\n            if (scaleBy >= OVERFLOW_RESCALE_OOMS) {\n                return true;\n            }\n            uint256 b = 10 ** scaleBy;\n            uint256 c = a * b;\n            return c / b != a;\n        }\n    }\n\n    /// True if `scaleDown` will round.\n    /// @param a The number to scale down.\n    /// @param scaleDownBy The number of orders of magnitude to scale down by.\n    /// @return True if `scaleDown` will round.\n    function scaleDownWillRound(uint256 a, uint256 scaleDownBy) internal pure returns (bool) {\n        if (scaleDownBy >= OVERFLOW_RESCALE_OOMS) {\n            return a != 0;\n        }\n        uint256 b = 10 ** scaleDownBy;\n        uint256 c = a / b;\n        // Discovering precision loss is the whole point of this check so the\n        // thing slither is complaining about is exactly what we're measuring.\n        //slither-disable-next-line divide-before-multiply\n        return c * b != a;\n    }\n\n    /// True if `scale18` will overflow.\n    /// @param a The number to scale.\n    /// @param decimals The current number of decimals of `a`.\n    /// @param flags The flags to use.\n    /// @return True if `scale18` will overflow.\n    function scale18WillOverflow(uint256 a, uint256 decimals, uint256 flags) internal pure returns (bool) {\n        if (decimals < FIXED_POINT_DECIMALS && (FLAG_SATURATE & flags == 0)) {\n            return scaleUpWillOverflow(a, FIXED_POINT_DECIMALS - decimals);\n        } else {\n            return false;\n        }\n    }\n\n    /// True if `scaleN` will overflow.\n    /// @param a The number to scale.\n    /// @param decimals The current number of decimals of `a`.\n    /// @param flags The flags to use.\n    /// @return True if `scaleN` will overflow.\n    function scaleNWillOverflow(uint256 a, uint256 decimals, uint256 flags) internal pure returns (bool) {\n        if (decimals > FIXED_POINT_DECIMALS && (FLAG_SATURATE & flags == 0)) {\n            return scaleUpWillOverflow(a, decimals - FIXED_POINT_DECIMALS);\n        } else {\n            return false;\n        }\n    }\n\n    /// True if `scaleBy` will overflow.\n    /// @param a The number to scale.\n    /// @param scaleBy The number of orders of magnitude to scale by.\n    /// @param flags The flags to use.\n    /// @return True if `scaleBy` will overflow.\n    function scaleByWillOverflow(uint256 a, int8 scaleBy, uint256 flags) internal pure returns (bool) {\n        // If we're scaling up and not saturating check the overflow.\n        if (scaleBy > 0 && (FLAG_SATURATE & flags == 0)) {\n            return scaleUpWillOverflow(a, uint8(scaleBy));\n        } else {\n            return false;\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/rain.math.fixedpoint/src/lib/LibFixedPointDecimalScale.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"./FixedPointDecimalConstants.sol\";\n\n/// @title FixedPointDecimalScale\n/// @notice Tools to scale unsigned values to/from 18 decimal fixed point\n/// representation.\n///\n/// Overflows error and underflows are rounded up or down explicitly.\n///\n/// The max uint256 as decimal is roughly 1e77 so scaling values comparable to\n/// 1e18 is unlikely to ever overflow in most contexts. For a typical use case\n/// involving tokens, the entire supply of a token rescaled up a full 18 decimals\n/// would still put it \"only\" in the region of ~1e40 which has a full 30 orders\n/// of magnitude buffer before running into saturation issues. However, there's\n/// no theoretical reason that a token or any other use case couldn't use large\n/// numbers or extremely precise decimals that would push this library to\n/// overflow point, so it MUST be treated with caution around the edge cases.\n///\n/// Scaling down ANY fixed point decimal also reduces the precision which can\n/// lead to  dust or in the worst case trapped funds if subsequent subtraction\n/// overflows a rounded-down number. Consider using saturating subtraction for\n/// safety against previously downscaled values, and whether trapped dust is a\n/// significant issue. If you need to retain full/arbitrary precision in the case\n/// of downscaling DO NOT use this library.\n///\n/// All rescaling and/or division operations in this library require a rounding\n/// flag. This allows and forces the caller to specify where dust sits due to\n/// rounding. For example the caller could round up when taking tokens from\n/// `msg.sender` and round down when returning them, ensuring that any dust in\n/// the round trip accumulates in the contract rather than opening an exploit or\n/// reverting and trapping all funds. This is exactly how the ERC4626 vault spec\n/// handles dust and is a good reference point in general. Typically the contract\n/// holding tokens and non-interactive participants should be favoured by\n/// rounding calculations rather than active participants. This is because we\n/// assume that an active participant, e.g. `msg.sender`, knowns something we\n/// don't and is carefully crafting an attack, so we are most conservative and\n/// suspicious of their inputs and actions.\nlibrary LibFixedPointDecimalScale {\n    /// Scales `a` up by a specified number of decimals.\n    /// @param a The number to scale up.\n    /// @param scaleUpBy Number of orders of magnitude to scale `b_` up by.\n    /// Errors if overflows.\n    /// @return b `a` scaled up by `scaleUpBy`.\n    function scaleUp(uint256 a, uint256 scaleUpBy) internal pure returns (uint256 b) {\n        // Checked power is expensive so don't do that.\n        unchecked {\n            b = 10 ** scaleUpBy;\n        }\n        b = a * b;\n\n        // We know exactly when 10 ** X overflows so replay the checked version\n        // to get the standard Solidity overflow behaviour. The branching logic\n        // here is still ~230 gas cheaper than unconditionally running the\n        // overflow checks. We're optimising for standardisation rather than gas\n        // in the unhappy revert case.\n        if (scaleUpBy >= OVERFLOW_RESCALE_OOMS) {\n            b = a == 0 ? 0 : 10 ** scaleUpBy;\n        }\n    }\n\n    /// Identical to `scaleUp` but saturates instead of reverting on overflow.\n    /// @param a As per `scaleUp`.\n    /// @param scaleUpBy As per `scaleUp`.\n    /// @return c As per `scaleUp` but saturates as `type(uint256).max` on\n    /// overflow.\n    function scaleUpSaturating(uint256 a, uint256 scaleUpBy) internal pure returns (uint256 c) {\n        unchecked {\n            if (scaleUpBy >= OVERFLOW_RESCALE_OOMS) {\n                c = a == 0 ? 0 : type(uint256).max;\n            } else {\n                // Adapted from saturatingMath.\n                // Inlining everything here saves ~250-300+ gas relative to slow.\n                uint256 b_ = 10 ** scaleUpBy;\n                c = a * b_;\n                // Checking b_ here allows us to skip an \"is zero\" check because even\n                // 10 ** 0 = 1, so we have a positive lower bound on b_.\n                c = c / b_ == a ? c : type(uint256).max;\n            }\n        }\n    }\n\n    /// Scales `a` down by a specified number of decimals, rounding down.\n    /// Used internally by several other functions in this lib.\n    /// @param a The number to scale down.\n    /// @param scaleDownBy Number of orders of magnitude to scale `a` down by.\n    /// Overflows if greater than 77.\n    /// @return c `a` scaled down by `scaleDownBy` and rounded down.\n    function scaleDown(uint256 a, uint256 scaleDownBy) internal pure returns (uint256) {\n        unchecked {\n            return scaleDownBy >= OVERFLOW_RESCALE_OOMS ? 0 : a / (10 ** scaleDownBy);\n        }\n    }\n\n    /// Scales `a` down by a specified number of decimals, rounding up.\n    /// Used internally by several other functions in this lib.\n    /// @param a The number to scale down.\n    /// @param scaleDownBy Number of orders of magnitude to scale `a` down by.\n    /// Overflows if greater than 77.\n    /// @return c `a` scaled down by `scaleDownBy` and rounded up.\n    function scaleDownRoundUp(uint256 a, uint256 scaleDownBy) internal pure returns (uint256 c) {\n        unchecked {\n            if (scaleDownBy >= OVERFLOW_RESCALE_OOMS) {\n                c = a == 0 ? 0 : 1;\n            } else {\n                uint256 b = 10 ** scaleDownBy;\n                c = a / b;\n\n                // Intentionally doing a divide before multiply here to detect\n                // the need to round up.\n                //slither-disable-next-line divide-before-multiply\n                if (a != c * b) {\n                    c += 1;\n                }\n            }\n        }\n    }\n\n    /// Scale a fixed point decimal of some scale factor to 18 decimals.\n    /// @param a Some fixed point decimal value.\n    /// @param decimals The number of fixed decimals of `a`.\n    /// @param flags Controls rounding and saturation.\n    /// @return `a` scaled to 18 decimals.\n    function scale18(uint256 a, uint256 decimals, uint256 flags) internal pure returns (uint256) {\n        unchecked {\n            if (FIXED_POINT_DECIMALS > decimals) {\n                uint256 scaleUpBy = FIXED_POINT_DECIMALS - decimals;\n                if (flags & FLAG_SATURATE > 0) {\n                    return scaleUpSaturating(a, scaleUpBy);\n                } else {\n                    return scaleUp(a, scaleUpBy);\n                }\n            } else if (decimals > FIXED_POINT_DECIMALS) {\n                uint256 scaleDownBy = decimals - FIXED_POINT_DECIMALS;\n                if (flags & FLAG_ROUND_UP > 0) {\n                    return scaleDownRoundUp(a, scaleDownBy);\n                } else {\n                    return scaleDown(a, scaleDownBy);\n                }\n            } else {\n                return a;\n            }\n        }\n    }\n\n    /// Scale an 18 decimal fixed point value to some other scale.\n    /// Exactly the inverse behaviour of `scale18`. Where `scale18` would scale\n    /// up, `scaleN` scales down, and vice versa.\n    /// @param a An 18 decimal fixed point number.\n    /// @param targetDecimals The new scale of `a`.\n    /// @param flags Controls rounding and saturation.\n    /// @return `a` rescaled from 18 to `targetDecimals`.\n    function scaleN(uint256 a, uint256 targetDecimals, uint256 flags) internal pure returns (uint256) {\n        unchecked {\n            if (FIXED_POINT_DECIMALS > targetDecimals) {\n                uint256 scaleDownBy = FIXED_POINT_DECIMALS - targetDecimals;\n                if (flags & FLAG_ROUND_UP > 0) {\n                    return scaleDownRoundUp(a, scaleDownBy);\n                } else {\n                    return scaleDown(a, scaleDownBy);\n                }\n            } else if (targetDecimals > FIXED_POINT_DECIMALS) {\n                uint256 scaleUpBy = targetDecimals - FIXED_POINT_DECIMALS;\n                if (flags & FLAG_SATURATE > 0) {\n                    return scaleUpSaturating(a, scaleUpBy);\n                } else {\n                    return scaleUp(a, scaleUpBy);\n                }\n            } else {\n                return a;\n            }\n        }\n    }\n\n    /// Scale a fixed point up or down by `ooms` orders of magnitude.\n    /// Notably `scaleBy` is a SIGNED integer so scaling down by negative OOMS\n    /// IS supported.\n    /// @param a Some integer of any scale.\n    /// @param ooms OOMs to scale `a` up or down by. This is a SIGNED int8\n    /// which means it can be negative, and also means that sign extension MUST\n    /// be considered if changing it to another type.\n    /// @param flags Controls rounding and saturating.\n    /// @return `a` rescaled according to `ooms`.\n    function scaleBy(uint256 a, int8 ooms, uint256 flags) internal pure returns (uint256) {\n        unchecked {\n            if (ooms > 0) {\n                if (flags & FLAG_SATURATE > 0) {\n                    return scaleUpSaturating(a, uint8(ooms));\n                } else {\n                    return scaleUp(a, uint8(ooms));\n                }\n            } else if (ooms < 0) {\n                // We know that ooms is negative here, so we can convert it\n                // to an absolute value with bitwise NOT + 1.\n                // This is slightly less gas than multiplying by negative 1 and\n                // casting it, and handles the case of -128 without overflow.\n                uint8 scaleDownBy = uint8(~ooms) + 1;\n                if (flags & FLAG_ROUND_UP > 0) {\n                    return scaleDownRoundUp(a, scaleDownBy);\n                } else {\n                    return scaleDown(a, scaleDownBy);\n                }\n            } else {\n                return a;\n            }\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/sol.lib.binmaskflag/src/Binary.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// @dev Binary 1.\nuint256 constant B_1 = 2 ** 1 - 1;\n/// @dev Binary 11.\nuint256 constant B_11 = 2 ** 2 - 1;\n/// @dev Binary 111.\nuint256 constant B_111 = 2 ** 3 - 1;\n/// @dev Binary 1111.\nuint256 constant B_1111 = 2 ** 4 - 1;\n/// @dev Binary 11111.\nuint256 constant B_11111 = 2 ** 5 - 1;\n/// @dev Binary 111111.\nuint256 constant B_111111 = 2 ** 6 - 1;\n/// @dev Binary 1111111.\nuint256 constant B_1111111 = 2 ** 7 - 1;\n/// @dev Binary 11111111.\nuint256 constant B_11111111 = 2 ** 8 - 1;\n/// @dev Binary 111111111.\nuint256 constant B_111111111 = 2 ** 9 - 1;\n/// @dev Binary 1111111111.\nuint256 constant B_1111111111 = 2 ** 10 - 1;\n/// @dev Binary 11111111111.\nuint256 constant B_11111111111 = 2 ** 11 - 1;\n/// @dev Binary 111111111111.\nuint256 constant B_111111111111 = 2 ** 12 - 1;\n/// @dev Binary 1111111111111.\nuint256 constant B_1111111111111 = 2 ** 13 - 1;\n/// @dev Binary 11111111111111.\nuint256 constant B_11111111111111 = 2 ** 14 - 1;\n/// @dev Binary 111111111111111.\nuint256 constant B_111111111111111 = 2 ** 15 - 1;\n/// @dev Binary 1111111111111111.\nuint256 constant B_1111111111111111 = 2 ** 16 - 1;\n\n/// @dev Bitmask for 1 bit.\nuint256 constant MASK_1BIT = B_1;\n/// @dev Bitmask for 2 bits.\nuint256 constant MASK_2BIT = B_11;\n/// @dev Bitmask for 3 bits.\nuint256 constant MASK_3BIT = B_111;\n/// @dev Bitmask for 4 bits.\nuint256 constant MASK_4BIT = B_1111;\n/// @dev Bitmask for 5 bits.\nuint256 constant MASK_5BIT = B_11111;\n/// @dev Bitmask for 6 bits.\nuint256 constant MASK_6BIT = B_111111;\n/// @dev Bitmask for 7 bits.\nuint256 constant MASK_7BIT = B_1111111;\n/// @dev Bitmask for 8 bits.\nuint256 constant MASK_8BIT = B_11111111;\n/// @dev Bitmask for 9 bits.\nuint256 constant MASK_9BIT = B_111111111;\n/// @dev Bitmask for 10 bits.\nuint256 constant MASK_10BIT = B_1111111111;\n/// @dev Bitmask for 11 bits.\nuint256 constant MASK_11BIT = B_11111111111;\n/// @dev Bitmask for 12 bits.\nuint256 constant MASK_12BIT = B_111111111111;\n/// @dev Bitmask for 13 bits.\nuint256 constant MASK_13BIT = B_1111111111111;\n/// @dev Bitmask for 14 bits.\nuint256 constant MASK_14BIT = B_11111111111111;\n/// @dev Bitmask for 15 bits.\nuint256 constant MASK_15BIT = B_111111111111111;\n/// @dev Bitmask for 16 bits.\nuint256 constant MASK_16BIT = B_1111111111111111;\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/uniswap/LibUniswapV2.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"v2-core/interfaces/IUniswapV2Pair.sol\";\nimport \"v2-core/interfaces/IUniswapV2Factory.sol\";\n\n/// UniswapV2Library from uniswap/v2-periphery is compiled with a version of\n/// SafeMath that is locked to Solidity 0.6.x which means we can't use it in\n/// Solidity 0.8.x. This is a copy of the library with the SafeMath dependency\n/// removed, using Solidity's built-in overflow checking.\n/// Some minor modifications have been made to the reference functions. These\n/// are noted in the comments and/or made explicit by descriptively renaming the\n/// functions to differentiate them from the original.\nlibrary LibUniswapV2 {\n    /// Copy of UniswapV2Library.sortTokens for solidity 0.8.x support.\n    function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {\n        require(tokenA != tokenB, \"UniswapV2Library: IDENTICAL_ADDRESSES\");\n        (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);\n        require(token0 != address(0), \"UniswapV2Library: ZERO_ADDRESS\");\n    }\n\n    /// Copy of UniswapV2Library.pairFor for solidity 0.8.x support.\n    function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) {\n        (address token0, address token1) = sortTokens(tokenA, tokenB);\n        pair = address(\n            uint160(\n                uint256(\n                    keccak256(\n                        abi.encodePacked(\n                            hex\"ff\",\n                            factory,\n                            keccak256(abi.encodePacked(token0, token1)),\n                            hex\"96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f\" // init code hash\n                        )\n                    )\n                )\n            )\n        );\n    }\n\n    /// UniswapV2Library.sol has a `getReserves` function but it discards the\n    /// timestamp that the pair reserves were last updated at. This function\n    /// duplicates the logic of `getReserves` but returns the timestamp as well.\n    function getReservesWithTime(address factory, address tokenA, address tokenB)\n        internal\n        view\n        returns (uint256 reserveA, uint256 reserveB, uint256 timestamp)\n    {\n        (address token0,) = sortTokens(tokenA, tokenB);\n        // Reference implementation uses `pairFor` but for some reason this\n        // doesn't seem to work on sushi's factory. Using `getPair` instead.\n        // @todo investigate the discrepency.\n        address pair = IUniswapV2Factory(factory).getPair(tokenA, tokenB);\n        (uint256 reserve0, uint256 reserve1, uint256 blockTimestampLast) = IUniswapV2Pair(pair).getReserves();\n        (reserveA, reserveB, timestamp) =\n            tokenA == token0 ? (reserve0, reserve1, blockTimestampLast) : (reserve1, reserve0, blockTimestampLast);\n    }\n\n    /// Copy of UniswapV2Library.getAmountIn for solidity 0.8.x support.\n    function getAmountIn(uint256 amountOut, uint256 reserveIn, uint256 reserveOut)\n        internal\n        pure\n        returns (uint256 amountIn)\n    {\n        require(amountOut > 0, \"UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT\");\n        require(reserveIn > 0 && reserveOut > 0, \"UniswapV2Library: INSUFFICIENT_LIQUIDITY\");\n        uint256 numerator = reserveIn * amountOut * 1000;\n        uint256 denominator = (reserveOut - amountOut) * 997;\n        amountIn = (numerator / denominator) + 1;\n    }\n\n    /// Copy of UniswapV2Library.getAmountOut for solidity 0.8.x support.\n    function getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut)\n        internal\n        pure\n        returns (uint256 amountOut)\n    {\n        require(amountIn > 0, \"UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT\");\n        require(reserveIn > 0 && reserveOut > 0, \"UniswapV2Library: INSUFFICIENT_LIQUIDITY\");\n        uint256 amountInWithFee = amountIn * 997;\n        uint256 numerator = amountInWithFee * reserveOut;\n        uint256 denominator = (reserveIn * 1000) + amountInWithFee;\n        amountOut = numerator / denominator;\n    }\n\n    /// Bundles the key library logic together to produce amounts based on tokens\n    /// and amounts out rather than needing to handle reserves directly.\n    /// Also maps 0 amountOut to 0 amountIn unconditionally, which is different\n    /// to the reference implementation.\n    function getAmountInByTokenWithTime(address factory, address tokenIn, address tokenOut, uint256 amountOut)\n        internal\n        view\n        returns (uint256 amountIn, uint256 timestamp)\n    {\n        (uint256 reserveIn, uint256 reserveOut, uint256 reserveTimestamp) =\n            getReservesWithTime(factory, tokenIn, tokenOut);\n        // Perform the 0 amountOut to 0 amountIn mapping after getting the\n        // reserves so that we still error on invalid reserves.\n        amountIn = amountOut == 0 ? 0 : getAmountIn(amountOut, reserveIn, reserveOut);\n        timestamp = reserveTimestamp;\n    }\n\n    /// Bundles the key library logic together to produce amounts based on tokens\n    /// and amounts in rather than needing to handle reserves directly.\n    /// Also maps 0 amountIn to 0 amountOut unconditionally, which is different\n    /// to the reference implementation.\n    function getAmountOutByTokenWithTime(address factory, address tokenIn, address tokenOut, uint256 amountIn)\n        internal\n        view\n        returns (uint256 amountOut, uint256 timestamp)\n    {\n        (uint256 reserveIn, uint256 reserveOut, uint256 reserveTimestamp) =\n            getReservesWithTime(factory, tokenIn, tokenOut);\n        // Perform the 0 amountIn to 0 amountOut mapping after getting the\n        // reserves so that we still error on invalid reserves.\n        amountOut = amountIn == 0 ? 0 : getAmountOut(amountIn, reserveIn, reserveOut);\n        timestamp = reserveTimestamp;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/src/lib/parse/LibParseStackName.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"./LibParse.sol\";\n\nlibrary LibParseStackName {\n    /// Push a word onto the stack name stack.\n    /// @return exists Whether the word already existed.\n    /// @return index The new index after the word was pushed. Will be unchanged\n    /// if the word already existed.\n    function pushStackName(ParseState memory state, bytes32 word) internal pure returns (bool exists, uint256 index) {\n        unchecked {\n            (exists, index) = stackNameIndex(state, word);\n            if (!exists) {\n                uint256 fingerprint;\n                uint256 ptr;\n                uint256 oldStackNames = state.stackNames;\n                assembly (\"memory-safe\") {\n                    ptr := mload(0x40)\n                    mstore(ptr, word)\n                    fingerprint := and(keccak256(ptr, 0x20), not(0xFFFFFFFF))\n                    mstore(ptr, oldStackNames)\n                    mstore(0x40, add(ptr, 0x20))\n                }\n                // Add the start of line height to the LHS line parse count.\n                uint256 stackLHSIndex = state.topLevel1 & 0xFF;\n                state.stackNames = fingerprint | (stackLHSIndex << 0x10) | ptr;\n                index = stackLHSIndex + 1;\n            }\n        }\n    }\n\n    /// Retrieve the index of a previously pushed stack name.\n    function stackNameIndex(ParseState memory state, bytes32 word) internal pure returns (bool exists, uint256 index) {\n        uint256 fingerprint;\n        uint256 stackNames = state.stackNames;\n        uint256 stackNameBloom = state.stackNameBloom;\n        uint256 bloom;\n        assembly (\"memory-safe\") {\n            mstore(0, word)\n            fingerprint := shr(0x20, keccak256(0, 0x20))\n            //slither-disable-next-line incorrect-shift\n            bloom := shl(and(fingerprint, 0xFF), 1)\n\n            // If the bloom matches then maybe the stack name is in the stack.\n            if and(bloom, stackNameBloom) {\n                for { let ptr := and(stackNames, 0xFFFF) } iszero(iszero(ptr)) {\n                    stackNames := mload(ptr)\n                    ptr := and(stackNames, 0xFFFF)\n                } {\n                    if eq(fingerprint, shr(0x20, stackNames)) {\n                        exists := true\n                        index := and(shr(0x10, stackNames), 0xFFFF)\n                        break\n                    }\n                }\n            }\n        }\n        state.stackNameBloom = bloom | stackNameBloom;\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/ud60x18/Casting.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_SD59x18 } from \"../sd59x18/Constants.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD60x18 number into SD1x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\n    uint256 xUint = UD60x18.unwrap(x);\n    if (xUint > uint256(int256(uMAX_SD1x18))) {\n        revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\n    }\n    result = SD1x18.wrap(int64(uint64(xUint)));\n}\n\n/// @notice Casts a UD60x18 number into UD2x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_UD2x18`.\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\n    uint256 xUint = UD60x18.unwrap(x);\n    if (xUint > uMAX_UD2x18) {\n        revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\n    }\n    result = UD2x18.wrap(uint64(xUint));\n}\n\n/// @notice Casts a UD60x18 number into SD59x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_SD59x18`.\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\n    uint256 xUint = UD60x18.unwrap(x);\n    if (xUint > uint256(uMAX_SD59x18)) {\n        revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\n    }\n    result = SD59x18.wrap(int256(xUint));\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev This is basically an alias for {unwrap}.\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\n    result = UD60x18.unwrap(x);\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT128`.\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\n    uint256 xUint = UD60x18.unwrap(x);\n    if (xUint > MAX_UINT128) {\n        revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\n    }\n    result = uint128(xUint);\n}\n\n/// @notice Casts a UD60x18 number into uint40.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\n    uint256 xUint = UD60x18.unwrap(x);\n    if (xUint > MAX_UINT40) {\n        revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\n    }\n    result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud(uint256 x) pure returns (UD60x18 result) {\n    result = UD60x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\n    result = UD60x18.wrap(x);\n}\n\n/// @notice Unwraps a UD60x18 number into uint256.\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\n    result = UD60x18.unwrap(x);\n}\n\n/// @notice Wraps a uint256 number into the UD60x18 value type.\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\n    result = UD60x18.wrap(x);\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/ud60x18/Constants.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as a UD60x18 number.\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev The maximum input permitted in {exp2}.\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Half the UNIT number.\nuint256 constant uHALF_UNIT = 0.5e18;\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as a UD60x18 number.\nuint256 constant uLOG2_10 = 3_321928094887362347;\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as a UD60x18 number.\nuint256 constant uLOG2_E = 1_442695040888963407;\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\n\n/// @dev The maximum value a UD60x18 number can have.\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\n\n/// @dev The maximum whole value a UD60x18 number can have.\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\n\n/// @dev PI as a UD60x18 number.\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD60x18.\nuint256 constant uUNIT = 1e18;\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\n\n/// @dev The unit number squared.\nuint256 constant uUNIT_SQUARED = 1e36;\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as a UD60x18 number.\nUD60x18 constant ZERO = UD60x18.wrap(0);\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/ud60x18/Conversions.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { uMAX_UD60x18, uUNIT } from \"./Constants.sol\";\nimport { PRBMath_UD60x18_Convert_Overflow } from \"./Errors.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\n/// @dev The result is rounded toward zero.\n/// @param x The UD60x18 number to convert.\n/// @return result The same number in basic integer form.\nfunction convert(UD60x18 x) pure returns (uint256 result) {\n    result = UD60x18.unwrap(x) / uUNIT;\n}\n\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\n///\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\n///\n/// @param x The basic integer to convert.\n/// @param result The same number converted to UD60x18.\nfunction convert(uint256 x) pure returns (UD60x18 result) {\n    if (x > uMAX_UD60x18 / uUNIT) {\n        revert PRBMath_UD60x18_Convert_Overflow(x);\n    }\n    unchecked {\n        result = UD60x18.wrap(x * uUNIT);\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/ud60x18/Errors.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when ceiling a number overflows UD60x18.\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than 1.\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\n\n/// @notice Thrown when calculating the square root overflows UD60x18.\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/ud60x18/Helpers.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal operation (==) in the UD60x18 type.\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n    result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n    result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n    result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the UD60x18 type.\nfunction isZero(UD60x18 x) pure returns (bool result) {\n    // This wouldn't work if x could be negative.\n    result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n    result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n    result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n    result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\n    result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    unchecked {\n        result = wrap(x.unwrap() + y.unwrap());\n    }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    unchecked {\n        result = wrap(x.unwrap() - y.unwrap());\n    }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    result = wrap(x.unwrap() ^ y.unwrap());\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/ud60x18/Math.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { wrap } from \"./Casting.sol\";\nimport {\n    uEXP_MAX_INPUT,\n    uEXP2_MAX_INPUT,\n    uHALF_UNIT,\n    uLOG2_10,\n    uLOG2_E,\n    uMAX_UD60x18,\n    uMAX_WHOLE_UD60x18,\n    UNIT,\n    uUNIT,\n    uUNIT_SQUARED,\n    ZERO\n} from \"./Constants.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/*//////////////////////////////////////////////////////////////////////////\n                            MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the arithmetic average of x and y using the following formula:\n///\n/// $$\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\n/// $$\n//\n/// In English, this is what this formula does:\n///\n/// 1. AND x and y.\n/// 2. Calculate half of XOR x and y.\n/// 3. Add the two results together.\n///\n/// This technique is known as SWAR, which stands for \"SIMD within a register\". You can read more about it here:\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The arithmetic average as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n    uint256 yUint = y.unwrap();\n    unchecked {\n        result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\n    }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\n///\n/// @param x The UD60x18 number to ceil.\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n    if (xUint > uMAX_WHOLE_UD60x18) {\n        revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\n    }\n\n    assembly (\"memory-safe\") {\n        // Equivalent to `x % UNIT`.\n        let remainder := mod(x, uUNIT)\n\n        // Equivalent to `UNIT - remainder`.\n        let delta := sub(uUNIT, remainder)\n\n        // Equivalent to `x + remainder > 0 ? delta : 0`.\n        result := add(x, mul(delta, gt(remainder, 0)))\n    }\n}\n\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @param x The numerator as a UD60x18 number.\n/// @param y The denominator as a UD60x18 number.\n/// @param result The quotient as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Requirements:\n/// - x must be less than 133_084258667509499441.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n\n    // This check prevents values greater than 192e18 from being passed to {exp2}.\n    if (xUint > uEXP_MAX_INPUT) {\n        revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\n    }\n\n    unchecked {\n        // Inline the fixed-point multiplication to save gas.\n        uint256 doubleUnitProduct = xUint * uLOG2_E;\n        result = exp2(wrap(doubleUnitProduct / uUNIT));\n    }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\n///\n/// Requirements:\n/// - x must be less than 192e18.\n/// - The result must fit in UD60x18.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n\n    // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n    if (xUint > uEXP2_MAX_INPUT) {\n        revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\n    }\n\n    // Convert x to the 192.64-bit fixed-point format.\n    uint256 x_192x64 = (xUint << 64) / uUNIT;\n\n    // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\n    result = wrap(Common.exp2(x_192x64));\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n/// @param x The UD60x18 number to floor.\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\n    assembly (\"memory-safe\") {\n        // Equivalent to `x % UNIT`.\n        let remainder := mod(x, uUNIT)\n\n        // Equivalent to `x - remainder > 0 ? remainder : 0)`.\n        result := sub(x, mul(remainder, gt(remainder, 0)))\n    }\n}\n\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\n/// @param x The UD60x18 number to get the fractional part of.\n/// @param result The fractional part of x as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\n    assembly (\"memory-safe\") {\n        result := mod(x, uUNIT)\n    }\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$, rounding down.\n///\n/// @dev Requirements:\n/// - x * y must fit in UD60x18.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n    uint256 yUint = y.unwrap();\n    if (xUint == 0 || yUint == 0) {\n        return ZERO;\n    }\n\n    unchecked {\n        // Checking for overflow this way is faster than letting Solidity do it.\n        uint256 xyUint = xUint * yUint;\n        if (xyUint / xUint != yUint) {\n            revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\n        }\n\n        // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n        // during multiplication. See the comments in {Common.sqrt}.\n        result = wrap(Common.sqrt(xyUint));\n    }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The UD60x18 number for which to calculate the inverse.\n/// @return result The inverse as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\n    unchecked {\n        result = wrap(uUNIT_SQUARED / x.unwrap());\n    }\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\n    unchecked {\n        // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n        // {log2} can return is ~196_205294292027477728.\n        result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n    }\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n    if (xUint < uUNIT) {\n        revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n    }\n\n    // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\n    // prettier-ignore\n    assembly (\"memory-safe\") {\n        switch x\n        case 1 { result := mul(uUNIT, sub(0, 18)) }\n        case 10 { result := mul(uUNIT, sub(1, 18)) }\n        case 100 { result := mul(uUNIT, sub(2, 18)) }\n        case 1000 { result := mul(uUNIT, sub(3, 18)) }\n        case 10000 { result := mul(uUNIT, sub(4, 18)) }\n        case 100000 { result := mul(uUNIT, sub(5, 18)) }\n        case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n        case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n        case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n        case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n        case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n        case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n        case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n        case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n        case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n        case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n        case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n        case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n        case 1000000000000000000 { result := 0 }\n        case 10000000000000000000 { result := uUNIT }\n        case 100000000000000000000 { result := mul(uUNIT, 2) }\n        case 1000000000000000000000 { result := mul(uUNIT, 3) }\n        case 10000000000000000000000 { result := mul(uUNIT, 4) }\n        case 100000000000000000000000 { result := mul(uUNIT, 5) }\n        case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n        case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n        case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n        case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n        case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n        case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n        case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n        case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n        case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n        case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n        case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n        case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n        case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n        case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n        case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n        case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n        case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n        case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n        case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n        case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n        case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n        case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n        case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n        case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n        case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n        case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n        case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n        case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n        case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n        case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n        case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n        case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n        case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n        case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n        case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n        case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n        case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n        case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n        case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n        case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n        case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n        case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n        case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n        case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n        case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n        case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n        case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n        case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n        case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n        case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n        case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n        case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n        case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n        case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\n        default { result := uMAX_UD60x18 }\n    }\n\n    if (result.unwrap() == uMAX_UD60x18) {\n        unchecked {\n            // Inline the fixed-point division to save gas.\n            result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n        }\n    }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x must be greater than zero.\n///\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n\n    if (xUint < uUNIT) {\n        revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n    }\n\n    unchecked {\n        // Calculate the integer part of the logarithm.\n        uint256 n = Common.msb(xUint / uUNIT);\n\n        // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\n        // n is at most 255 and UNIT is 1e18.\n        uint256 resultUint = n * uUNIT;\n\n        // Calculate $y = x * 2^{-n}$.\n        uint256 y = xUint >> n;\n\n        // If y is the unit number, the fractional part is zero.\n        if (y == uUNIT) {\n            return wrap(resultUint);\n        }\n\n        // Calculate the fractional part via the iterative approximation.\n        // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n        uint256 DOUBLE_UNIT = 2e18;\n        for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n            y = (y * y) / uUNIT;\n\n            // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n            if (y >= DOUBLE_UNIT) {\n                // Add the 2^{-m} factor to the logarithm.\n                resultUint += delta;\n\n                // Halve y, which corresponds to z/2 in the Wikipedia article.\n                y >>= 1;\n            }\n        }\n        result = wrap(resultUint);\n    }\n}\n\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @dev See the documentation in {Common.mulDiv18}.\n/// @param x The multiplicand as a UD60x18 number.\n/// @param y The multiplier as a UD60x18 number.\n/// @return result The product as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\n}\n\n/// @notice Raises x to the power of y.\n///\n/// For $1 \\leq x \\leq \\infty$, the following standard formula is used:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\n///\n/// $$\n/// i = \\frac{1}{x}\n/// w = 2^{log_2{i} * y}\n/// x^y = \\frac{1}{w}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2} and {mul}.\n/// - Returns `UNIT` for 0^0.\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n    uint256 yUint = y.unwrap();\n\n    // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n    if (xUint == 0) {\n        return yUint == 0 ? UNIT : ZERO;\n    }\n    // If x is `UNIT`, the result is always `UNIT`.\n    else if (xUint == uUNIT) {\n        return UNIT;\n    }\n\n    // If y is zero, the result is always `UNIT`.\n    if (yUint == 0) {\n        return UNIT;\n    }\n    // If y is `UNIT`, the result is always x.\n    else if (yUint == uUNIT) {\n        return x;\n    }\n\n    // If x is greater than `UNIT`, use the standard formula.\n    if (xUint > uUNIT) {\n        result = exp2(mul(log2(x), y));\n    }\n    // Conversely, if x is less than `UNIT`, use the equivalent formula.\n    else {\n        UD60x18 i = wrap(uUNIT_SQUARED / xUint);\n        UD60x18 w = exp2(mul(log2(i), y));\n        result = wrap(uUNIT_SQUARED / w.unwrap());\n    }\n}\n\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - The result must fit in UD60x18.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\n    // Calculate the first iteration of the loop in advance.\n    uint256 xUint = x.unwrap();\n    uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\n\n    // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n    for (y >>= 1; y > 0; y >>= 1) {\n        xUint = Common.mulDiv18(xUint, xUint);\n\n        // Equivalent to `y % 2 == 1`.\n        if (y & 1 > 0) {\n            resultUint = Common.mulDiv18(resultUint, xUint);\n        }\n    }\n    result = wrap(resultUint);\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must be less than `MAX_UD60x18 / UNIT`.\n///\n/// @param x The UD60x18 number for which to calculate the square root.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\n    uint256 xUint = x.unwrap();\n\n    unchecked {\n        if (xUint > uMAX_UD60x18 / uUNIT) {\n            revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\n        }\n        // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\n        // In this case, the two numbers are both the square root.\n        result = wrap(Common.sqrt(xUint * uUNIT));\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/ud60x18/ValueType.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\n/// @dev The value type is defined here so it can be imported in all other files.\ntype UD60x18 is uint256;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n    Casting.intoSD1x18,\n    Casting.intoUD2x18,\n    Casting.intoSD59x18,\n    Casting.intoUint128,\n    Casting.intoUint256,\n    Casting.intoUint40,\n    Casting.unwrap\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n                            MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n    Math.avg,\n    Math.ceil,\n    Math.div,\n    Math.exp,\n    Math.exp2,\n    Math.floor,\n    Math.frac,\n    Math.gm,\n    Math.inv,\n    Math.ln,\n    Math.log10,\n    Math.log2,\n    Math.mul,\n    Math.pow,\n    Math.powu,\n    Math.sqrt\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n    Helpers.add,\n    Helpers.and,\n    Helpers.eq,\n    Helpers.gt,\n    Helpers.gte,\n    Helpers.isZero,\n    Helpers.lshift,\n    Helpers.lt,\n    Helpers.lte,\n    Helpers.mod,\n    Helpers.neq,\n    Helpers.not,\n    Helpers.or,\n    Helpers.rshift,\n    Helpers.sub,\n    Helpers.uncheckedAdd,\n    Helpers.uncheckedSub,\n    Helpers.xor\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the UD60x18 type.\nusing {\n    Helpers.add as +,\n    Helpers.and2 as &,\n    Math.div as /,\n    Helpers.eq as ==,\n    Helpers.gt as >,\n    Helpers.gte as >=,\n    Helpers.lt as <,\n    Helpers.lte as <=,\n    Helpers.or as |,\n    Helpers.mod as %,\n    Math.mul as *,\n    Helpers.neq as !=,\n    Helpers.not as ~,\n    Helpers.sub as -,\n    Helpers.xor as ^\n} for UD60x18 global;\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/rain.math.fixedpoint/src/lib/FixedPointDecimalConstants.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// @dev The scale of all fixed point math. This is adopting the conventions of\n/// both ETH (wei) and most ERC20 tokens, so is hopefully uncontroversial.\nuint256 constant FIXED_POINT_DECIMALS = 18;\n\n/// @dev Value of \"one\" for fixed point math.\nuint256 constant FIXED_POINT_ONE = 1e18;\n\n/// @dev Calculations MUST round up.\nuint256 constant FLAG_ROUND_UP = 1;\n\n/// @dev Calculations MUST saturate NOT overflow.\nuint256 constant FLAG_SATURATE = 1 << 1;\n\n/// @dev Flags MUST NOT exceed this value.\nuint256 constant FLAG_MAX_INT = FLAG_SATURATE | FLAG_ROUND_UP;\n\n/// @dev Can't represent this many OOMs of decimals in `uint256`.\nuint256 constant OVERFLOW_RESCALE_OOMS = 78;\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/v2-core/contracts/interfaces/IUniswapV2Pair.sol": {
        "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Pair {\n    event Approval(address indexed owner, address indexed spender, uint value);\n    event Transfer(address indexed from, address indexed to, uint value);\n\n    function name() external pure returns (string memory);\n    function symbol() external pure returns (string memory);\n    function decimals() external pure returns (uint8);\n    function totalSupply() external view returns (uint);\n    function balanceOf(address owner) external view returns (uint);\n    function allowance(address owner, address spender) external view returns (uint);\n\n    function approve(address spender, uint value) external returns (bool);\n    function transfer(address to, uint value) external returns (bool);\n    function transferFrom(address from, address to, uint value) external returns (bool);\n\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n    function PERMIT_TYPEHASH() external pure returns (bytes32);\n    function nonces(address owner) external view returns (uint);\n\n    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n    event Mint(address indexed sender, uint amount0, uint amount1);\n    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);\n    event Swap(\n        address indexed sender,\n        uint amount0In,\n        uint amount1In,\n        uint amount0Out,\n        uint amount1Out,\n        address indexed to\n    );\n    event Sync(uint112 reserve0, uint112 reserve1);\n\n    function MINIMUM_LIQUIDITY() external pure returns (uint);\n    function factory() external view returns (address);\n    function token0() external view returns (address);\n    function token1() external view returns (address);\n    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n    function price0CumulativeLast() external view returns (uint);\n    function price1CumulativeLast() external view returns (uint);\n    function kLast() external view returns (uint);\n\n    function mint(address to) external returns (uint liquidity);\n    function burn(address to) external returns (uint amount0, uint amount1);\n    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n    function skim(address to) external;\n    function sync() external;\n\n    function initialize(address, address) external;\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/v2-core/contracts/interfaces/IUniswapV2Factory.sol": {
        "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Factory {\n    event PairCreated(address indexed token0, address indexed token1, address pair, uint);\n\n    function feeTo() external view returns (address);\n    function feeToSetter() external view returns (address);\n\n    function getPair(address tokenA, address tokenB) external view returns (address pair);\n    function allPairs(uint) external view returns (address pair);\n    function allPairsLength() external view returns (uint);\n\n    function createPair(address tokenA, address tokenB) external returns (address pair);\n\n    function setFeeTo(address) external;\n    function setFeeToSetter(address) external;\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/Common.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n// Common.sol\n//\n// Common mathematical functions needed by both SD59x18 and UD60x18. Note that these global functions do not\n// always operate with SD59x18 and UD60x18 numbers.\n\n/*//////////////////////////////////////////////////////////////////////////\n                                CUSTOM ERRORS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\n\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\n\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\nerror PRBMath_MulDivSigned_InputTooSmall();\n\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    CONSTANTS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @dev The maximum value a uint128 number can have.\nuint128 constant MAX_UINT128 = type(uint128).max;\n\n/// @dev The maximum value a uint40 number can have.\nuint40 constant MAX_UINT40 = type(uint40).max;\n\n/// @dev The unit number, which the decimal precision of the fixed-point types.\nuint256 constant UNIT = 1e18;\n\n/// @dev The unit number inverted mod 2^256.\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\n\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\n/// bit in the binary representation of `UNIT`.\nuint256 constant UNIT_LPOTD = 262144;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(uint256 x) pure returns (uint256 result) {\n    unchecked {\n        // Start from 0.5 in the 192.64-bit fixed-point format.\n        result = 0x800000000000000000000000000000000000000000000000;\n\n        // The following logic multiplies the result by $\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\n        //\n        // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\n        // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\n        // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\n        // we know that `x & 0xFF` is also 1.\n        if (x & 0xFF00000000000000 > 0) {\n            if (x & 0x8000000000000000 > 0) {\n                result = (result * 0x16A09E667F3BCC909) >> 64;\n            }\n            if (x & 0x4000000000000000 > 0) {\n                result = (result * 0x1306FE0A31B7152DF) >> 64;\n            }\n            if (x & 0x2000000000000000 > 0) {\n                result = (result * 0x1172B83C7D517ADCE) >> 64;\n            }\n            if (x & 0x1000000000000000 > 0) {\n                result = (result * 0x10B5586CF9890F62A) >> 64;\n            }\n            if (x & 0x800000000000000 > 0) {\n                result = (result * 0x1059B0D31585743AE) >> 64;\n            }\n            if (x & 0x400000000000000 > 0) {\n                result = (result * 0x102C9A3E778060EE7) >> 64;\n            }\n            if (x & 0x200000000000000 > 0) {\n                result = (result * 0x10163DA9FB33356D8) >> 64;\n            }\n            if (x & 0x100000000000000 > 0) {\n                result = (result * 0x100B1AFA5ABCBED61) >> 64;\n            }\n        }\n\n        if (x & 0xFF000000000000 > 0) {\n            if (x & 0x80000000000000 > 0) {\n                result = (result * 0x10058C86DA1C09EA2) >> 64;\n            }\n            if (x & 0x40000000000000 > 0) {\n                result = (result * 0x1002C605E2E8CEC50) >> 64;\n            }\n            if (x & 0x20000000000000 > 0) {\n                result = (result * 0x100162F3904051FA1) >> 64;\n            }\n            if (x & 0x10000000000000 > 0) {\n                result = (result * 0x1000B175EFFDC76BA) >> 64;\n            }\n            if (x & 0x8000000000000 > 0) {\n                result = (result * 0x100058BA01FB9F96D) >> 64;\n            }\n            if (x & 0x4000000000000 > 0) {\n                result = (result * 0x10002C5CC37DA9492) >> 64;\n            }\n            if (x & 0x2000000000000 > 0) {\n                result = (result * 0x1000162E525EE0547) >> 64;\n            }\n            if (x & 0x1000000000000 > 0) {\n                result = (result * 0x10000B17255775C04) >> 64;\n            }\n        }\n\n        if (x & 0xFF0000000000 > 0) {\n            if (x & 0x800000000000 > 0) {\n                result = (result * 0x1000058B91B5BC9AE) >> 64;\n            }\n            if (x & 0x400000000000 > 0) {\n                result = (result * 0x100002C5C89D5EC6D) >> 64;\n            }\n            if (x & 0x200000000000 > 0) {\n                result = (result * 0x10000162E43F4F831) >> 64;\n            }\n            if (x & 0x100000000000 > 0) {\n                result = (result * 0x100000B1721BCFC9A) >> 64;\n            }\n            if (x & 0x80000000000 > 0) {\n                result = (result * 0x10000058B90CF1E6E) >> 64;\n            }\n            if (x & 0x40000000000 > 0) {\n                result = (result * 0x1000002C5C863B73F) >> 64;\n            }\n            if (x & 0x20000000000 > 0) {\n                result = (result * 0x100000162E430E5A2) >> 64;\n            }\n            if (x & 0x10000000000 > 0) {\n                result = (result * 0x1000000B172183551) >> 64;\n            }\n        }\n\n        if (x & 0xFF00000000 > 0) {\n            if (x & 0x8000000000 > 0) {\n                result = (result * 0x100000058B90C0B49) >> 64;\n            }\n            if (x & 0x4000000000 > 0) {\n                result = (result * 0x10000002C5C8601CC) >> 64;\n            }\n            if (x & 0x2000000000 > 0) {\n                result = (result * 0x1000000162E42FFF0) >> 64;\n            }\n            if (x & 0x1000000000 > 0) {\n                result = (result * 0x10000000B17217FBB) >> 64;\n            }\n            if (x & 0x800000000 > 0) {\n                result = (result * 0x1000000058B90BFCE) >> 64;\n            }\n            if (x & 0x400000000 > 0) {\n                result = (result * 0x100000002C5C85FE3) >> 64;\n            }\n            if (x & 0x200000000 > 0) {\n                result = (result * 0x10000000162E42FF1) >> 64;\n            }\n            if (x & 0x100000000 > 0) {\n                result = (result * 0x100000000B17217F8) >> 64;\n            }\n        }\n\n        if (x & 0xFF000000 > 0) {\n            if (x & 0x80000000 > 0) {\n                result = (result * 0x10000000058B90BFC) >> 64;\n            }\n            if (x & 0x40000000 > 0) {\n                result = (result * 0x1000000002C5C85FE) >> 64;\n            }\n            if (x & 0x20000000 > 0) {\n                result = (result * 0x100000000162E42FF) >> 64;\n            }\n            if (x & 0x10000000 > 0) {\n                result = (result * 0x1000000000B17217F) >> 64;\n            }\n            if (x & 0x8000000 > 0) {\n                result = (result * 0x100000000058B90C0) >> 64;\n            }\n            if (x & 0x4000000 > 0) {\n                result = (result * 0x10000000002C5C860) >> 64;\n            }\n            if (x & 0x2000000 > 0) {\n                result = (result * 0x1000000000162E430) >> 64;\n            }\n            if (x & 0x1000000 > 0) {\n                result = (result * 0x10000000000B17218) >> 64;\n            }\n        }\n\n        if (x & 0xFF0000 > 0) {\n            if (x & 0x800000 > 0) {\n                result = (result * 0x1000000000058B90C) >> 64;\n            }\n            if (x & 0x400000 > 0) {\n                result = (result * 0x100000000002C5C86) >> 64;\n            }\n            if (x & 0x200000 > 0) {\n                result = (result * 0x10000000000162E43) >> 64;\n            }\n            if (x & 0x100000 > 0) {\n                result = (result * 0x100000000000B1721) >> 64;\n            }\n            if (x & 0x80000 > 0) {\n                result = (result * 0x10000000000058B91) >> 64;\n            }\n            if (x & 0x40000 > 0) {\n                result = (result * 0x1000000000002C5C8) >> 64;\n            }\n            if (x & 0x20000 > 0) {\n                result = (result * 0x100000000000162E4) >> 64;\n            }\n            if (x & 0x10000 > 0) {\n                result = (result * 0x1000000000000B172) >> 64;\n            }\n        }\n\n        if (x & 0xFF00 > 0) {\n            if (x & 0x8000 > 0) {\n                result = (result * 0x100000000000058B9) >> 64;\n            }\n            if (x & 0x4000 > 0) {\n                result = (result * 0x10000000000002C5D) >> 64;\n            }\n            if (x & 0x2000 > 0) {\n                result = (result * 0x1000000000000162E) >> 64;\n            }\n            if (x & 0x1000 > 0) {\n                result = (result * 0x10000000000000B17) >> 64;\n            }\n            if (x & 0x800 > 0) {\n                result = (result * 0x1000000000000058C) >> 64;\n            }\n            if (x & 0x400 > 0) {\n                result = (result * 0x100000000000002C6) >> 64;\n            }\n            if (x & 0x200 > 0) {\n                result = (result * 0x10000000000000163) >> 64;\n            }\n            if (x & 0x100 > 0) {\n                result = (result * 0x100000000000000B1) >> 64;\n            }\n        }\n\n        if (x & 0xFF > 0) {\n            if (x & 0x80 > 0) {\n                result = (result * 0x10000000000000059) >> 64;\n            }\n            if (x & 0x40 > 0) {\n                result = (result * 0x1000000000000002C) >> 64;\n            }\n            if (x & 0x20 > 0) {\n                result = (result * 0x10000000000000016) >> 64;\n            }\n            if (x & 0x10 > 0) {\n                result = (result * 0x1000000000000000B) >> 64;\n            }\n            if (x & 0x8 > 0) {\n                result = (result * 0x10000000000000006) >> 64;\n            }\n            if (x & 0x4 > 0) {\n                result = (result * 0x10000000000000003) >> 64;\n            }\n            if (x & 0x2 > 0) {\n                result = (result * 0x10000000000000001) >> 64;\n            }\n            if (x & 0x1 > 0) {\n                result = (result * 0x10000000000000001) >> 64;\n            }\n        }\n\n        // In the code snippet below, two operations are executed simultaneously:\n        //\n        // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\n        // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\n        // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\n        //\n        // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\n        // integer part, $2^n$.\n        result *= UNIT;\n        result >>= (191 - (x >> 64));\n    }\n}\n\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\n///\n/// @dev See the note on \"msb\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\n///\n/// Each step in this implementation is equivalent to this high-level code:\n///\n/// ```solidity\n/// if (x >= 2 ** 128) {\n///     x >>= 128;\n///     result += 128;\n/// }\n/// ```\n///\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\n///\n/// The Yul instructions used below are:\n///\n/// - \"gt\" is \"greater than\"\n/// - \"or\" is the OR bitwise operator\n/// - \"shl\" is \"shift left\"\n/// - \"shr\" is \"shift right\"\n///\n/// @param x The uint256 number for which to find the index of the most significant bit.\n/// @return result The index of the most significant bit as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction msb(uint256 x) pure returns (uint256 result) {\n    // 2^128\n    assembly (\"memory-safe\") {\n        let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^64\n    assembly (\"memory-safe\") {\n        let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^32\n    assembly (\"memory-safe\") {\n        let factor := shl(5, gt(x, 0xFFFFFFFF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^16\n    assembly (\"memory-safe\") {\n        let factor := shl(4, gt(x, 0xFFFF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^8\n    assembly (\"memory-safe\") {\n        let factor := shl(3, gt(x, 0xFF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^4\n    assembly (\"memory-safe\") {\n        let factor := shl(2, gt(x, 0xF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^2\n    assembly (\"memory-safe\") {\n        let factor := shl(1, gt(x, 0x3))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^1\n    // No need to shift x any more.\n    assembly (\"memory-safe\") {\n        let factor := gt(x, 0x1)\n        result := or(result, factor)\n    }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - The denominator must not be zero.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as a uint256.\n/// @param y The multiplier as a uint256.\n/// @param denominator The divisor as a uint256.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\n    // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n    // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\n    // variables such that product = prod1 * 2^256 + prod0.\n    uint256 prod0; // Least significant 256 bits of the product\n    uint256 prod1; // Most significant 256 bits of the product\n    assembly (\"memory-safe\") {\n        let mm := mulmod(x, y, not(0))\n        prod0 := mul(x, y)\n        prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n    }\n\n    // Handle non-overflow cases, 256 by 256 division.\n    if (prod1 == 0) {\n        unchecked {\n            return prod0 / denominator;\n        }\n    }\n\n    // Make sure the result is less than 2^256. Also prevents denominator == 0.\n    if (prod1 >= denominator) {\n        revert PRBMath_MulDiv_Overflow(x, y, denominator);\n    }\n\n    ////////////////////////////////////////////////////////////////////////////\n    // 512 by 256 division\n    ////////////////////////////////////////////////////////////////////////////\n\n    // Make division exact by subtracting the remainder from [prod1 prod0].\n    uint256 remainder;\n    assembly (\"memory-safe\") {\n        // Compute remainder using the mulmod Yul instruction.\n        remainder := mulmod(x, y, denominator)\n\n        // Subtract 256 bit number from 512-bit number.\n        prod1 := sub(prod1, gt(remainder, prod0))\n        prod0 := sub(prod0, remainder)\n    }\n\n    unchecked {\n        // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\n        // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\n        // For more detail, see https://cs.stackexchange.com/q/138556/92363.\n        uint256 lpotdod = denominator & (~denominator + 1);\n        uint256 flippedLpotdod;\n\n        assembly (\"memory-safe\") {\n            // Factor powers of two out of denominator.\n            denominator := div(denominator, lpotdod)\n\n            // Divide [prod1 prod0] by lpotdod.\n            prod0 := div(prod0, lpotdod)\n\n            // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\n            // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\n            // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\n            flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\n        }\n\n        // Shift in bits from prod1 into prod0.\n        prod0 |= prod1 * flippedLpotdod;\n\n        // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n        // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n        // four bits. That is, denominator * inv = 1 mod 2^4.\n        uint256 inverse = (3 * denominator) ^ 2;\n\n        // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n        // in modular arithmetic, doubling the correct bits in each step.\n        inverse *= 2 - denominator * inverse; // inverse mod 2^8\n        inverse *= 2 - denominator * inverse; // inverse mod 2^16\n        inverse *= 2 - denominator * inverse; // inverse mod 2^32\n        inverse *= 2 - denominator * inverse; // inverse mod 2^64\n        inverse *= 2 - denominator * inverse; // inverse mod 2^128\n        inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n        // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n        // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n        // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n        // is no longer required.\n        result = prod0 * inverse;\n    }\n}\n\n/// @notice Calculates x*y÷1e18 with 512-bit precision.\n///\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\n///\n/// Notes:\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\n/// - The result is rounded toward zero.\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\n///\n/// $$\n/// \\begin{cases}\n///     x * y = MAX\\_UINT256 * UNIT \\\\\n///     (x * y) \\% UNIT \\geq \\frac{UNIT}{2}\n/// \\end{cases}\n/// $$\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\n    uint256 prod0;\n    uint256 prod1;\n    assembly (\"memory-safe\") {\n        let mm := mulmod(x, y, not(0))\n        prod0 := mul(x, y)\n        prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n    }\n\n    if (prod1 == 0) {\n        unchecked {\n            return prod0 / UNIT;\n        }\n    }\n\n    if (prod1 >= UNIT) {\n        revert PRBMath_MulDiv18_Overflow(x, y);\n    }\n\n    uint256 remainder;\n    assembly (\"memory-safe\") {\n        remainder := mulmod(x, y, UNIT)\n        result :=\n            mul(\n                or(\n                    div(sub(prod0, remainder), UNIT_LPOTD),\n                    mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\n                ),\n                UNIT_INVERSE\n            )\n    }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - None of the inputs can be `type(int256).min`.\n/// - The result must fit in int256.\n///\n/// @param x The multiplicand as an int256.\n/// @param y The multiplier as an int256.\n/// @param denominator The divisor as an int256.\n/// @return result The result as an int256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\n    if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\n        revert PRBMath_MulDivSigned_InputTooSmall();\n    }\n\n    // Get hold of the absolute values of x, y and the denominator.\n    uint256 xAbs;\n    uint256 yAbs;\n    uint256 dAbs;\n    unchecked {\n        xAbs = x < 0 ? uint256(-x) : uint256(x);\n        yAbs = y < 0 ? uint256(-y) : uint256(y);\n        dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\n    }\n\n    // Compute the absolute value of x*y÷denominator. The result must fit in int256.\n    uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\n    if (resultAbs > uint256(type(int256).max)) {\n        revert PRBMath_MulDivSigned_Overflow(x, y);\n    }\n\n    // Get the signs of x, y and the denominator.\n    uint256 sx;\n    uint256 sy;\n    uint256 sd;\n    assembly (\"memory-safe\") {\n        // \"sgt\" is the \"signed greater than\" assembly instruction and \"sub(0,1)\" is -1 in two's complement.\n        sx := sgt(x, sub(0, 1))\n        sy := sgt(y, sub(0, 1))\n        sd := sgt(denominator, sub(0, 1))\n    }\n\n    // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\n    // If there are, the result should be negative. Otherwise, it should be positive.\n    unchecked {\n        result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\n    }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - If x is not a perfect square, the result is rounded down.\n/// - Credits to OpenZeppelin for the explanations in comments below.\n///\n/// @param x The uint256 number for which to calculate the square root.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(uint256 x) pure returns (uint256 result) {\n    if (x == 0) {\n        return 0;\n    }\n\n    // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\n    //\n    // We know that the \"msb\" (most significant bit) of x is a power of 2 such that we have:\n    //\n    // $$\n    // msb(x) <= x <= 2*msb(x)$\n    // $$\n    //\n    // We write $msb(x)$ as $2^k$, and we get:\n    //\n    // $$\n    // k = log_2(x)\n    // $$\n    //\n    // Thus, we can write the initial inequality as:\n    //\n    // $$\n    // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\n    // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\n    // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\n    // $$\n    //\n    // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\n    uint256 xAux = uint256(x);\n    result = 1;\n    if (xAux >= 2 ** 128) {\n        xAux >>= 128;\n        result <<= 64;\n    }\n    if (xAux >= 2 ** 64) {\n        xAux >>= 64;\n        result <<= 32;\n    }\n    if (xAux >= 2 ** 32) {\n        xAux >>= 32;\n        result <<= 16;\n    }\n    if (xAux >= 2 ** 16) {\n        xAux >>= 16;\n        result <<= 8;\n    }\n    if (xAux >= 2 ** 8) {\n        xAux >>= 8;\n        result <<= 4;\n    }\n    if (xAux >= 2 ** 4) {\n        xAux >>= 4;\n        result <<= 2;\n    }\n    if (xAux >= 2 ** 2) {\n        result <<= 1;\n    }\n\n    // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\n    // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\n    // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\n    // precision into the expected uint128 result.\n    unchecked {\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n\n        // If x is not a perfect square, round the result toward zero.\n        uint256 roundedResult = x / result;\n        if (result >= roundedResult) {\n            result = roundedResult;\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/sd1x18/Constants.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as an SD1x18 number.\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\n\n/// @dev PI as an SD1x18 number.\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD1x18.\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\nint256 constant uUNIT = 1e18;\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/sd1x18/ValueType.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype SD1x18 is int64;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n    Casting.intoSD59x18,\n    Casting.intoUD2x18,\n    Casting.intoUD60x18,\n    Casting.intoUint256,\n    Casting.intoUint128,\n    Casting.intoUint40,\n    Casting.unwrap\n} for SD1x18 global;\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/sd59x18/Constants.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as an SD59x18 number.\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev The maximum input permitted in {exp2}.\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Half the UNIT number.\nint256 constant uHALF_UNIT = 0.5e18;\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as an SD59x18 number.\nint256 constant uLOG2_10 = 3_321928094887362347;\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as an SD59x18 number.\nint256 constant uLOG2_E = 1_442695040888963407;\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\n\n/// @dev The maximum value an SD59x18 number can have.\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\n\n/// @dev The maximum whole value an SD59x18 number can have.\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\n\n/// @dev The minimum value an SD59x18 number can have.\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\n\n/// @dev The minimum whole value an SD59x18 number can have.\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\n\n/// @dev PI as an SD59x18 number.\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD59x18.\nint256 constant uUNIT = 1e18;\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\n\n/// @dev The unit number squared.\nint256 constant uUNIT_SQUARED = 1e36;\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as an SD59x18 number.\nSD59x18 constant ZERO = SD59x18.wrap(0);\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/sd59x18/ValueType.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int256.\ntype SD59x18 is int256;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n    Casting.intoInt256,\n    Casting.intoSD1x18,\n    Casting.intoUD2x18,\n    Casting.intoUD60x18,\n    Casting.intoUint256,\n    Casting.intoUint128,\n    Casting.intoUint40,\n    Casting.unwrap\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n                            MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n    Math.abs,\n    Math.avg,\n    Math.ceil,\n    Math.div,\n    Math.exp,\n    Math.exp2,\n    Math.floor,\n    Math.frac,\n    Math.gm,\n    Math.inv,\n    Math.log10,\n    Math.log2,\n    Math.ln,\n    Math.mul,\n    Math.pow,\n    Math.powu,\n    Math.sqrt\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n    Helpers.add,\n    Helpers.and,\n    Helpers.eq,\n    Helpers.gt,\n    Helpers.gte,\n    Helpers.isZero,\n    Helpers.lshift,\n    Helpers.lt,\n    Helpers.lte,\n    Helpers.mod,\n    Helpers.neq,\n    Helpers.not,\n    Helpers.or,\n    Helpers.rshift,\n    Helpers.sub,\n    Helpers.uncheckedAdd,\n    Helpers.uncheckedSub,\n    Helpers.uncheckedUnary,\n    Helpers.xor\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the SD59x18 type.\nusing {\n    Helpers.add as +,\n    Helpers.and2 as &,\n    Math.div as /,\n    Helpers.eq as ==,\n    Helpers.gt as >,\n    Helpers.gte as >=,\n    Helpers.lt as <,\n    Helpers.lte as <=,\n    Helpers.mod as %,\n    Math.mul as *,\n    Helpers.neq as !=,\n    Helpers.not as ~,\n    Helpers.or as |,\n    Helpers.sub as -,\n    Helpers.unary as -,\n    Helpers.xor as ^\n} for SD59x18 global;\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/ud2x18/Constants.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as a UD2x18 number.\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value a UD2x18 number can have.\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\n\n/// @dev PI as a UD2x18 number.\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD2x18.\nuint256 constant uUNIT = 1e18;\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/ud2x18/ValueType.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype UD2x18 is uint64;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n    Casting.intoSD1x18,\n    Casting.intoSD59x18,\n    Casting.intoUD60x18,\n    Casting.intoUint256,\n    Casting.intoUint128,\n    Casting.intoUint40,\n    Casting.unwrap\n} for UD2x18 global;\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/sd1x18/Casting.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as CastingErrors;\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD1x18 number into SD59x18.\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\n    result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\n}\n\n/// @notice Casts an SD1x18 number into UD2x18.\n/// - x must be positive.\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\n    int64 xInt = SD1x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\n    }\n    result = UD2x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into UD60x18.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\n    int64 xInt = SD1x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\n    }\n    result = UD60x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint256.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\n    int64 xInt = SD1x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\n    }\n    result = uint256(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint128.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\n    int64 xInt = SD1x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\n    }\n    result = uint128(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint40.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\n    int64 xInt = SD1x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\n    }\n    if (xInt > int64(uint64(Common.MAX_UINT40))) {\n        revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\n    }\n    result = uint40(uint64(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\n    result = SD1x18.wrap(x);\n}\n\n/// @notice Unwraps an SD1x18 number into int64.\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\n    result = SD1x18.unwrap(x);\n}\n\n/// @notice Wraps an int64 number into SD1x18.\nfunction wrap(int64 x) pure returns (SD1x18 result) {\n    result = SD1x18.wrap(x);\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/sd59x18/Casting.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD59x18 number into int256.\n/// @dev This is basically a functional alias for {unwrap}.\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\n    result = SD59x18.unwrap(x);\n}\n\n/// @notice Casts an SD59x18 number into SD1x18.\n/// @dev Requirements:\n/// - x must be greater than or equal to `uMIN_SD1x18`.\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\n    int256 xInt = SD59x18.unwrap(x);\n    if (xInt < uMIN_SD1x18) {\n        revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\n    }\n    if (xInt > uMAX_SD1x18) {\n        revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\n    }\n    result = SD1x18.wrap(int64(xInt));\n}\n\n/// @notice Casts an SD59x18 number into UD2x18.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `uMAX_UD2x18`.\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\n    int256 xInt = SD59x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\n    }\n    if (xInt > int256(uint256(uMAX_UD2x18))) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\n    }\n    result = UD2x18.wrap(uint64(uint256(xInt)));\n}\n\n/// @notice Casts an SD59x18 number into UD60x18.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\n    int256 xInt = SD59x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\n    }\n    result = UD60x18.wrap(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint256.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\n    int256 xInt = SD59x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\n    }\n    result = uint256(xInt);\n}\n\n/// @notice Casts an SD59x18 number into uint128.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `uMAX_UINT128`.\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\n    int256 xInt = SD59x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\n    }\n    if (xInt > int256(uint256(MAX_UINT128))) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\n    }\n    result = uint128(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint40.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\n    int256 xInt = SD59x18.unwrap(x);\n    if (xInt < 0) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\n    }\n    if (xInt > int256(uint256(MAX_UINT40))) {\n        revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\n    }\n    result = uint40(uint256(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd(int256 x) pure returns (SD59x18 result) {\n    result = SD59x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\n    result = SD59x18.wrap(x);\n}\n\n/// @notice Unwraps an SD59x18 number into int256.\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\n    result = SD59x18.unwrap(x);\n}\n\n/// @notice Wraps an int256 number into SD59x18.\nfunction wrap(int256 x) pure returns (SD59x18 result) {\n    result = SD59x18.wrap(x);\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/sd59x18/Helpers.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    return wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\n    return wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    return wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal (=) operation in the SD59x18 type.\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n    result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n    result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n    result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the SD59x18 type.\nfunction isZero(SD59x18 x) pure returns (bool result) {\n    result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n    result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n    result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n    result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n    result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\n    result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n    result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\n    result = wrap(-x.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    unchecked {\n        result = wrap(x.unwrap() + y.unwrap());\n    }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    unchecked {\n        result = wrap(x.unwrap() - y.unwrap());\n    }\n}\n\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\n    unchecked {\n        result = wrap(-x.unwrap());\n    }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    result = wrap(x.unwrap() ^ y.unwrap());\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/sd59x18/Math.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport {\n    uEXP_MAX_INPUT,\n    uEXP2_MAX_INPUT,\n    uHALF_UNIT,\n    uLOG2_10,\n    uLOG2_E,\n    uMAX_SD59x18,\n    uMAX_WHOLE_SD59x18,\n    uMIN_SD59x18,\n    uMIN_WHOLE_SD59x18,\n    UNIT,\n    uUNIT,\n    uUNIT_SQUARED,\n    ZERO\n} from \"./Constants.sol\";\nimport { wrap } from \"./Helpers.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Calculates the absolute value of x.\n///\n/// @dev Requirements:\n/// - x must be greater than `MIN_SD59x18`.\n///\n/// @param x The SD59x18 number for which to calculate the absolute value.\n/// @param result The absolute value of x as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    if (xInt == uMIN_SD59x18) {\n        revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\n    }\n    result = xInt < 0 ? wrap(-xInt) : x;\n}\n\n/// @notice Calculates the arithmetic average of x and y.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The arithmetic average as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    int256 yInt = y.unwrap();\n\n    unchecked {\n        // This operation is equivalent to `x / 2 +  y / 2`, and it can never overflow.\n        int256 sum = (xInt >> 1) + (yInt >> 1);\n\n        if (sum < 0) {\n            // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\n            // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\n            assembly (\"memory-safe\") {\n                result := add(sum, and(or(xInt, yInt), 1))\n            }\n        } else {\n            // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\n            result = wrap(sum + (xInt & yInt & 1));\n        }\n    }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\n///\n/// @param x The SD59x18 number to ceil.\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    if (xInt > uMAX_WHOLE_SD59x18) {\n        revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\n    }\n\n    int256 remainder = xInt % uUNIT;\n    if (remainder == 0) {\n        result = x;\n    } else {\n        unchecked {\n            // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n            int256 resultInt = xInt - remainder;\n            if (xInt > 0) {\n                resultInt += uUNIT;\n            }\n            result = wrap(resultInt);\n        }\n    }\n}\n\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\n///\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\n/// values separately.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The denominator must not be zero.\n/// - The result must fit in SD59x18.\n///\n/// @param x The numerator as an SD59x18 number.\n/// @param y The denominator as an SD59x18 number.\n/// @param result The quotient as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    int256 yInt = y.unwrap();\n    if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n        revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\n    }\n\n    // Get hold of the absolute values of x and y.\n    uint256 xAbs;\n    uint256 yAbs;\n    unchecked {\n        xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n        yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n    }\n\n    // Compute the absolute value (x*UNIT÷y). The resulting value must fit in SD59x18.\n    uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\n    if (resultAbs > uint256(uMAX_SD59x18)) {\n        revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\n    }\n\n    // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n    // negative, 0 for positive or zero).\n    bool sameSign = (xInt ^ yInt) > -1;\n\n    // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n    unchecked {\n        result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n    }\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}.\n/// - x must be less than 133_084258667509499441.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n\n    // This check prevents values greater than 192e18 from being passed to {exp2}.\n    if (xInt > uEXP_MAX_INPUT) {\n        revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\n    }\n\n    unchecked {\n        // Inline the fixed-point multiplication to save gas.\n        int256 doubleUnitProduct = xInt * uLOG2_E;\n        result = exp2(wrap(doubleUnitProduct / uUNIT));\n    }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\n///\n/// $$\n/// 2^{-x} = \\frac{1}{2^x}\n/// $$\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\n///\n/// Notes:\n/// - If x is less than -59_794705707972522261, the result is zero.\n///\n/// Requirements:\n/// - x must be less than 192e18.\n/// - The result must fit in SD59x18.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    if (xInt < 0) {\n        // The inverse of any number less than this is truncated to zero.\n        if (xInt < -59_794705707972522261) {\n            return ZERO;\n        }\n\n        unchecked {\n            // Inline the fixed-point inversion to save gas.\n            result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\n        }\n    } else {\n        // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n        if (xInt > uEXP2_MAX_INPUT) {\n            revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\n        }\n\n        unchecked {\n            // Convert x to the 192.64-bit fixed-point format.\n            uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\n\n            // It is safe to cast the result to int256 due to the checks above.\n            result = wrap(int256(Common.exp2(x_192x64)));\n        }\n    }\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\n///\n/// @param x The SD59x18 number to floor.\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    if (xInt < uMIN_WHOLE_SD59x18) {\n        revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\n    }\n\n    int256 remainder = xInt % uUNIT;\n    if (remainder == 0) {\n        result = x;\n    } else {\n        unchecked {\n            // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n            int256 resultInt = xInt - remainder;\n            if (xInt < 0) {\n                resultInt -= uUNIT;\n            }\n            result = wrap(resultInt);\n        }\n    }\n}\n\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\n/// of the radix point for negative numbers.\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\n/// @param x The SD59x18 number to get the fractional part of.\n/// @param result The fractional part of x as an SD59x18 number.\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\n    result = wrap(x.unwrap() % uUNIT);\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x * y must fit in SD59x18.\n/// - x * y must not be negative, since complex numbers are not supported.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    int256 yInt = y.unwrap();\n    if (xInt == 0 || yInt == 0) {\n        return ZERO;\n    }\n\n    unchecked {\n        // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\n        int256 xyInt = xInt * yInt;\n        if (xyInt / xInt != yInt) {\n            revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\n        }\n\n        // The product must not be negative, since complex numbers are not supported.\n        if (xyInt < 0) {\n            revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\n        }\n\n        // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n        // during multiplication. See the comments in {Common.sqrt}.\n        uint256 resultUint = Common.sqrt(uint256(xyInt));\n        result = wrap(int256(resultUint));\n    }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The SD59x18 number for which to calculate the inverse.\n/// @return result The inverse as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\n    result = wrap(uUNIT_SQUARED / x.unwrap());\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\n    // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n    // {log2} can return is ~195_205294292027477728.\n    result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    if (xInt < 0) {\n        revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n    }\n\n    // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\n    // prettier-ignore\n    assembly (\"memory-safe\") {\n        switch x\n        case 1 { result := mul(uUNIT, sub(0, 18)) }\n        case 10 { result := mul(uUNIT, sub(1, 18)) }\n        case 100 { result := mul(uUNIT, sub(2, 18)) }\n        case 1000 { result := mul(uUNIT, sub(3, 18)) }\n        case 10000 { result := mul(uUNIT, sub(4, 18)) }\n        case 100000 { result := mul(uUNIT, sub(5, 18)) }\n        case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n        case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n        case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n        case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n        case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n        case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n        case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n        case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n        case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n        case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n        case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n        case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n        case 1000000000000000000 { result := 0 }\n        case 10000000000000000000 { result := uUNIT }\n        case 100000000000000000000 { result := mul(uUNIT, 2) }\n        case 1000000000000000000000 { result := mul(uUNIT, 3) }\n        case 10000000000000000000000 { result := mul(uUNIT, 4) }\n        case 100000000000000000000000 { result := mul(uUNIT, 5) }\n        case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n        case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n        case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n        case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n        case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n        case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n        case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n        case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n        case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n        case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n        case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n        case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n        case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n        case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n        case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n        case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n        case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n        case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n        case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n        case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n        case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n        case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n        case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n        case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n        case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n        case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n        case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n        case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n        case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n        case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n        case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n        case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n        case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n        case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n        case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n        case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n        case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n        case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n        case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n        case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n        case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n        case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n        case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n        case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n        case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n        case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n        case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n        case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n        case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n        case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n        case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n        case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n        case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n        default { result := uMAX_SD59x18 }\n    }\n\n    if (result.unwrap() == uMAX_SD59x18) {\n        unchecked {\n            // Inline the fixed-point division to save gas.\n            result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n        }\n    }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x must be greater than zero.\n///\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    if (xInt <= 0) {\n        revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n    }\n\n    unchecked {\n        int256 sign;\n        if (xInt >= uUNIT) {\n            sign = 1;\n        } else {\n            sign = -1;\n            // Inline the fixed-point inversion to save gas.\n            xInt = uUNIT_SQUARED / xInt;\n        }\n\n        // Calculate the integer part of the logarithm.\n        uint256 n = Common.msb(uint256(xInt / uUNIT));\n\n        // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\n        // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\n        int256 resultInt = int256(n) * uUNIT;\n\n        // Calculate $y = x * 2^{-n}$.\n        int256 y = xInt >> n;\n\n        // If y is the unit number, the fractional part is zero.\n        if (y == uUNIT) {\n            return wrap(resultInt * sign);\n        }\n\n        // Calculate the fractional part via the iterative approximation.\n        // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n        int256 DOUBLE_UNIT = 2e18;\n        for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n            y = (y * y) / uUNIT;\n\n            // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n            if (y >= DOUBLE_UNIT) {\n                // Add the 2^{-m} factor to the logarithm.\n                resultInt = resultInt + delta;\n\n                // Halve y, which corresponds to z/2 in the Wikipedia article.\n                y >>= 1;\n            }\n        }\n        resultInt *= sign;\n        result = wrap(resultInt);\n    }\n}\n\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\n///\n/// @dev Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv18}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The result must fit in SD59x18.\n///\n/// @param x The multiplicand as an SD59x18 number.\n/// @param y The multiplier as an SD59x18 number.\n/// @return result The product as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    int256 yInt = y.unwrap();\n    if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n        revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\n    }\n\n    // Get hold of the absolute values of x and y.\n    uint256 xAbs;\n    uint256 yAbs;\n    unchecked {\n        xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n        yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n    }\n\n    // Compute the absolute value (x*y÷UNIT). The resulting value must fit in SD59x18.\n    uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\n    if (resultAbs > uint256(uMAX_SD59x18)) {\n        revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\n    }\n\n    // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n    // negative, 0 for positive or zero).\n    bool sameSign = (xInt ^ yInt) > -1;\n\n    // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n    unchecked {\n        result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n    }\n}\n\n/// @notice Raises x to the power of y using the following formula:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y Exponent to raise x to, as an SD59x18 number\n/// @return result x raised to power y, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    int256 yInt = y.unwrap();\n\n    // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n    if (xInt == 0) {\n        return yInt == 0 ? UNIT : ZERO;\n    }\n    // If x is `UNIT`, the result is always `UNIT`.\n    else if (xInt == uUNIT) {\n        return UNIT;\n    }\n\n    // If y is zero, the result is always `UNIT`.\n    if (yInt == 0) {\n        return UNIT;\n    }\n    // If y is `UNIT`, the result is always x.\n    else if (yInt == uUNIT) {\n        return x;\n    }\n\n    // Calculate the result using the formula.\n    result = exp2(mul(log2(x), y));\n}\n\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\n/// - The result must fit in SD59x18.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\n    uint256 xAbs = uint256(abs(x).unwrap());\n\n    // Calculate the first iteration of the loop in advance.\n    uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\n\n    // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n    uint256 yAux = y;\n    for (yAux >>= 1; yAux > 0; yAux >>= 1) {\n        xAbs = Common.mulDiv18(xAbs, xAbs);\n\n        // Equivalent to `y % 2 == 1`.\n        if (yAux & 1 > 0) {\n            resultAbs = Common.mulDiv18(resultAbs, xAbs);\n        }\n    }\n\n    // The result must fit in SD59x18.\n    if (resultAbs > uint256(uMAX_SD59x18)) {\n        revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\n    }\n\n    unchecked {\n        // Is the base negative and the exponent odd? If yes, the result should be negative.\n        int256 resultInt = int256(resultAbs);\n        bool isNegative = x.unwrap() < 0 && y & 1 == 1;\n        if (isNegative) {\n            resultInt = -resultInt;\n        }\n        result = wrap(resultInt);\n    }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - Only the positive root is returned.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x cannot be negative, since complex numbers are not supported.\n/// - x must be less than `MAX_SD59x18 / UNIT`.\n///\n/// @param x The SD59x18 number for which to calculate the square root.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\n    int256 xInt = x.unwrap();\n    if (xInt < 0) {\n        revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\n    }\n    if (xInt > uMAX_SD59x18 / uUNIT) {\n        revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\n    }\n\n    unchecked {\n        // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\n        // In this case, the two numbers are both the square root.\n        uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\n        result = wrap(int256(resultUint));\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/ud2x18/Casting.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD2x18 number into SD1x18.\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\n    uint64 xUint = UD2x18.unwrap(x);\n    if (xUint > uint64(uMAX_SD1x18)) {\n        revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\n    }\n    result = SD1x18.wrap(int64(xUint));\n}\n\n/// @notice Casts a UD2x18 number into SD59x18.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\n    result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\n}\n\n/// @notice Casts a UD2x18 number into UD60x18.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\n    result = UD60x18.wrap(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint128.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\n    result = uint128(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint256.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\n    result = uint256(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint40.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\n    uint64 xUint = UD2x18.unwrap(x);\n    if (xUint > uint64(Common.MAX_UINT40)) {\n        revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\n    }\n    result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\n    result = UD2x18.wrap(x);\n}\n\n/// @notice Unwrap a UD2x18 number into uint64.\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\n    result = UD2x18.unwrap(x);\n}\n\n/// @notice Wraps a uint64 number into UD2x18.\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\n    result = UD2x18.wrap(x);\n}\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/sd1x18/Errors.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/sd59x18/Errors.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\nerror PRBMath_SD59x18_Abs_MinSD59x18();\n\n/// @notice Thrown when ceiling a number overflows SD59x18.\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\n\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Div_InputTooSmall();\n\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when flooring a number underflows SD59x18.\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\n\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Mul_InputTooSmall();\n\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when raising a number to a power and hte intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\n\n/// @notice Thrown when taking the square root of a negative number.\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\n\n/// @notice Thrown when the calculating the square root overflows SD59x18.\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\n"
      },
      "lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/ud2x18/Errors.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\n"
      }
    },
    "settings": {
      "remappings": [
        "@prb/test/=lib/rain.flow/lib/rain.interpreter/lib/prb-math/lib/prb-test/src/",
        "bitwise/=lib/rain.flow/lib/rain.interpreter/src/lib/bitwise/",
        "bytecode/=lib/rain.flow/lib/rain.interpreter/src/lib/bytecode/",
        "caller/=lib/rain.flow/lib/rain.interpreter/src/lib/caller/",
        "compile/=lib/rain.flow/lib/rain.interpreter/src/lib/compile/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "erc4626-tests/=lib/rain.flow/lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
        "eval/=lib/rain.flow/lib/rain.interpreter/src/lib/eval/",
        "extern/=lib/rain.flow/lib/rain.interpreter/src/lib/extern/",
        "forge-std/=lib/forge-std/src/",
        "integrity/=lib/rain.flow/lib/rain.interpreter/src/lib/integrity/",
        "ns/=lib/rain.flow/lib/rain.interpreter/src/lib/ns/",
        "op/=lib/rain.flow/lib/rain.interpreter/src/lib/op/",
        "openzeppelin-contracts-upgradeable/=lib/rain.flow/lib/openzeppelin-contracts-upgradeable/",
        "openzeppelin-contracts/=lib/rain.flow/lib/rain.factory/lib/openzeppelin-contracts/",
        "openzeppelin/=lib/rain.flow/lib/openzeppelin-contracts-upgradeable/contracts/",
        "parse/=lib/rain.flow/lib/rain.interpreter/src/lib/parse/",
        "prb-math/=lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/",
        "prb-test/=lib/rain.flow/lib/rain.interpreter/lib/prb-math/lib/prb-test/src/",
        "rain.chainlink/=lib/rain.flow/lib/rain.interpreter/lib/rain.chainlink/src/",
        "rain.datacontract/=lib/rain.flow/lib/rain.interpreter/lib/rain.datacontract/src/",
        "rain.erc1820/=lib/rain.flow/lib/rain.interpreter/lib/rain.erc1820/src/",
        "rain.extrospection/=lib/rain.flow/lib/rain.factory/lib/rain.extrospection/",
        "rain.factory/=lib/rain.flow/lib/rain.factory/",
        "rain.flow/=lib/rain.flow/",
        "rain.interpreter/=lib/rain.flow/lib/rain.interpreter/",
        "rain.lib.hash/=lib/rain.flow/lib/rain.interpreter/lib/rain.lib.memkv/lib/rain.lib.hash/src/",
        "rain.lib.memkv/=lib/rain.flow/lib/rain.interpreter/lib/rain.lib.memkv/src/",
        "rain.lib.typecast/=lib/rain.flow/lib/rain.interpreter/lib/rain.lib.typecast/src/",
        "rain.math.fixedpoint/=lib/rain.flow/lib/rain.interpreter/lib/rain.math.fixedpoint/src/",
        "rain.math.saturating/=lib/rain.flow/lib/rain.interpreter/lib/rain.math.fixedpoint/lib/rain.math.saturating/src/",
        "rain.metadata/=lib/rain.flow/lib/rain.interpreter/lib/rain.metadata/src/",
        "rain.solmem/=lib/rain.flow/lib/rain.interpreter/lib/rain.solmem/src/",
        "sol.lib.binmaskflag/=lib/rain.flow/lib/rain.interpreter/lib/sol.lib.binmaskflag/src/",
        "state/=lib/rain.flow/lib/rain.interpreter/src/lib/state/",
        "uniswap/=lib/rain.flow/lib/rain.interpreter/src/lib/uniswap/",
        "v2-core/=lib/rain.flow/lib/rain.interpreter/lib/v2-core/contracts/",
        "v2-periphery/=lib/rain.flow/lib/rain.interpreter/lib/v2-periphery/contracts/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 1000000
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "none",
        "appendCBOR": false
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "viaIR": false,
      "libraries": {}
    }
  }}