ETH Price: $3,366.04 (-0.41%)

Contract

0x0082578eedFD01ec97c36165469D012D6DC257CC
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

TokenTracker

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Safe Transfer Fr...214651402024-12-23 12:19:2324 days ago1734956363IN
0x0082578e...D6DC257CC
0 ETH0.000382597.37625489
Safe Transfer Fr...203347122024-07-18 16:50:35182 days ago1721321435IN
0x0082578e...D6DC257CC
0 ETH0.0009891319.06574962
Safe Transfer Fr...202361542024-07-04 22:33:59196 days ago1720132439IN
0x0082578e...D6DC257CC
0 ETH0.000208814.02500726
Safe Transfer Fr...202361432024-07-04 22:31:47196 days ago1720132307IN
0x0082578e...D6DC257CC
0 ETH0.000228214.39888701
Safe Transfer Fr...202241952024-07-03 6:28:35197 days ago1719988115IN
0x0082578e...D6DC257CC
0 ETH0.000082872.4348784
Safe Transfer Fr...202241902024-07-03 6:27:35197 days ago1719988055IN
0x0082578e...D6DC257CC
0 ETH0.000083152.44201237
Safe Transfer Fr...197229212024-04-24 4:40:59268 days ago1713933659IN
0x0082578e...D6DC257CC
0 ETH0.000461228.13739005
Safe Transfer Fr...194289862024-03-13 22:04:47309 days ago1710367487IN
0x0082578e...D6DC257CC
0 ETH0.0036144569.66952774
Set Approval For...192307822024-02-15 3:55:11337 days ago1707969311IN
0x0082578e...D6DC257CC
0 ETH0.000411418.63763357
Set Approval For...192307482024-02-15 3:48:23337 days ago1707968903IN
0x0082578e...D6DC257CC
0 ETH0.0003949317.89140939
Set Approval For...192307342024-02-15 3:45:23337 days ago1707968723IN
0x0082578e...D6DC257CC
0 ETH0.0003873217.54674398
Set Approval For...192307092024-02-15 3:40:11337 days ago1707968411IN
0x0082578e...D6DC257CC
0 ETH0.0004210519.13890448
Safe Transfer Fr...190686312024-01-23 9:59:47359 days ago1706003987IN
0x0082578e...D6DC257CC
0 ETH0.0014593828.13008509
Safe Transfer Fr...189216912024-01-02 19:11:23380 days ago1704222683IN
0x0082578e...D6DC257CC
0 ETH0.001247324.04206376
Safe Transfer Fr...188890242023-12-29 5:01:11385 days ago1703826071IN
0x0082578e...D6DC257CC
0 ETH0.0009241117.81254441
Safe Transfer Fr...188055542023-12-17 11:50:11396 days ago1702813811IN
0x0082578e...D6DC257CC
0 ETH0.0020182731.84808766
Safe Transfer Fr...188055542023-12-17 11:50:11396 days ago1702813811IN
0x0082578e...D6DC257CC
0 ETH0.0020060431.84808766
Safe Transfer Fr...186067582023-11-19 15:30:23424 days ago1700407823IN
0x0082578e...D6DC257CC
0 ETH0.0011329322.00555641
Safe Transfer Fr...184048992023-10-22 9:18:59452 days ago1697966339IN
0x0082578e...D6DC257CC
0 ETH0.000354576.83603889
Degenerate182626082023-10-02 11:40:23472 days ago1696246823IN
0x0082578e...D6DC257CC
0 ETH0.0004031311.75125331
Regenerate Many182626032023-10-02 11:39:23472 days ago1696246763IN
0x0082578e...D6DC257CC
0 ETH0.0005962810.69415858
Generate Existin...182615772023-10-02 8:13:23472 days ago1696234403IN
0x0082578e...D6DC257CC
0.008 ETH0.000269897.45810062
Safe Transfer Fr...182499052023-09-30 17:06:59474 days ago1696093619IN
0x0082578e...D6DC257CC
0 ETH0.000743514.34899361
Safe Transfer Fr...182499032023-09-30 17:06:35474 days ago1696093595IN
0x0082578e...D6DC257CC
0 ETH0.0007906915.26312507
Safe Transfer Fr...182280772023-09-27 15:46:35477 days ago1695829595IN
0x0082578e...D6DC257CC
0 ETH0.0008625116.75301352
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block
From
To
188055542023-12-17 11:50:11396 days ago1702813811
0x0082578e...D6DC257CC
0 ETH
188055542023-12-17 11:50:11396 days ago1702813811
0x0082578e...D6DC257CC
0 ETH
182626082023-10-02 11:40:23472 days ago1696246823
0x0082578e...D6DC257CC
0.008 ETH
182615772023-10-02 8:13:23472 days ago1696234403
0x0082578e...D6DC257CC
0 ETH
181545022023-09-17 8:12:23487 days ago1694938343
0x0082578e...D6DC257CC
0.008 ETH
181539202023-09-17 6:12:59487 days ago1694931179
0x0082578e...D6DC257CC
0 ETH
180742042023-09-06 1:41:11499 days ago1693964471
0x0082578e...D6DC257CC
0.008 ETH
180738792023-09-06 0:35:47499 days ago1693960547
0x0082578e...D6DC257CC
0 ETH
179552352023-08-20 10:02:59515 days ago1692525779
0x0082578e...D6DC257CC
0.008 ETH
179547692023-08-20 8:28:59515 days ago1692520139
0x0082578e...D6DC257CC
0 ETH
179233482023-08-15 22:53:59520 days ago1692140039
0x0082578e...D6DC257CC
0.016 ETH
179225262023-08-15 20:08:35520 days ago1692130115
0x0082578e...D6DC257CC
0 ETH
179223302023-08-15 19:29:11520 days ago1692127751
0x0082578e...D6DC257CC
0 ETH
179161252023-08-14 22:39:35521 days ago1692052775
0x0082578e...D6DC257CC
0.032 ETH
179143552023-08-14 16:43:23521 days ago1692031403
0x0082578e...D6DC257CC
0 ETH
179143522023-08-14 16:42:47521 days ago1692031367
0x0082578e...D6DC257CC
0 ETH
179143282023-08-14 16:37:59521 days ago1692031079
0x0082578e...D6DC257CC
0 ETH
179143262023-08-14 16:37:35521 days ago1692031055
0x0082578e...D6DC257CC
0 ETH
179123112023-08-14 9:52:47521 days ago1692006767
0x0082578e...D6DC257CC
0.008 ETH
179117662023-08-14 8:02:59521 days ago1692000179
0x0082578e...D6DC257CC
0 ETH
178940182023-08-11 20:25:59524 days ago1691785559
0x0082578e...D6DC257CC
0.064 ETH
178937622023-08-11 19:33:59524 days ago1691782439
0x0082578e...D6DC257CC
0 ETH
178932212023-08-11 17:45:35524 days ago1691775935
0x0082578e...D6DC257CC
0 ETH
178907402023-08-11 9:25:47524 days ago1691745947
0x0082578e...D6DC257CC
0.016 ETH
178904632023-08-11 8:30:23524 days ago1691742623
0x0082578e...D6DC257CC
0 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Infinity

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion
File 1 of 14 : Infinity.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "./libraries/InfiniteArt.sol";
import "./libraries/InfiniteBags.sol";
import "./libraries/InfiniteGenerator.sol";
import "./libraries/InfiniteMetadata.sol";

import "./standards/ERC1155.sol";

/// @title Infinity token contract.
/// @notice Imo notable.
/// @author Visualize Value
contract Infinity is ERC1155 {

    /// @notice The name of the collection.
    string public name = "Infinity";

    /// @notice The symbol of the collection.
    string public symbol = unicode"∞";

    /// @notice The price of an infinity token.
    uint public price = 0.008 ether;

    /// @dev VV creator account.
    address private constant VV = 0xc8f8e2F59Dd95fF67c3d39109ecA2e2A017D4c8a;

    /// @dev Instanciate the contract...
    constructor(address[] memory genesisRecipients) ERC1155() payable {
        _checkDeposit(genesisRecipients.length);

        uint count = genesisRecipients.length;
        for (uint i = 0; i < count;) {
            _mint(genesisRecipients[i], 0, 1, "");

            unchecked { ++i; }
        }
    }

    /// @notice Deposit ether, receive random infinities
    receive() external payable {
        _generateViaDeposit(msg.sender, _randomId());
    }

    /// @notice Create a new infinity check and deposit 0.008 ETH for each token.
    /// @param recipient The address that should receive the token.
    /// @param message Mint the token with an optional message.
    function generate(
        address recipient,
        string calldata message
    ) public payable {
        uint tokenId = _randomId();

        _generateViaDeposit(recipient, tokenId);

        _message(recipient, tokenId, message);
    }

    /// @notice Copy an existing infinity check owned by someone and deposit 0.008 ETH for each token.
    /// @param source The address of an existing owner of the token.
    /// @param recipient The address that should receive the token.
    /// @param tokenId The token ID to mint.
    /// @param message Mint the token with an optional message.
    function generateExisting(
        address source,
        address recipient,
        uint tokenId,
        string calldata message
    ) public payable {
        _validateId(tokenId, source);

        _generateViaDeposit(recipient, tokenId);

        _message(recipient, tokenId, message);
    }

    /// @notice Swap an inifinity token for a new one.
    /// @param id The token ID to burn.
    /// @param amount The token amount to burn / recreate.
    function regenerate(uint id, uint amount) public {
        // Execute burn
        _burn(msg.sender, id, amount);

        // Mint a new token
        _mint(msg.sender, _randomId(), amount, "");
    }

    /// @notice Destroy the token to withdraw its desposited ETH.
    /// @param id The token ID to destroy.
    /// @param amount The amount to degenerate (withdraws 0.008 ETH per item).
    function degenerate(
        uint id,
        uint amount
    ) public {
        // Execute burn
        _burn(msg.sender, id, amount);

        // Withdraw funds
        _send(msg.sender, amount * price);
    }

    /// @notice Create multiple infinity check tokens and deposit 0.008 ETH in each.
    /// @param recipients The addresses that should receive the token.
    /// @param amounts The number of tokens to send to each recipient.
    function generateMany(
        address[] calldata recipients,
        uint[] calldata amounts
    ) public payable {
        _checkDeposit(_totalAmount(amounts));

        uint count = recipients.length;
        for (uint i = 0; i < count;) {
            _mint(recipients[i], _randomId(), amounts[i], "");

            unchecked { ++i; }
        }
    }

    /// @notice Copy multiple infinity check tokens and deposit 0.008 ETH in each.
    /// @param sources The addresses of existing owners of each token.
    /// @param recipients The addresses that should receive the token.
    /// @param tokenIds The tokenIDs to mint.
    /// @param amounts The number of tokens to send for each token.
    function generateManyExisting(
        address[] calldata sources,
        address[] calldata recipients,
        uint[] calldata tokenIds,
        uint[] calldata amounts
    ) public payable {
        _checkDeposit(_totalAmount(amounts));

        uint count = sources.length;
        for (uint i = 0; i < count;) {
            _validateId(tokenIds[i], sources[i]);

            _mint(recipients[i], tokenIds[i], amounts[i], "");

            unchecked { ++i; }
        }
    }

    /// @notice Create multiple new infinity check tokens and deposit 0.008 ETH in each.
    /// @param ids The existing token IDs that should be destroyed in the process.
    /// @param degenerateAmounts The number of tokens per id to burn.
    /// @param amounts The number of tokens per id recreate.
    function regenerateMany(
        uint[] calldata ids,
        uint[] calldata degenerateAmounts,
        uint[] calldata amounts
    ) public payable {
        if (_totalAmount(degenerateAmounts) != _totalAmount(amounts)) revert InvalidInput();

        uint count = ids.length;
        for (uint i = 0; i < count;) {
            _burn(msg.sender, ids[i], degenerateAmounts[i]);
            _mint(msg.sender, _randomId(), amounts[i], "");

            unchecked { ++i; }
        }
    }

    /// @notice Degenerate multiple tokens at once.
    /// @param ids The tokenIDs to destroy.
    /// @param amounts The amounts to degenerate (withdraws 0.008 ETH per item).
    function degenerateMany(
        uint[] memory ids,
        uint[] memory amounts
    ) public {
        if (ids.length != amounts.length) revert InvalidInput();

        // Execute burn
        _burnBatch(msg.sender, ids, amounts);

        // Withdraw funds
        _send(msg.sender, _totalAmount(amounts) * price);
    }

    /// @notice Render SVG of the token.
    /// @param tokenId The token ID to render.
    function svg(uint tokenId) public pure returns (string memory) {
        return InfiniteArt.renderSVG(InfiniteGenerator.tokenData(tokenId));
    }

    /// @notice Render the encoded token metadata-URI.
    /// @param tokenId The token ID to get metadata for.
    function uri(uint tokenId) public pure override returns (string memory) {
        return InfiniteMetadata.tokenURI(InfiniteGenerator.tokenData(tokenId));
    }

    /// @notice Supply is (in)finite: (2^256 - 1)^2.
    function totalSupply() public pure returns (uint) { return type(uint).max; }
    function totalSupply(uint) public pure returns (uint) { return type(uint).max; }

    /// @dev Mint a token n times, based on the amount of ETH sent.
    function _generateViaDeposit(address recipient, uint tokenId) internal {
        uint amount  = msg.value / price;
        uint surplus = msg.value % price;

        if (amount == 0) revert InvalidDesposit();

        _mint(recipient, tokenId, amount, "");
        _send(recipient, surplus);
    }

    /// @dev Validate IDs to minted tokens or randomize for initial mints. Exception for VV mints.
    function _validateId(uint id, address source) internal view {
        bool minted = balanceOf(source, id) > 0;

        // If it's not already minted piece, or we are not VV, revert.
        if(! minted && msg.sender != VV) revert InvalidToken();
    }

    /// @dev Make a random generative token ID.
    function _randomId() internal view returns (uint) {
        return uint(keccak256(abi.encodePacked(block.prevrandao, msg.sender, gasleft())));
    }

    /// @dev Check whether the deposited Ether is a correct {price} multipe of the token {amount}
    function _checkDeposit(uint amount) internal {
        if (msg.value != amount * price) revert InvalidDesposit();
    }

    /// @dev Get the sum of all given amounts
    function _totalAmount(uint[] memory amounts) internal pure returns (uint amount) {
        for (uint i = 0; i < amounts.length; i++) {
            amount += amounts[i];
        }
    }

    /// @dev Send ETH to an address
    function _send(address to, uint value) internal {
        (bool success, ) = payable(to).call{value: value}("");
        require(success, "Unable to send value, recipient may have reverted");
    }

    /// @dev Emit a mint message, if provided
    function _message(address recipient, uint tokenId, string calldata message) internal {
        if (bytes(message).length > 0) {
            emit Message(msg.sender, recipient, tokenId, message);
        }
    }
}

File 2 of 14 : IERC1155MetadataURI.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)

pragma solidity ^0.8.0;

import "../IERC1155.sol";

/**
 * @dev Interface of the optional ERC1155MetadataExtension interface, as defined
 * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155MetadataURI is IERC1155 {
    /**
     * @dev Returns the URI for token type `id`.
     *
     * If the `\{id\}` substring is present in the URI, it must be replaced by
     * clients with the actual token type ID.
     */
    function uri(uint256 id) external view returns (string memory);
}

File 3 of 14 : IERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

File 4 of 14 : IERC1155Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {
    /**
     * @dev Handles the receipt of a single ERC1155 token type. This function is
     * called at the end of a `safeTransferFrom` after the balance has been updated.
     *
     * NOTE: To accept the transfer, this must return
     * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
     * (i.e. 0xf23a6e61, or its own function selector).
     *
     * @param operator The address which initiated the transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param id The ID of the token being transferred
     * @param value The amount of tokens being transferred
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
     */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
     * @dev Handles the receipt of a multiple ERC1155 token types. This function
     * is called at the end of a `safeBatchTransferFrom` after the balances have
     * been updated.
     *
     * NOTE: To accept the transfer(s), this must return
     * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
     * (i.e. 0xbc197c81, or its own function selector).
     *
     * @param operator The address which initiated the batch transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param ids An array containing ids of each token being transferred (order and length must match values array)
     * @param values An array containing amounts of each token being transferred (order and length must match ids array)
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
     */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

File 5 of 14 : Base64.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides a set of functions to operate with Base64 strings.
 *
 * _Available since v4.5._
 */
library Base64 {
    /**
     * @dev Base64 Encoding/Decoding Table
     */
    string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /**
     * @dev Converts a `bytes` to its Bytes64 `string` representation.
     */
    function encode(bytes memory data) internal pure returns (string memory) {
        /**
         * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence
         * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol
         */
        if (data.length == 0) return "";

        // Loads the table into memory
        string memory table = _TABLE;

        // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter
        // and split into 4 numbers of 6 bits.
        // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up
        // - `data.length + 2`  -> Round up
        // - `/ 3`              -> Number of 3-bytes chunks
        // - `4 *`              -> 4 characters for each chunk
        string memory result = new string(4 * ((data.length + 2) / 3));

        /// @solidity memory-safe-assembly
        assembly {
            // Prepare the lookup table (skip the first "length" byte)
            let tablePtr := add(table, 1)

            // Prepare result pointer, jump over length
            let resultPtr := add(result, 32)

            // Run over the input, 3 bytes at a time
            for {
                let dataPtr := data
                let endPtr := add(data, mload(data))
            } lt(dataPtr, endPtr) {

            } {
                // Advance 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // To write each character, shift the 3 bytes (18 bits) chunk
                // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)
                // and apply logical AND with 0x3F which is the number of
                // the previous character in the ASCII table prior to the Base64 Table
                // The result is then added to the table to get the character to write,
                // and finally write it in the result pointer but with a left shift
                // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits

                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance
            }

            // When data `bytes` is not exactly 3 bytes long
            // it is padded with `=` characters at the end
            switch mod(mload(data), 3)
            case 1 {
                mstore8(sub(resultPtr, 1), 0x3d)
                mstore8(sub(resultPtr, 2), 0x3d)
            }
            case 2 {
                mstore8(sub(resultPtr, 1), 0x3d)
            }
        }

        return result;
    }
}

File 6 of 14 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 7 of 14 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 8 of 14 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 9 of 14 : InfiniteArt.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "./InfiniteBags.sol";
import "./Utilities.sol";

/**
@title  InfiniteArt
@author VisualizeValue
@notice Renders the Infinity visuals.
*/
library InfiniteArt {

    /// @dev Generate the SVG code for an Infinity token.
    function renderSVG(Token memory data) public pure returns (string memory) {
        return string.concat(
            '<svg viewBox="0 0 800 800" fill="none" xmlns="http://www.w3.org/2000/svg">',
                renderStyle(data),
                renderDefs(),
                '<rect width="800" height="800" fill="var(--bg)" />',
                '<g transform="scale(0.95)" transform-origin="center">',
                    renderGrid(),
                '</g>',
                renderNoise(data),
                '<g transform="scale(0.95)" transform-origin="center">',
                    renderSymbols(data),
                '</g>',
            '</svg>'
        );
    }

    /// @dev Render CSS variables.
    function renderStyle(Token memory data) public pure returns (string memory) {
        return string.concat(
            '<style>',
                ':root {',
                    '--bg: ', data.background, ';',
                    '--gr: ', data.gridColor, ';',
                '}',
            '</style>'
        );
    }

    /// @dev Render SVG meta defenitions.
    function renderDefs() public pure returns (string memory) {
        return string.concat(
            '<defs>',
                '<rect id="box" width="100" height="100" stroke="var(--gr)" stroke-width="3" style="paint-order: stroke;" />'
                '<g id="row">', renderGridRow(), '</g>',
                '<mask id="mask"><rect width="800" height="800" fill="white"/></mask>',
                '<path id="loop" d="M 100 0 A 100 100, 0, 1, 1, 0 100 L 0 0 Z"/>',
                '<g id="infinity">',
                    '<use href="#loop" />',
                    '<use href="#loop" transform="scale(-1,-1)" />',
                '</g>',
                '<filter id="noise">',
                    '<feTurbulence type="fractalNoise" baseFrequency="0.8" stitchTiles="stitch" numOctaves="1" seed="8"/>',
                    '<feColorMatrix type="saturate" values="0"/>',
                '</filter>',
            '</defs>'
        );
    }

    /// @dev Generate the SVG code for the entire 8x8 grid.
    function renderGrid() public pure returns (string memory) {
        string memory grid;
        for (uint256 i; i < 8; i++) {
            grid = string.concat(
                grid,
                '<use href="#row" transform="translate(0,', str(i*100), ')" />'
            );
        }

        return grid;
    }

    /// @dev Generate the SVG code for rows in the 8x8 grid.
    function renderGridRow() public pure returns (string memory) {
        string memory row;
        for (uint256 i; i < 8; i++) {
            row = string.concat(
                row,
                '<use transform="translate(', str(i*100), ')" href="#box" />'
            );
        }
        return row;
    }

    /// @dev Render the noise layer.
    function renderNoise(Token memory data) public pure returns (string memory) {
        return string.concat(
            '<rect mask="url(#mask)" width="800" height="800" fill="black" filter="url(#noise)" ',
                'style="mix-blend-mode: multiply;" opacity="', data.light ? '0.248"' : '0.8"',
            '/>'
        );
    }

    /// @dev Generate SVG code for the symbols.
    function renderSymbols(Token memory data) public pure returns (string memory) {
        uint space  = 800 / data.grid;
        uint center = space / 4;
        uint width  = space / 2;

        string memory symbols;
        for (uint i = 0; i < data.count; i++) {
            Symbol memory symbol = data.symbols[i];

            uint baseStroke = symbol.isInfinity ? 8 : 4;
            uint stroke = (data.grid < 8 ? baseStroke : baseStroke * 3 / 4) * data.grid / 2;
            uint scale  = width * 1000 / symbol.formWidth;

            symbol.x      = str(i % data.grid * space + center);
            symbol.y      = str(i / data.grid * space + center);
            symbol.stroke = str(stroke);
            symbol.center = str(center);
            symbol.width  = str(width);
            symbol.scale  = scale < 1000
                ? string.concat('0.', str(scale))
                : str(scale / 1000);

            symbols = string.concat(symbols, renderSymbol(symbol));
        }
        return symbols;
    }

    /// @dev Generate SVG code for the symbols.
    function renderSymbol(Symbol memory symbol) public pure returns (string memory) {
        symbol.color.rendered = renderColor(symbol.color);

        string memory rendered = symbol.form == 1 ? renderLoop(symbol)
                               : symbol.form == 2 ? renderInfinitySingle(symbol)
                               : symbol.form == 3 ? render90Loop(symbol)
                               : symbol.form == 4 ? renderInfinityPair(symbol)
                               : symbol.form == 5 ? render180Loop(symbol)
                               : symbol.form == 8 ? renderInfinityCheck(symbol)
                                                  : render360Loop(symbol);

        return string.concat(
            '<g transform="translate(',symbol.x,',',symbol.y,') rotate(',symbol.rotation,')" ',
                'transform-origin="',symbol.center,' ',symbol.center,'" ',
                'stroke-width="', symbol.stroke,
            '">',
                rendered,
            '</g>'
        );
    }

    /// @dev Helper to render a color to its SVG compliant HSL string.
    function renderColor(Color memory color) public pure returns (string memory) {
        if (bytes(color.rendered).length > 0) return color.rendered;

        return string.concat('hsl(', str(color.h), ' ', str(color.s), '% ', str(color.l), '%)');
    }

    /// @dev Render a single loop symbol.
    function renderLoop(Symbol memory symbol) public pure returns (string memory) {
        return string.concat(
            '<use href="#loop" transform="scale(', symbol.scale, ')" stroke="', symbol.color.rendered, '" />'
        );
    }

    /// @dev Render two loop symbols, one rotated by 90 degrees.
    function render90Loop(Symbol memory symbol) public pure returns (string memory) {
        return string.concat(
            '<g transform="scale(', symbol.scale, ')" stroke="', symbol.color.rendered, '">',
                '<use href="#loop" />',
                '<use href="#loop" transform="translate(200,0) scale(-1,1)" />',
            '</g>'
        );
    }

    /// @dev Render two loop symbols, one rotated by 180 degrees.
    function render180Loop(Symbol memory symbol) public pure returns (string memory) {
        return string.concat(
            '<g transform="scale(', symbol.scale, ')" stroke="', symbol.color.rendered, '">',
                '<use href="#loop" />',
                '<use href="#loop" transform="translate(200,200) scale(-1,-1)" />',
            '</g>'
        );
    }

    /// @dev Render four loop symbols to form a square.
    function render360Loop(Symbol memory symbol) public pure returns (string memory) {
        return string.concat(
            '<g transform="scale(', symbol.scale, ')" stroke="', symbol.color.rendered, '">',
                '<use href="#loop" />',
                '<use href="#loop" transform="translate(200,0) scale(-1,1)" />',
                '<use href="#loop" transform="translate(0,200) scale(1,-1)" />',
                '<use href="#loop" transform="translate(200,200) scale(-1,-1)" />',
            '</g>'
        );
    }

    /// @dev Check: Render a single infinity.
    function renderInfinitySingle(Symbol memory symbol) public pure returns (string memory) {
        return string.concat(
            '<g transform="scale(', symbol.scale, ')" stroke="', symbol.color.rendered, '">',
                '<g transform="translate(200,200)">'
                    '<use href="#infinity" />',
                '</g>'
            '</g>'
        );
    }

    /// @dev Double check: Render an infinity pair.
    function renderInfinityPair(Symbol memory symbol) public pure returns (string memory) {
        return string.concat(
            '<g transform="scale(', symbol.scale, ')" stroke="', symbol.color.rendered, '">',
                '<g transform="translate(200,200)">'
                    '<use href="#infinity" />',
                    '<use href="#infinity" transform="rotate(90)" />',
                '</g>'
            '</g>'
        );
    }

    /// @dev Quadruple check: Render an infinity check.
    function renderInfinityCheck(Symbol memory symbol) public pure returns (string memory) {
        return string.concat(
            '<g transform="scale(', symbol.scale, ')" stroke="', symbol.color.rendered, '">',
                '<g transform="translate(200,200)">'
                    '<use href="#infinity" />',
                    '<use href="#infinity" transform="rotate(45)" />',
                    '<use href="#infinity" transform="rotate(90)" />',
                    '<use href="#infinity" transform="rotate(135)" />',
                '</g>'
            '</g>'
        );
    }

    /// @dev Uint to string helper.
    function str(uint n) public pure returns (string memory) {
        return Utilities.uint2str(n);
    }
}

File 10 of 14 : InfiniteBags.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/**
@title  InfiniteBags
@author VisualizeValue
@notice Bags to hold infinity token data. Imo pretty funny...
*/

/// @dev Bag holding computed token data.
struct Token {
    uint seed;
    string background;
    string gridColor;
    uint8 alloy;
    uint8 grid;
    uint8 count;
    uint8 band;
    uint8 gradient;
    bool continuous;
    bool mapColors;
    bool light;
    Symbol[64] symbols;
}

/// @dev Bag holding computed symbol data.
struct Symbol {
    uint form;
    uint16 formWidth;
    bool isInfinity;
    string rotation;
    string stroke;
    string center;
    string scale;
    string width;
    string x;
    string y;
    uint colorIdx;
    Color color;
}

/// @dev Bag holding color data.
struct Color {
    uint16 h;
    uint16 s;
    uint16 l;
    string rendered;
}

File 11 of 14 : InfiniteGenerator.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "./InfiniteBags.sol";
import "./Utilities.sol";

/**
@title  InfiniteGenerator
@author VisualizeValue
@notice Gathers the data to render Infinity visuals.
*/
library InfiniteGenerator {

    /// @dev 16 distinct colors + void.
    uint8 public constant ELEMENTS = 17;

    /// @dev Number of shades for each color.
    uint8 public constant SHADES = 4;

    /// @dev Collect relevant rendering data for easy access across functions.
    function tokenData(uint tokenId) public pure returns (Token memory data) {
        data.seed        = tokenId;
        data.light       = tokenId % 4096 == 0 ? true : false;
        data.background  = data.light == true ? '#FFFFFF' : '#111111';
        data.gridColor   = data.light == true ? '#F5F5F5' : '#19181B';
        data.grid        = getGrid(data);
        data.count       = data.grid ** 2;
        data.alloy       = getAlloy(data);
        data.band        = getBand(data);
        data.continuous  = getContinuous(data);
        data.gradient    = getGradient(data);
        data.mapColors   = getColorMap(data);
        data.symbols     = getSymbols(data);
    }

    /// @dev Define the grid for a token.
    function getGrid(Token memory data) public pure returns (uint8) {
        if (data.seed == 0) return 1; // Genesis token override.

        uint n = Utilities.random(data.seed, 'grid', 160);

        return n <  1 ? 1
             : n <  8 ? 2
             : n < 32 ? 4
                      : 8;
    }

    /// @dev Define the color band size for a token.
    function getBand(Token memory data) public pure returns (uint8) {
        // Four times the number of used elements, min 1.
        return Utilities.max(data.alloy * SHADES, 1);
    }

    /// @dev Whether to map symbols to colors.
    function getColorMap(Token memory data) public pure returns (bool) {
        // 20% for gradients; 8% for skittles.
        return data.gradient > 0
            ? Utilities.random(data.seed, 'color_map', 100) < 20
            : Utilities.random(data.seed, 'color_map', 100) < 8;
    }

    /// @dev Whether color banding is continuous or random. 50/50.
    function getContinuous(Token memory data) public pure returns (bool) {
        return Utilities.random(data.seed, 'continuous', 2) < 1;
    }

    /// @dev Get the number of distinct elements used. 0 for Isolates.
    function getAlloy(Token memory data) public pure returns (uint8) {
        if (data.grid == 1) return 0;

        uint8 n = uint8(Utilities.random(data.seed, 'alloy', 100));

        return n >= 56 ? 4 + n % (ELEMENTS - 4) // Complete
             : n >= 24 ? 2                     // Compound
             : n >=  4 ? 1                    // Composite
                       : 0;                  // Isolate
    }

    /// @dev Choose a gradient for the token.
    function getGradient(Token memory data) public pure returns (uint8) {
        if (data.grid == 1 || data.alloy == 0) return 0; // No gradients for 1x1 or isolate tokens
        if (Utilities.random(data.seed, 'gradient', 10) < 8) return 0; // 80% have no gradient

        uint8 options = data.grid == 2 ? 2 : 7;
        uint8[7] memory GRADIENTS = data.grid == 2 ? [1, 2, 0, 0, 0, 0, 0]
                                  : data.grid == 4 ? [1, 2, 3, 4, 5, 8, 10]
                                                   : [1, 2, 4, 7, 8, 9, 16];

        return GRADIENTS[Utilities.random(data.seed, 'select_gradient', options)];
    }

    /// @dev Get the symbols for all slots on the grid.
    function getSymbols(Token memory data) public pure returns (Symbol[64] memory symbols) {
        uint8[7] memory forms          = [1, 2, 3, 4, 5, 8, 9]; // Seven distinct symbols.
        uint8[7] memory rotationCounts = [2, 4, 4, 2, 2, 0, 0]; // How often we rotate.

        (uint[64] memory colorIndexes, Color[64] memory colors) = getColors(data);
        uint[64] memory formColorMap;

        for (uint i = 0; i < data.count; i++) {
            symbols[i].colorIdx = colorIndexes[i];
            symbols[i].color = colors[i];

            uint formIdx = getFormIdx(data, i);
            uint form = forms[formIdx];
            if (data.mapColors) {
                (formColorMap, form) = setGetMap(formColorMap, symbols[i].colorIdx, form);
            }
            symbols[i].form = form;

            symbols[i].isInfinity = symbols[i].form % 2 == 0;
            symbols[i].formWidth = symbols[i].isInfinity ? 400 : 200;

            uint rotationIncrement = symbols[i].isInfinity ? 45 : 90;
            uint rotations = rotationCounts[formIdx] > 0
                ? Utilities.random(
                    data.seed,
                    string.concat('rotation', str(i)),
                    rotationCounts[formIdx]
                )
                : 0;
            symbols[i].rotation = str(rotations * rotationIncrement);
        }
    }

    /// @dev Get shape of a given symbol of a token.
    function getFormIdx(Token memory data, uint i) public pure returns (uint) {
        if (data.seed == 0) return 5; // Genesis token is an infinity flower.

        uint random = Utilities.random(data.seed, string.concat('form', str(i)), 10);
        if (random == 0) return 0; // 10% Single Loops

        uint8[3] memory common = [1, 3, 5]; // Infinities
        uint8[3] memory uncommon = [2, 4, 6]; // Loops

        uint idx = Utilities.random(data.seed, string.concat('form-idx', str(i)), 3);
        return random < 8 ? common[idx] : uncommon[idx];
    }

    /// @dev Get all colors available to choose from.
    function allColors() public pure returns (Color[68] memory colors) {
        // One "Void" color with 4 shades.
        uint8[4] memory voidLums = [16, 32, 80, 96];
        for (uint i = 0; i < SHADES; i++) {
            colors[i].h = 270;
            colors[i].s = 8;
            colors[i].l = voidLums[i];
        }

        // 16 distinct colors with 4 shades each.
        uint8 count = 4*4;
        uint16 startHue = 256;
        uint8[4] memory lums = [56, 60, 64, 72];
        for (uint8 i = 0; i < 16; i++) {
            uint16 hue = (startHue + 360 * i / count) % 360;

            for(uint8 e = 0; e < 4; e++) {
                uint8 idx = 4+i*4+e;
                colors[idx].h = hue;
                colors[idx].s = 88;
                colors[idx].l = lums[e];
            }
        }
    }

    /// @dev Get the color variations for a specific token. Compute gradients / skittles.
    function getColors(Token memory data) public pure returns (
        uint[64] memory colorIndexes,
        Color[64] memory colors
    ) {
        Color[68] memory all = allColors();
        uint[68] memory options = getColorOptions(data);
        bool reverse = Utilities.random(data.seed, 'reverse', 2) > 0;

        for (uint i = 0; i < data.count; i++) {
            colorIndexes[i] = (
                data.gradient > 0
                    ? getGradientColor(data, i)
                    : getRandomColor(data, i)
            ) % 68;

            uint idx = reverse ? data.count - 1 - i : i;

            colors[idx] = all[options[colorIndexes[i]]];

            // Paradoxical, i know. Opepen your eyes. All one. Common fate.
            if (data.light) colors[idx].rendered = '#080808';
        }
    }

    /// @dev Get the colors to choose from for a given token.
    function getColorOptions(Token memory data) public pure returns (uint[68] memory options) {
        uint count = Utilities.max(1, data.alloy);
        for (uint element = 0; element < count; element++) {
            uint idx = element * SHADES;

            uint chosen = data.continuous && element > 0
                // Increment previous by one for a continuous band.
                ? (options[idx - 1] / SHADES + 1) % ELEMENTS
                // Random selection for hard shifts in color.
                : Utilities.random(data.seed, string.concat('element', str(element)), ELEMENTS);

            uint chosenIdx = chosen * SHADES;

            for (uint shade = 0; shade < SHADES; shade++) {
                options[idx + shade] = chosenIdx + shade;
            }
        }
    }

    /// @dev Compute the gradient colors for a gradient token.
    function getGradientColor(Token memory data, uint i) public pure returns (uint) {
        uint offset;
        if (data.gradient == 3 || data.gradient == 7) {
            // Fix angled gradient y-shift.
            offset = data.grid + 1;
        }

        return ((offset + i) * data.gradient * data.band / data.count) % data.band;
    }

    /// @dev Compute colors for a skittle tokens.
    function getRandomColor(Token memory data, uint i) public pure returns (uint) {
        uint8 max = Utilities.max(SHADES, data.band);
        string memory key = data.alloy == 0 ? '0' : str(i);
        return Utilities.random(data.seed, string.concat('random_color_', key), max);
    }

    /// @dev Helper to keep track of a key value store in memory.
    function setGetMap(
        uint[64] memory map, uint key, uint value
    ) public pure returns (uint[64] memory, uint) {
        uint k = key % 64;

        if (map[k] == 0) {
            map[k] = value;
        }

        return (map, map[k]);
    }

    /// @dev Uint to string helper.
    function str(uint n) public pure returns (string memory) {
        return Utilities.uint2str(n);
    }
}

File 12 of 14 : InfiniteMetadata.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/utils/Base64.sol";

import "./InfiniteBags.sol";
import "./InfiniteArt.sol";
import "./Utilities.sol";

/**
@title  InfiniteMetadata
@author VisualizeValue
@notice Renders ERC1155 compatible metadata for Infinity tokens.
*/
library InfiniteMetadata {

    /// @dev Render the JSON Metadata for a given Infinity token.
    /// @param data The render data for our token
    function tokenURI(
        Token memory data
    ) public pure returns (string memory) {
        bytes memory metadata = abi.encodePacked(
            '{',
                '"name": "Infinity",',
                unicode'"description": "∞",',
                '"image": ',
                    '"data:image/svg+xml;base64,',
                    Base64.encode(abi.encodePacked(InfiniteArt.renderSVG(data))),
                    '",',
                '"attributes": [', attributes(data), ']',
            '}'
        );

        return string.concat(
            "data:application/json;base64,",
            Base64.encode(metadata)
        );
    }

    /// @dev Render the JSON atributes for a given Infinity token.
    /// @param data The check to render.
    function attributes(Token memory data) public pure returns (string memory) {
        return string.concat(
            trait('Light', light(data.light), ','),
            trait('Grid', grid(data), ','),
            data.light  ? '' : trait('Elements',  elements(data), ','),
            data.light  ? '' : trait('Gradient',  gradient(data), ','),
            data.light  ? '' : trait('Band',      band(data), ','),
            trait('Symbols',   symbols(data), '')
        );
    }

    /// @dev Get the value for the 'Light' attribute.
    function light(bool on) public pure returns (string memory) {
        return on ? 'On' : 'Off';
    }

    /// @dev Get the value for the 'Grid' attribute.
    function grid(Token memory data) public pure returns (string memory) {
        string memory g = Utilities.uint2str(data.grid);

        return string.concat(g, 'x', g);
    }

    /// @dev Get the value for the 'Elements' attribute.
    function elements(Token memory data) public pure returns (string memory) {
        return data.alloy == 0 ? 'Isolate'
             : data.alloy == 1 ? 'Composite'
             : data.alloy == 2 ? 'Compound'
                               : 'Complete';
    }

    /// @dev Get the value for the 'Band' attribute.
    function band(Token memory data) public pure returns (string memory) {
        return (data.continuous || data.alloy < 2) ? 'Continuous' : 'Cut';
    }

    /// @dev Get the value for the 'Gradient' attribute.
    function gradient(Token memory data) public pure returns (string memory) {
        return [
            // [0, 1, 2, 3, 4, 5, _, 7, 8, 9, 10, _, _, _, _, _, 16]
            'None', 'Linear', 'Double Linear', 'Angled Down', 'Ordered', 'Angled Up', '', 'Angled Down', 'Linear Z',
            'Angled', 'Angled Up', '', '', '', '', '', 'Double Linear Z'
        ][data.gradient];
    }

    /// @dev Get the value for the 'Symbols' attribute.
    function symbols(Token memory data) public pure returns (string memory) {
        return data.mapColors ? 'Mapped' : 'Random';
    }

    /// @dev Generate the SVG snipped for a single attribute.
    /// @param traitType The `trait_type` for this trait.
    /// @param traitValue The `value` for this trait.
    /// @param append Helper to append a comma.
    function trait(
        string memory traitType, string memory traitValue, string memory append
    ) public pure returns (string memory) {
        return string(abi.encodePacked(
            '{',
                '"trait_type": "', traitType, '",'
                '"value": "', traitValue, '"'
            '}',
            append
        ));
    }

}

File 13 of 14 : Utilities.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

library Utilities {
    /// @dev Zero-index based pseudorandom number based on one input and max bound
    function random(uint256 input, uint256 _max) public pure returns (uint256) {
        return (uint256(keccak256(abi.encodePacked(input))) % _max);
    }

    /// @dev Zero-index based salted pseudorandom number based on two inputs and max bound
    function random(uint256 input, string memory salt, uint256 _max) public pure returns (uint256) {
        return (uint256(keccak256(abi.encodePacked(input, salt))) % _max);
    }

    /// @dev Convert an integer to a string
    function uint2str(uint256 _i) public pure returns (string memory _uintAsString) {
        if (_i == 0) {
            return "0";
        }
        uint256 j = _i;
        uint256 len;
        while (j != 0) {
            ++len;
            j /= 10;
        }
        bytes memory bstr = new bytes(len);
        uint256 k = len;
        while (_i != 0) {
            k = k - 1;
            uint8 temp = (48 + uint8(_i - (_i / 10) * 10));
            bytes1 b1 = bytes1(temp);
            bstr[k] = b1;
            _i /= 10;
        }
        return string(bstr);
    }

    /// @dev Get the smallest non zero number
    function minGt0(uint8 one, uint8 two) public pure returns (uint8) {
        return one > two
            ? two > 0
                ? two
                : one
            : one;
    }

    /// @dev Get the smaller number
    function min(uint8 one, uint8 two) public pure returns (uint8) {
        return one < two ? one : two;
    }

    /// @dev Get the larger number
    function max(uint8 one, uint8 two) public pure returns (uint8) {
        return one > two ? one : two;
    }

    /// @dev Get the average between two numbers
    function avg(uint8 one, uint8 two) public pure returns (uint8 result) {
        unchecked {
            result = (one >> 1) + (two >> 1) + (one & two & 1);
        }
    }

    /// @dev Get the days since another date (input is seconds)
    function day(uint256 from, uint256 to) public pure returns (uint24) {
        return uint24((to - from) / 24 hours + 1);
    }
}

File 14 of 14 : ERC1155.sol
// SPDX-License-Identifier: MIT
// Derived from OpenZeppelin Contracts (last updated v4.8.0) (token/ERC1155/ERC1155.sol)

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
import "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";

/**
 * @dev Simplified implementation of the basic standard multi-token.
 * See https://eips.ethereum.org/EIPS/eip-1155
 * Originally based on code by Enjin: https://github.com/enjin/erc-1155
 */
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
    // Mapping from token ID to account balances
    mapping(uint256 => mapping(address => uint256)) private _balances;

    /**
     * @dev Emitted when minting a token with a message.
     */
    event Message(address indexed from, address indexed to, uint256 indexed id, string message);

    /**
     * @dev Custom revert errors.
     */
    error InvalidToken();
    error InvalidInput();
    error InvalidDesposit();

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC1155).interfaceId ||
            interfaceId == type(IERC1155MetadataURI).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC1155MetadataURI-uri}.
     *
     * This implementation returns the same URI for *all* token types. It relies
     * on the token type ID substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * Clients calling this function must replace the `\{id\}` substring with the
     * actual token type ID.
     */
    function uri(uint256) public view virtual override returns (string memory) {}

    /**
     * @dev See {IERC1155-balanceOf}.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
        if (account == address(0)) return 0;
        return _balances[id][account];
    }

    /**
     * @dev See {IERC1155-balanceOfBatch}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
        public
        view
        virtual
        override
        returns (uint256[] memory)
    {
        require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");

        uint256[] memory batchBalances = new uint256[](accounts.length);

        for (uint256 i = 0; i < accounts.length; ++i) {
            batchBalances[i] = balanceOf(accounts[i], ids[i]);
        }

        return batchBalances;
    }

    /**
     * @notice Infinities are never approved.
     * @dev See {IERC1155-setApprovalForAll}.
     */
    function setApprovalForAll(address, bool) public virtual override {
        revert("No approvals on infinities");
    }

    /**
     * @notice Infinities are never approved.
     * @dev See {IERC1155-isApprovedForAll}.
     */
    function isApprovedForAll(address, address) public view virtual override returns (bool) {
        return false;
    }

    /**
     * @dev See {IERC1155-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender(),
            "ERC1155: caller is not token owner"
        );
        _safeTransferFrom(from, to, id, amount, data);
    }

    /**
     * @dev See {IERC1155-safeBatchTransferFrom}.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender(),
            "ERC1155: caller is not token owner"
        );
        _safeBatchTransferFrom(from, to, ids, amounts, data);
    }

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: transfer to the zero address");

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }
        _balances[id][to] += amount;

        emit TransferSingle(from, from, to, id, amount);

        _doSafeTransferAcceptanceCheck(from, from, to, id, amount, data);
    }

    /**
     * @dev Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
        require(to != address(0), "ERC1155: transfer to the zero address");

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
            _balances[id][to] += amount;
        }

        emit TransferBatch(from, from, to, ids, amounts);

        _doSafeBatchTransferAcceptanceCheck(from, from, to, ids, amounts, data);
    }

    /**
     * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _mint(
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");

        address operator = _msgSender();

        _balances[id][to] += amount;
        emit TransferSingle(operator, address(0), to, id, amount);

        _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
    }

    /**
     * @dev Destroys `amount` tokens of token type `id` from `from`
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `from` must have at least `amount` tokens of token type `id`.
     */
    function _burn(
        address from,
        uint256 id,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC1155: burn from the zero address");

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }

        emit TransferSingle(_msgSender(), from, address(0), id, amount);
    }

    /**
     * @dev Batched version of {_burn}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     */
    function _burnBatch(
        address from,
        uint256[] memory ids,
        uint256[] memory amounts
    ) internal virtual {
        require(from != address(0), "ERC1155: burn from the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        for (uint256 i = 0; i < ids.length; i++) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
        }

        emit TransferBatch(operator, from, address(0), ids, amounts);
    }

    function _doSafeTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) private {
        if (_isContract(to)) {
            try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
                if (response != IERC1155Receiver.onERC1155Received.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non-ERC1155Receiver implementer");
            }
        }
    }

    function _doSafeBatchTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) private {
        if (_isContract(to)) {
            try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
                bytes4 response
            ) {
                if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non-ERC1155Receiver implementer");
            }
        }
    }

    function _isContract(address account) internal view returns (bool) {
        return account.code.length > 0;
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 1000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {
    "contracts/libraries/InfiniteArt.sol": {
      "InfiniteArt": "0xc6b17cafcc2439ef4833fe6a073ba71438112f87"
    },
    "contracts/libraries/InfiniteGenerator.sol": {
      "InfiniteGenerator": "0xb0047233de84066b491f093380b8ca3cff4f7333"
    },
    "contracts/libraries/InfiniteMetadata.sol": {
      "InfiniteMetadata": "0x12b7f0e2f3d562b0cd012bd58e2d620bfdfe542f"
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address[]","name":"genesisRecipients","type":"address[]"}],"stateMutability":"payable","type":"constructor"},{"inputs":[],"name":"InvalidDesposit","type":"error"},{"inputs":[],"name":"InvalidInput","type":"error"},{"inputs":[],"name":"InvalidToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"string","name":"message","type":"string"}],"name":"Message","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"degenerate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"degenerateMany","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"string","name":"message","type":"string"}],"name":"generate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"source","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"message","type":"string"}],"name":"generateExisting","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"generateMany","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"sources","type":"address[]"},{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"generateManyExisting","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"regenerate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"degenerateAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"regenerateMany","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"svg","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"stateMutability":"payable","type":"receive"}]

60c06040526008608090815267496e66696e69747960c01b60a0526001906200002990826200047b565b5060408051808201909152600381526271444f60e91b60208201526002906200005390826200047b565b50661c6bf526340000600355604051620034bf380380620034bf833981016040819052620000819162000572565b80516200008e90620000ec565b80515f5b81811015620000e357620000da838281518110620000b457620000b462000637565b60200260200101515f600160405180602001604052805f8152506200011e60201b60201c565b60010162000092565b5050506200080c565b600354620000fb90826200065f565b34146200011b576040516328df225d60e01b815260040160405180910390fd5b50565b6001600160a01b038416620001845760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b60648201526084015b60405180910390fd5b5f838152602081815260408083206001600160a01b0388168452909152812080543392859291620001b79084906200067f565b909155505060408051858152602081018590526001600160a01b03808816925f92918516917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a462000217815f878787876200021e565b5050505050565b6001600160a01b0384163b15620003d75760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e6190620002659089908990889088908890600401620006da565b6020604051808303815f875af1925050508015620002a2575060408051601f3d908101601f191682019092526200029f9181019062000720565b60015b6200036257620002b162000750565b806308c379a003620002f15750620002c86200076a565b80620002d55750620002f3565b8060405162461bcd60e51b81526004016200017b9190620007f8565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560448201527f526563656976657220696d706c656d656e74657200000000000000000000000060648201526084016200017b565b6001600160e01b0319811663f23a6e6160e01b14620003d55760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b60648201526084016200017b565b505b505050505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806200040857607f821691505b6020821081036200042757634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000476575f81815260208120601f850160051c81016020861015620004555750805b601f850160051c820191505b81811015620003d75782815560010162000461565b505050565b81516001600160401b03811115620004975762000497620003df565b620004af81620004a88454620003f3565b846200042d565b602080601f831160018114620004e5575f8415620004cd5750858301515b5f19600386901b1c1916600185901b178555620003d7565b5f85815260208120601f198616915b828110156200051557888601518255948401946001909101908401620004f4565b50858210156200053357878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b601f8201601f191681016001600160401b03811182821017156200056b576200056b620003df565b6040525050565b5f602080838503121562000584575f80fd5b82516001600160401b03808211156200059b575f80fd5b818501915085601f830112620005af575f80fd5b815181811115620005c457620005c4620003df565b8060051b9150604051620005db8584018262000543565b81815291830184019184810188841115620005f4575f80fd5b938501935b838510156200062b57845192506001600160a01b03831683146200061c575f8081fd5b828152938501938501620005f9565b50979650505050505050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b80820281158282048414176200067957620006796200064b565b92915050565b808201808211156200067957620006796200064b565b5f81518084525f5b81811015620006bb576020818501810151868301820152016200069d565b505f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190525f90620007159083018462000695565b979650505050505050565b5f6020828403121562000731575f80fd5b81516001600160e01b03198116811462000749575f80fd5b9392505050565b5f60033d1115620007675760045f803e505f5160e01c5b90565b5f60443d1015620007785790565b6040516003193d81016004833e81513d6001600160401b038083116024840183101715620007a857505050505090565b8285019150815181811115620007c15750505050505090565b843d8701016020828501011115620007dc5750505050505090565b620007ed6020828601018762000543565b509095945050505050565b602081525f62000749602083018462000695565b612ca5806200081a5f395ff3fe60806040526004361061016f575f3560e01c806344b285db116100c65780639c095f561161007c578063bd85b03911610057578063bd85b039146103ad578063e985e9c5146103cd578063f242432a146103ee575f80fd5b80639c095f561461035a578063a035b1fe14610379578063a22cb4651461038e575f80fd5b80634e840992116100ac5780634e8409921461031457806368987a831461033357806395d89b4114610346575f80fd5b806344b285db146102c95780634e1273f4146102e8575f80fd5b806318160ddd116101265780632bfc3052116101015780632bfc3052146102845780632eb2c2d6146102975780633f6b5fde146102b6575f80fd5b806318160ddd1461024b57806325431b181461025e578063262fb60814610271575f80fd5b806306fdde031161015657806306fdde03146101ec5780630e89341c1461020d57806310981eb31461022c575f80fd5b8062fdd58e1461018b57806301ffc9a7146101bd575f80fd5b36610187576101853361018061040d565b610463565b005b5f80fd5b348015610196575f80fd5b506101aa6101a5366004611a68565b6104cf565b6040519081526020015b60405180910390f35b3480156101c8575f80fd5b506101dc6101d7366004611aa5565b61050d565b60405190151581526020016101b4565b3480156101f7575f80fd5b506102006105a7565b6040516101b49190611b14565b348015610218575f80fd5b50610200610227366004611b26565b610633565b348015610237575f80fd5b50610185610246366004611b3d565b610726565b348015610256575f80fd5b505f196101aa565b61018561026c366004611ba2565b61074c565b61018561027f366004611c4d565b610773565b610185610292366004611ce0565b610898565b3480156102a2575f80fd5b506101856102b1366004611ee9565b610928565b6101856102c4366004611f8c565b61099d565b3480156102d4575f80fd5b506102006102e3366004611b26565b6109be565b3480156102f3575f80fd5b50610307610302366004611fdb565b610a13565b6040516101b491906120d9565b34801561031f575f80fd5b5061018561032e3660046120eb565b610b4f565b610185610341366004612134565b610b96565b348015610351575f80fd5b50610200610c90565b348015610365575f80fd5b50610185610374366004611b3d565b610c9d565b348015610384575f80fd5b506101aa60035481565b348015610399575f80fd5b506101856103a83660046121fc565b610cc9565b3480156103b8575f80fd5b506101aa6103c7366004611b26565b505f1990565b3480156103d8575f80fd5b506101dc6103e7366004612231565b5f92915050565b3480156103f9575f80fd5b50610185610408366004612262565b610d11565b5f44335a6040516020016104469392919092835260609190911b6bffffffffffffffffffffffff19166020830152603482015260540190565b604051602081830303815290604052805190602001205f1c905090565b5f6003543461047291906122ea565b90505f6003543461048391906122fd565b9050815f036104a5576040516328df225d60e01b815260040160405180910390fd5b6104bf84848460405180602001604052805f815250610d81565b6104c98482610e8c565b50505050565b5f6001600160a01b0383166104e557505f610507565b505f818152602081815260408083206001600160a01b03861684529091529020545b92915050565b5f6001600160e01b031982167fd9b67a2600000000000000000000000000000000000000000000000000000000148061056f57506001600160e01b031982167f0e89341c00000000000000000000000000000000000000000000000000000000145b8061050757507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b0319831614610507565b600180546105b490612310565b80601f01602080910402602001604051908101604052809291908181526020018280546105e090612310565b801561062b5780601f106106025761010080835404028352916020019161062b565b820191905f5260205f20905b81548152906001019060200180831161060e57829003601f168201915b505050505081565b60607312b7f0e2f3d562b0cd012bd58e2d620bfdfe542f634afd561b73b0047233de84066b491f093380b8ca3cff4f733363b4b5b48f856040518263ffffffff1660e01b815260040161068891815260200190565b5f60405180830381865af41580156106a2573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526106c9919081019061263f565b6040518263ffffffff1660e01b81526004016106e59190612923565b5f60405180830381865af41580156106ff573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526105079190810190612a2b565b610731338383610f56565b61074833600354836107439190612a5d565b610e8c565b5050565b610756838661109a565b6107608484610463565b61076c84848484611101565b5050505050565b6107ae8282808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525061114d92505050565b6107e98585808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525061114d92505050565b146108075760405163b4fa3fb360e01b815260040160405180910390fd5b845f5b8181101561088e5761084d3389898481811061082857610828612a74565b9050602002013588888581811061084157610841612a74565b90506020020135610f56565b6108863361085961040d565b86868581811061086b5761086b612a74565b9050602002013560405180602001604052805f815250610d81565b60010161080a565b5050505050505050565b6108db6108d68383808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525061114d92505050565b611198565b825f5b81811015610920576109188686838181106108fb576108fb612a74565b90506020020160208101906109109190612a88565b61085961040d565b6001016108de565b505050505050565b6001600160a01b03851633146109905760405162461bcd60e51b815260206004820152602260248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201526132b960f11b60648201526084015b60405180910390fd5b61076c85858585856111c7565b5f6109a661040d565b90506109b28482610463565b6104c984828585611101565b606073c6b17cafcc2439ef4833fe6a073ba71438112f8763929ecd9d73b0047233de84066b491f093380b8ca3cff4f733363b4b5b48f856040518263ffffffff1660e01b815260040161068891815260200190565b60608151835114610a8c5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d6174636800000000000000000000000000000000000000000000006064820152608401610987565b5f835167ffffffffffffffff811115610aa757610aa7611d47565b604051908082528060200260200182016040528015610ad0578160200160208202803683370190505b5090505f5b8451811015610b4757610b1a858281518110610af357610af3612a74565b6020026020010151858381518110610b0d57610b0d612a74565b60200260200101516104cf565b828281518110610b2c57610b2c612a74565b6020908102919091010152610b4081612aa1565b9050610ad5565b509392505050565b8051825114610b715760405163b4fa3fb360e01b815260040160405180910390fd5b610b7c338383611417565b61074833600354610b8c8461114d565b6107439190612a5d565b610bd46108d68383808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525061114d92505050565b865f5b81811015610c8457610c27868683818110610bf457610bf4612a74565b905060200201358b8b84818110610c0d57610c0d612a74565b9050602002016020810190610c229190612a88565b61109a565b610c7c888883818110610c3c57610c3c612a74565b9050602002016020810190610c519190612a88565b878784818110610c6357610c63612a74565b9050602002013586868581811061086b5761086b612a74565b600101610bd7565b50505050505050505050565b600280546105b490612310565b610ca8338383610f56565b61074833610cb461040d565b8360405180602001604052805f815250610d81565b60405162461bcd60e51b815260206004820152601a60248201527f4e6f20617070726f76616c73206f6e20696e66696e69746965730000000000006044820152606401610987565b6001600160a01b0385163314610d745760405162461bcd60e51b815260206004820152602260248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201526132b960f11b6064820152608401610987565b61076c8585858585611628565b6001600160a01b038416610dfd5760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610987565b5f838152602081815260408083206001600160a01b0388168452909152812080543392859291610e2e908490612ab9565b909155505060408051858152602081018590526001600160a01b03808816925f92918516917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461076c815f878787876117a5565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114610ed5576040519150601f19603f3d011682016040523d82523d5f602084013e610eda565b606091505b5050905080610f515760405162461bcd60e51b815260206004820152603160248201527f556e61626c6520746f2073656e642076616c75652c20726563697069656e742060448201527f6d617920686176652072657665727465640000000000000000000000000000006064820152608401610987565b505050565b6001600160a01b038316610fb85760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b6064820152608401610987565b5f828152602081815260408083206001600160a01b0387168452909152902054818110156110345760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b6064820152608401610987565b5f838152602081815260408083206001600160a01b038816808552908352818420868603905581518781529283018690529133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6291015b60405180910390a450505050565b5f806110a683856104cf565b1190508015816110ca57503373c8f8e2f59dd95ff67c3d39109eca2e2a017d4c8a14155b15610f51576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80156104c95782846001600160a01b0316336001600160a01b03167fdd99aef5e4fdfad84059320be40f5dc0f015dc4025f56bd4010608c6743bc22e858560405161108c929190612acc565b5f805b82518110156111925782818151811061116b5761116b612a74565b60200260200101518261117e9190612ab9565b91508061118a81612aa1565b915050611150565b50919050565b6003546111a59082612a5d565b34146111c4576040516328df225d60e01b815260040160405180910390fd5b50565b81518351146112295760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b6064820152608401610987565b6001600160a01b03841661128d5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610987565b5f5b83518110156113b1575f8482815181106112ab576112ab612a74565b602002602001015190505f8483815181106112c8576112c8612a74565b6020908102919091018101515f84815280835260408082206001600160a01b038d16835290935291909120549091508181101561135a5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201526939103a3930b739b332b960b11b6064820152608401610987565b5f838152602081815260408083206001600160a01b038d8116855292528083208585039055908a16825281208054849290611396908490612ab9565b92505081905550505050806113aa90612aa1565b905061128f565b50836001600160a01b0316856001600160a01b0316866001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051611401929190612afa565b60405180910390a461076c858686868686611952565b6001600160a01b0383166114795760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b6064820152608401610987565b80518251146114db5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b6064820152608401610987565b335f5b83518110156115d8575f8482815181106114fa576114fa612a74565b602002602001015190505f84838151811061151757611517612a74565b6020908102919091018101515f84815280835260408082206001600160a01b038c1683529093529190912054909150818110156115a25760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b6064820152608401610987565b5f928352602083815260408085206001600160a01b038b16865290915290922091039055806115d081612aa1565b9150506114de565b505f6001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb868660405161108c929190612afa565b6001600160a01b03841661168c5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610987565b5f838152602081815260408083206001600160a01b03891684529091529020548281101561170f5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201526939103a3930b739b332b960b11b6064820152608401610987565b5f848152602081815260408083206001600160a01b038a811685529252808320868503905590871682528120805485929061174b908490612ab9565b909155505060408051858152602081018590526001600160a01b03808816929089169182917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46109208687878787875b6001600160a01b0384163b156109205760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906117e99089908990889088908890600401612b1e565b6020604051808303815f875af1925050508015611823575060408051601f3d908101601f1916820190925261182091810190612b60565b60015b6118d85761182f612b7b565b806308c379a0036118685750611843612b94565b8061184e575061186a565b8060405162461bcd60e51b81526004016109879190611b14565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560448201527f526563656976657220696d706c656d656e7465720000000000000000000000006064820152608401610987565b6001600160e01b0319811663f23a6e6160e01b146119495760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b6064820152608401610987565b50505050505050565b6001600160a01b0384163b156109205760405163bc197c8160e01b81526001600160a01b0385169063bc197c81906119969089908990889088908890600401612c12565b6020604051808303815f875af19250505080156119d0575060408051601f3d908101601f191682019092526119cd91810190612b60565b60015b6119dc5761182f612b7b565b6001600160e01b0319811663bc197c8160e01b146119495760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b6064820152608401610987565b80356001600160a01b0381168114611a63575f80fd5b919050565b5f8060408385031215611a79575f80fd5b611a8283611a4d565b946020939093013593505050565b6001600160e01b0319811681146111c4575f80fd5b5f60208284031215611ab5575f80fd5b8135611ac081611a90565b9392505050565b5f5b83811015611ae1578181015183820152602001611ac9565b50505f910152565b5f8151808452611b00816020860160208601611ac7565b601f01601f19169290920160200192915050565b602081525f611ac06020830184611ae9565b5f60208284031215611b36575f80fd5b5035919050565b5f8060408385031215611b4e575f80fd5b50508035926020909101359150565b5f8083601f840112611b6d575f80fd5b50813567ffffffffffffffff811115611b84575f80fd5b602083019150836020828501011115611b9b575f80fd5b9250929050565b5f805f805f60808688031215611bb6575f80fd5b611bbf86611a4d565b9450611bcd60208701611a4d565b935060408601359250606086013567ffffffffffffffff811115611bef575f80fd5b611bfb88828901611b5d565b969995985093965092949392505050565b5f8083601f840112611c1c575f80fd5b50813567ffffffffffffffff811115611c33575f80fd5b6020830191508360208260051b8501011115611b9b575f80fd5b5f805f805f8060608789031215611c62575f80fd5b863567ffffffffffffffff80821115611c79575f80fd5b611c858a838b01611c0c565b90985096506020890135915080821115611c9d575f80fd5b611ca98a838b01611c0c565b90965094506040890135915080821115611cc1575f80fd5b50611cce89828a01611c0c565b979a9699509497509295939492505050565b5f805f8060408587031215611cf3575f80fd5b843567ffffffffffffffff80821115611d0a575f80fd5b611d1688838901611c0c565b90965094506020870135915080821115611d2e575f80fd5b50611d3b87828801611c0c565b95989497509550505050565b634e487b7160e01b5f52604160045260245ffd5b610800810181811067ffffffffffffffff82111715611d7c57611d7c611d47565b60405250565b601f8201601f1916810167ffffffffffffffff81118282101715611da857611da8611d47565b6040525050565b604051610180810167ffffffffffffffff81118282101715611dd357611dd3611d47565b60405290565b5f67ffffffffffffffff821115611df257611df2611d47565b5060051b60200190565b5f82601f830112611e0b575f80fd5b81356020611e1882611dd9565b604051611e258282611d82565b83815260059390931b8501820192828101915086841115611e44575f80fd5b8286015b84811015611e5f5780358352918301918301611e48565b509695505050505050565b5f67ffffffffffffffff821115611e8357611e83611d47565b50601f01601f191660200190565b5f82601f830112611ea0575f80fd5b8135611eab81611e6a565b604051611eb88282611d82565b828152856020848701011115611ecc575f80fd5b826020860160208301375f92810160200192909252509392505050565b5f805f805f60a08688031215611efd575f80fd5b611f0686611a4d565b9450611f1460208701611a4d565b9350604086013567ffffffffffffffff80821115611f30575f80fd5b611f3c89838a01611dfc565b94506060880135915080821115611f51575f80fd5b611f5d89838a01611dfc565b93506080880135915080821115611f72575f80fd5b50611f7f88828901611e91565b9150509295509295909350565b5f805f60408486031215611f9e575f80fd5b611fa784611a4d565b9250602084013567ffffffffffffffff811115611fc2575f80fd5b611fce86828701611b5d565b9497909650939450505050565b5f8060408385031215611fec575f80fd5b823567ffffffffffffffff80821115612003575f80fd5b818501915085601f830112612016575f80fd5b8135602061202382611dd9565b6040516120308282611d82565b83815260059390931b850182019282810191508984111561204f575f80fd5b948201945b838610156120745761206586611a4d565b82529482019490820190612054565b96505086013592505080821115612089575f80fd5b5061209685828601611dfc565b9150509250929050565b5f8151808452602080850194508084015f5b838110156120ce578151875295820195908201906001016120b2565b509495945050505050565b602081525f611ac060208301846120a0565b5f80604083850312156120fc575f80fd5b823567ffffffffffffffff80821115612113575f80fd5b61211f86838701611dfc565b93506020850135915080821115612089575f80fd5b5f805f805f805f806080898b03121561214b575f80fd5b883567ffffffffffffffff80821115612162575f80fd5b61216e8c838d01611c0c565b909a50985060208b0135915080821115612186575f80fd5b6121928c838d01611c0c565b909850965060408b01359150808211156121aa575f80fd5b6121b68c838d01611c0c565b909650945060608b01359150808211156121ce575f80fd5b506121db8b828c01611c0c565b999c989b5096995094979396929594505050565b80151581146111c4575f80fd5b5f806040838503121561220d575f80fd5b61221683611a4d565b91506020830135612226816121ef565b809150509250929050565b5f8060408385031215612242575f80fd5b61224b83611a4d565b915061225960208401611a4d565b90509250929050565b5f805f805f60a08688031215612276575f80fd5b61227f86611a4d565b945061228d60208701611a4d565b93506040860135925060608601359150608086013567ffffffffffffffff8111156122b6575f80fd5b611f7f88828901611e91565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f826122f8576122f86122c2565b500490565b5f8261230b5761230b6122c2565b500690565b600181811c9082168061232457607f821691505b60208210810361119257634e487b7160e01b5f52602260045260245ffd5b5f82601f830112612351575f80fd5b815161235c81611e6a565b6040516123698282611d82565b82815285602084870101111561237d575f80fd5b61238e836020830160208801611ac7565b95945050505050565b805160ff81168114611a63575f80fd5b8051611a63816121ef565b805161ffff81168114611a63575f80fd5b5f608082840312156123d3575f80fd5b6040516080810167ffffffffffffffff82821081831117156123f7576123f7611d47565b81604052829350612407856123b2565b8352612415602086016123b2565b6020840152612426604086016123b2565b6040840152606085015191508082111561243e575f80fd5b5061244b85828601612342565b6060830152505092915050565b5f82601f830112612467575f80fd5b6040805161247481611d5b565b80610800850186811115612486575f80fd5b855b8181101561263357805167ffffffffffffffff808211156124a8575f8081fd5b90880190610180828b0312156124bd575f8081fd5b6124c5611daf565b8251815260206124d68185016123b2565b818301526124e58985016123a7565b89830152606080850151848111156124fc575f8081fd5b6125088e828801612342565b82850152505060808085015184811115612521575f8081fd5b61252d8e828801612342565b82850152505060a08085015184811115612546575f8081fd5b6125528e828801612342565b82850152505060c0808501518481111561256b575f8081fd5b6125778e828801612342565b82850152505060e08085015184811115612590575f8081fd5b61259c8e828801612342565b82850152505061010080850151848111156125b6575f8081fd5b6125c28e828801612342565b82850152505061012080850151848111156125dc575f8081fd5b6125e88e828801612342565b828501525050610140808501518184015250610160808501518481111561260e575f8081fd5b61261a8e8288016123c3565b9184019190915250908652909401935050602001612488565b50919695505050505050565b5f6020828403121561264f575f80fd5b815167ffffffffffffffff80821115612666575f80fd5b90830190610180828603121561267a575f80fd5b612682611daf565b82518152602083015182811115612697575f80fd5b6126a387828601612342565b6020830152506040830151828111156126ba575f80fd5b6126c687828601612342565b6040830152506126d860608401612397565b60608201526126e960808401612397565b60808201526126fa60a08401612397565b60a082015261270b60c08401612397565b60c082015261271c60e08401612397565b60e082015261010061272f8185016123a7565b908201526101206127418482016123a7565b908201526101406127538482016123a7565b90820152610160838101518381111561276a575f80fd5b61277688828701612458565b918301919091525095945050505050565b5f61ffff808351168452806020840151166020850152806040840151166040850152506060820151608060608501526127c36080850182611ae9565b949350505050565b5f826108008101835f5b60408082106127e45750612918565b84840388528251610180815186526020808301516128078289018261ffff169052565b508284015180151588860152506060935083830151828589015261282d83890182611ae9565b9450506080915081830151878503838901526128498582611ae9565b94505060a0915081830151878503838901526128658582611ae9565b94505060c0915081830151878503838901526128818582611ae9565b94505060e09150818301518785038389015261289d8582611ae9565b945050610100915081830151878503838901526128ba8582611ae9565b945050610120915081830151878503838901526128d78582611ae9565b61014085810151908a015261016094850151898203868b015290955093925061290290508484612787565b9a81019a965094909401935050506001016127d5565b509095945050505050565b60208152815160208201525f602083015161018080604085015261294b6101a0850183611ae9565b91506040850151601f19808685030160608701526129698483611ae9565b935060608701519150612981608087018360ff169052565b608087015160ff811660a0880152915060a087015160ff811660c0880152915060c087015160ff811660e0880152915060e087015191506101006129c98188018460ff169052565b87015191506101206129de8782018415159052565b87015191506101406129f38782018415159052565b8701519150610160612a088782018415159052565b870151868503909101838701529050612a2183826127cb565b9695505050505050565b5f60208284031215612a3b575f80fd5b815167ffffffffffffffff811115612a51575f80fd5b6127c384828501612342565b8082028115828204841417610507576105076122d6565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215612a98575f80fd5b611ac082611a4d565b5f60018201612ab257612ab26122d6565b5060010190565b80820180821115610507576105076122d6565b60208152816020820152818360408301375f818301604090810191909152601f909201601f19160101919050565b604081525f612b0c60408301856120a0565b828103602084015261238e81856120a0565b5f6001600160a01b03808816835280871660208401525084604083015283606083015260a06080830152612b5560a0830184611ae9565b979650505050505050565b5f60208284031215612b70575f80fd5b8151611ac081611a90565b5f60033d1115612b915760045f803e505f5160e01c5b90565b5f60443d1015612ba15790565b6040516003193d81016004833e81513d67ffffffffffffffff8160248401118184111715612bd157505050505090565b8285019150815181811115612be95750505050505090565b843d8701016020828501011115612c035750505050505090565b61291860208286010187611d82565b5f6001600160a01b03808816835280871660208401525060a06040830152612c3d60a08301866120a0565b8281036060840152612c4f81866120a0565b90508281036080840152612c638185611ae9565b9897505050505050505056fea26469706673582212208f1dec0001dd30a4328452be58dc810cbf520c3cd7e3a40477f8707b3dc8445e64736f6c634300081400330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005000000000000000000000000044a3ccddccae339d05200a8f4347f83a58847e52000000000000000000000000c31328e68ba9770d4c3375fd2b7c79c9904c711f000000000000000000000000c3c7ea560b5533da8eee31212a9595a419e6d63100000000000000000000000097b439db483bb0e02c709b2e948a32ee72daa82d000000000000000000000000b3b5102aee1557135449ec0d514f2b7334769af2000000000000000000000000184a973a0ed40b7c4ee187b844bd1455f2191a1d0000000000000000000000007637dcb54a019a027175964ad845763d3fc3b5cd00000000000000000000000078b05cc4f278662416083dfe211f7496abc3851800000000000000000000000069e68074f1aada957edd39c5eae0069973343f300000000000000000000000004b5fe817488d86f55ab1a4e40598a3cfbde95b6a0000000000000000000000001a1427a73b7cb0f4ea3f71c6c8090c4366c8ebe10000000000000000000000002177da04f9479496c2292d6344d306aa49beb34a000000000000000000000000f0d6999725115e3ead3d927eb3329d63afaec09b000000000000000000000000e11da9560b51f8918295edc5ab9c0a90e9ada20b000000000000000000000000047d0cb513a2ccb1ed44d4af271410a9c8d5248f00000000000000000000000012c29df62b1b254e1311bef777a37bf8c575b58d00000000000000000000000016a2ebd556af2a39eba349be7d6eba7a57c477110000000000000000000000001da5331994e781ab0e2af9f85bfce2037a5141700000000000000000000000001f8615a2caa4c8ab08bf1312e022341022c90e37000000000000000000000000243db4aaa62b3785df27c364090749b96e45f3ec000000000000000000000000324111baf9886e0456d74cef0ecbd49ed0779ee1000000000000000000000000343e73d33639d9c354fa215ca23ffcd0f5604ac1000000000000000000000000367dc97068ab54ba1dfbfc0fad12fbcb7b3a0d090000000000000000000000003c1bee74ff0d159ab06b6113417fc536499057c6000000000000000000000000461a5b8326ba0e2dfd133651a3b559dc8d3b04000000000000000000000000004f55fd3b7ec169a364e34eb7f523ca5ceb12c88800000000000000000000000051787a2c56d710c68140bdadefd3a98bff96feb400000000000000000000000059590178e9eddb027ed87bed9c1da8cd5129fed90000000000000000000000005efdb6d8c798c2c2bea5b1961982a5944f92a5c10000000000000000000000005f45c7ea2e094fea813a8a8813620ffcc4a19d0f000000000000000000000000626ffae9f5537d4fadb6065585213f095b106bfc00000000000000000000000065a4c69f4ea3fea89a0d4156c3d91c787472b67000000000000000000000000067164d8853d3dc9ab5d11cb6744e6f04401cf772000000000000000000000000679d5162bad71990abca0f18095948c12a2756b000000000000000000000000072915ad3110eb31768a562f540ac1ebcd51d3dc800000000000000000000000075432062a9bcc6bc5c294f44a8e3aa65bec8a64d0000000000000000000000007a3cf7122eb2e3f3820f0afaaac4206cdc50bd7e00000000000000000000000081eef2d7c4033c3224660b6a5d4b4a4727f1c762000000000000000000000000881475210e75b814d5b711090a064942b6f30605000000000000000000000000a3e0f18fec11b027bc23fd8a1cac729cffab11d9000000000000000000000000b69cd25391df0b18e6cafe9dd61b966388d6beec000000000000000000000000c0dcce9d4f0e5dbf20dc2631786550dbdeebf756000000000000000000000000c3d1b0445c7d62fdb86e02c467f4239478b37f20000000000000000000000000c8f8e2f59dd95ff67c3d39109eca2e2a017d4c8a000000000000000000000000d52fba65a52214a65c78dc7f95c9fee1f13a5955000000000000000000000000e2601273be4c89a729a3fe0af4bd6503bb20c27c000000000000000000000000e3603cf313dcd49cc3061c9850a474d40aa81159000000000000000000000000e5b0a257f0420ed4860d5d431e6ad6744da08405000000000000000000000000f035af8a3dff1f90aeb21f9623589ae1330e9e09000000000000000000000000fc8f57a04f4df6f167599162bf5fdaa098ac18cc000000000000000000000000962a7d642178c87eeec92240669ec98f868dc54e000000000000000000000000a5af072b89525ef22b60bb1aa2107a48f35d0cfe0000000000000000000000005d802e2fe48392c104ce0401c7eca8a4456f1f16000000000000000000000000aec4075e4fc8ce829bc4f0cfd5e2fa10dd2b12d1000000000000000000000000463fc06d16e146ec9e4cb2ab8c3077732c75f38b00000000000000000000000081590c16b9d1495d133cf881acf5cc0b56730b740000000000000000000000001aae1bc09e1785c8cb00650db0c6015bd73b0c7e000000000000000000000000c3f1d077fa590018d3924ce8da1a085b4eae506d0000000000000000000000008715ed9bbd4f8cfbed14f045556f19f39f11c75b000000000000000000000000d5a06056701c7cfba12b1a384294148b9d2d8bca0000000000000000000000009027bd5b0d32b0cb51dce93e8add64aca3a2491200000000000000000000000099b8226ec774c957ffe2747fdfbae8f22741e8990000000000000000000000009c81559aac49da60ff1e7755436dc2924d1a4c4f00000000000000000000000036ed861a319278e5b6c39028884b0ca93df105d0000000000000000000000000b2d2ecc7d94cfb8e70f60aeb97bf7f4c4cb8ef28000000000000000000000000c2322d5e0cb1dc57695ecae84e5f6868c17f1cb7000000000000000000000000b379b56bcacdd58ae0768654763881849bfaad94000000000000000000000000d2dea18d040152c580f29195b29670633b0c979600000000000000000000000036041d9f21901599b9825bf4ecdf03aee81be0a600000000000000000000000092890034a3dcb1c38c1184775788ba0f95c23f03000000000000000000000000cd64a3e77335b652f8582e081f02bf9c90f908a40000000000000000000000003348de5cc020eefa5d3b8212aefbc0c19d315f24000000000000000000000000d8208bbf403a5de65a61e45321580fd0e31d4432000000000000000000000000f6e9ccea1f646fee85e13ab3361c75959a94d5b000000000000000000000000097a6d7365e64d56b8a9aede0096a0fa2ace4eebc0000000000000000000000009adccfd429a7ba40e7945841164ea2cffa7611fd0000000000000000000000003689c216f8f6ce7e2ce2a27c81a23096a787f532000000000000000000000000d2498b4dc8402789736f7c94caf969ea65badfa20000000000000000000000000d0e328b8fbc4a148eeae9e7b4791d7a6a0d2d07000000000000000000000000f56345338cb4cddaf915ebef3bfde63e70fe3053

Deployed Bytecode

0x60806040526004361061016f575f3560e01c806344b285db116100c65780639c095f561161007c578063bd85b03911610057578063bd85b039146103ad578063e985e9c5146103cd578063f242432a146103ee575f80fd5b80639c095f561461035a578063a035b1fe14610379578063a22cb4651461038e575f80fd5b80634e840992116100ac5780634e8409921461031457806368987a831461033357806395d89b4114610346575f80fd5b806344b285db146102c95780634e1273f4146102e8575f80fd5b806318160ddd116101265780632bfc3052116101015780632bfc3052146102845780632eb2c2d6146102975780633f6b5fde146102b6575f80fd5b806318160ddd1461024b57806325431b181461025e578063262fb60814610271575f80fd5b806306fdde031161015657806306fdde03146101ec5780630e89341c1461020d57806310981eb31461022c575f80fd5b8062fdd58e1461018b57806301ffc9a7146101bd575f80fd5b36610187576101853361018061040d565b610463565b005b5f80fd5b348015610196575f80fd5b506101aa6101a5366004611a68565b6104cf565b6040519081526020015b60405180910390f35b3480156101c8575f80fd5b506101dc6101d7366004611aa5565b61050d565b60405190151581526020016101b4565b3480156101f7575f80fd5b506102006105a7565b6040516101b49190611b14565b348015610218575f80fd5b50610200610227366004611b26565b610633565b348015610237575f80fd5b50610185610246366004611b3d565b610726565b348015610256575f80fd5b505f196101aa565b61018561026c366004611ba2565b61074c565b61018561027f366004611c4d565b610773565b610185610292366004611ce0565b610898565b3480156102a2575f80fd5b506101856102b1366004611ee9565b610928565b6101856102c4366004611f8c565b61099d565b3480156102d4575f80fd5b506102006102e3366004611b26565b6109be565b3480156102f3575f80fd5b50610307610302366004611fdb565b610a13565b6040516101b491906120d9565b34801561031f575f80fd5b5061018561032e3660046120eb565b610b4f565b610185610341366004612134565b610b96565b348015610351575f80fd5b50610200610c90565b348015610365575f80fd5b50610185610374366004611b3d565b610c9d565b348015610384575f80fd5b506101aa60035481565b348015610399575f80fd5b506101856103a83660046121fc565b610cc9565b3480156103b8575f80fd5b506101aa6103c7366004611b26565b505f1990565b3480156103d8575f80fd5b506101dc6103e7366004612231565b5f92915050565b3480156103f9575f80fd5b50610185610408366004612262565b610d11565b5f44335a6040516020016104469392919092835260609190911b6bffffffffffffffffffffffff19166020830152603482015260540190565b604051602081830303815290604052805190602001205f1c905090565b5f6003543461047291906122ea565b90505f6003543461048391906122fd565b9050815f036104a5576040516328df225d60e01b815260040160405180910390fd5b6104bf84848460405180602001604052805f815250610d81565b6104c98482610e8c565b50505050565b5f6001600160a01b0383166104e557505f610507565b505f818152602081815260408083206001600160a01b03861684529091529020545b92915050565b5f6001600160e01b031982167fd9b67a2600000000000000000000000000000000000000000000000000000000148061056f57506001600160e01b031982167f0e89341c00000000000000000000000000000000000000000000000000000000145b8061050757507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b0319831614610507565b600180546105b490612310565b80601f01602080910402602001604051908101604052809291908181526020018280546105e090612310565b801561062b5780601f106106025761010080835404028352916020019161062b565b820191905f5260205f20905b81548152906001019060200180831161060e57829003601f168201915b505050505081565b60607312b7f0e2f3d562b0cd012bd58e2d620bfdfe542f634afd561b73b0047233de84066b491f093380b8ca3cff4f733363b4b5b48f856040518263ffffffff1660e01b815260040161068891815260200190565b5f60405180830381865af41580156106a2573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526106c9919081019061263f565b6040518263ffffffff1660e01b81526004016106e59190612923565b5f60405180830381865af41580156106ff573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526105079190810190612a2b565b610731338383610f56565b61074833600354836107439190612a5d565b610e8c565b5050565b610756838661109a565b6107608484610463565b61076c84848484611101565b5050505050565b6107ae8282808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525061114d92505050565b6107e98585808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525061114d92505050565b146108075760405163b4fa3fb360e01b815260040160405180910390fd5b845f5b8181101561088e5761084d3389898481811061082857610828612a74565b9050602002013588888581811061084157610841612a74565b90506020020135610f56565b6108863361085961040d565b86868581811061086b5761086b612a74565b9050602002013560405180602001604052805f815250610d81565b60010161080a565b5050505050505050565b6108db6108d68383808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525061114d92505050565b611198565b825f5b81811015610920576109188686838181106108fb576108fb612a74565b90506020020160208101906109109190612a88565b61085961040d565b6001016108de565b505050505050565b6001600160a01b03851633146109905760405162461bcd60e51b815260206004820152602260248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201526132b960f11b60648201526084015b60405180910390fd5b61076c85858585856111c7565b5f6109a661040d565b90506109b28482610463565b6104c984828585611101565b606073c6b17cafcc2439ef4833fe6a073ba71438112f8763929ecd9d73b0047233de84066b491f093380b8ca3cff4f733363b4b5b48f856040518263ffffffff1660e01b815260040161068891815260200190565b60608151835114610a8c5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d6174636800000000000000000000000000000000000000000000006064820152608401610987565b5f835167ffffffffffffffff811115610aa757610aa7611d47565b604051908082528060200260200182016040528015610ad0578160200160208202803683370190505b5090505f5b8451811015610b4757610b1a858281518110610af357610af3612a74565b6020026020010151858381518110610b0d57610b0d612a74565b60200260200101516104cf565b828281518110610b2c57610b2c612a74565b6020908102919091010152610b4081612aa1565b9050610ad5565b509392505050565b8051825114610b715760405163b4fa3fb360e01b815260040160405180910390fd5b610b7c338383611417565b61074833600354610b8c8461114d565b6107439190612a5d565b610bd46108d68383808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525061114d92505050565b865f5b81811015610c8457610c27868683818110610bf457610bf4612a74565b905060200201358b8b84818110610c0d57610c0d612a74565b9050602002016020810190610c229190612a88565b61109a565b610c7c888883818110610c3c57610c3c612a74565b9050602002016020810190610c519190612a88565b878784818110610c6357610c63612a74565b9050602002013586868581811061086b5761086b612a74565b600101610bd7565b50505050505050505050565b600280546105b490612310565b610ca8338383610f56565b61074833610cb461040d565b8360405180602001604052805f815250610d81565b60405162461bcd60e51b815260206004820152601a60248201527f4e6f20617070726f76616c73206f6e20696e66696e69746965730000000000006044820152606401610987565b6001600160a01b0385163314610d745760405162461bcd60e51b815260206004820152602260248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201526132b960f11b6064820152608401610987565b61076c8585858585611628565b6001600160a01b038416610dfd5760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610987565b5f838152602081815260408083206001600160a01b0388168452909152812080543392859291610e2e908490612ab9565b909155505060408051858152602081018590526001600160a01b03808816925f92918516917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461076c815f878787876117a5565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114610ed5576040519150601f19603f3d011682016040523d82523d5f602084013e610eda565b606091505b5050905080610f515760405162461bcd60e51b815260206004820152603160248201527f556e61626c6520746f2073656e642076616c75652c20726563697069656e742060448201527f6d617920686176652072657665727465640000000000000000000000000000006064820152608401610987565b505050565b6001600160a01b038316610fb85760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b6064820152608401610987565b5f828152602081815260408083206001600160a01b0387168452909152902054818110156110345760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b6064820152608401610987565b5f838152602081815260408083206001600160a01b038816808552908352818420868603905581518781529283018690529133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6291015b60405180910390a450505050565b5f806110a683856104cf565b1190508015816110ca57503373c8f8e2f59dd95ff67c3d39109eca2e2a017d4c8a14155b15610f51576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80156104c95782846001600160a01b0316336001600160a01b03167fdd99aef5e4fdfad84059320be40f5dc0f015dc4025f56bd4010608c6743bc22e858560405161108c929190612acc565b5f805b82518110156111925782818151811061116b5761116b612a74565b60200260200101518261117e9190612ab9565b91508061118a81612aa1565b915050611150565b50919050565b6003546111a59082612a5d565b34146111c4576040516328df225d60e01b815260040160405180910390fd5b50565b81518351146112295760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b6064820152608401610987565b6001600160a01b03841661128d5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610987565b5f5b83518110156113b1575f8482815181106112ab576112ab612a74565b602002602001015190505f8483815181106112c8576112c8612a74565b6020908102919091018101515f84815280835260408082206001600160a01b038d16835290935291909120549091508181101561135a5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201526939103a3930b739b332b960b11b6064820152608401610987565b5f838152602081815260408083206001600160a01b038d8116855292528083208585039055908a16825281208054849290611396908490612ab9565b92505081905550505050806113aa90612aa1565b905061128f565b50836001600160a01b0316856001600160a01b0316866001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051611401929190612afa565b60405180910390a461076c858686868686611952565b6001600160a01b0383166114795760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b6064820152608401610987565b80518251146114db5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b6064820152608401610987565b335f5b83518110156115d8575f8482815181106114fa576114fa612a74565b602002602001015190505f84838151811061151757611517612a74565b6020908102919091018101515f84815280835260408082206001600160a01b038c1683529093529190912054909150818110156115a25760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b6064820152608401610987565b5f928352602083815260408085206001600160a01b038b16865290915290922091039055806115d081612aa1565b9150506114de565b505f6001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb868660405161108c929190612afa565b6001600160a01b03841661168c5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610987565b5f838152602081815260408083206001600160a01b03891684529091529020548281101561170f5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201526939103a3930b739b332b960b11b6064820152608401610987565b5f848152602081815260408083206001600160a01b038a811685529252808320868503905590871682528120805485929061174b908490612ab9565b909155505060408051858152602081018590526001600160a01b03808816929089169182917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46109208687878787875b6001600160a01b0384163b156109205760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906117e99089908990889088908890600401612b1e565b6020604051808303815f875af1925050508015611823575060408051601f3d908101601f1916820190925261182091810190612b60565b60015b6118d85761182f612b7b565b806308c379a0036118685750611843612b94565b8061184e575061186a565b8060405162461bcd60e51b81526004016109879190611b14565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560448201527f526563656976657220696d706c656d656e7465720000000000000000000000006064820152608401610987565b6001600160e01b0319811663f23a6e6160e01b146119495760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b6064820152608401610987565b50505050505050565b6001600160a01b0384163b156109205760405163bc197c8160e01b81526001600160a01b0385169063bc197c81906119969089908990889088908890600401612c12565b6020604051808303815f875af19250505080156119d0575060408051601f3d908101601f191682019092526119cd91810190612b60565b60015b6119dc5761182f612b7b565b6001600160e01b0319811663bc197c8160e01b146119495760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b6064820152608401610987565b80356001600160a01b0381168114611a63575f80fd5b919050565b5f8060408385031215611a79575f80fd5b611a8283611a4d565b946020939093013593505050565b6001600160e01b0319811681146111c4575f80fd5b5f60208284031215611ab5575f80fd5b8135611ac081611a90565b9392505050565b5f5b83811015611ae1578181015183820152602001611ac9565b50505f910152565b5f8151808452611b00816020860160208601611ac7565b601f01601f19169290920160200192915050565b602081525f611ac06020830184611ae9565b5f60208284031215611b36575f80fd5b5035919050565b5f8060408385031215611b4e575f80fd5b50508035926020909101359150565b5f8083601f840112611b6d575f80fd5b50813567ffffffffffffffff811115611b84575f80fd5b602083019150836020828501011115611b9b575f80fd5b9250929050565b5f805f805f60808688031215611bb6575f80fd5b611bbf86611a4d565b9450611bcd60208701611a4d565b935060408601359250606086013567ffffffffffffffff811115611bef575f80fd5b611bfb88828901611b5d565b969995985093965092949392505050565b5f8083601f840112611c1c575f80fd5b50813567ffffffffffffffff811115611c33575f80fd5b6020830191508360208260051b8501011115611b9b575f80fd5b5f805f805f8060608789031215611c62575f80fd5b863567ffffffffffffffff80821115611c79575f80fd5b611c858a838b01611c0c565b90985096506020890135915080821115611c9d575f80fd5b611ca98a838b01611c0c565b90965094506040890135915080821115611cc1575f80fd5b50611cce89828a01611c0c565b979a9699509497509295939492505050565b5f805f8060408587031215611cf3575f80fd5b843567ffffffffffffffff80821115611d0a575f80fd5b611d1688838901611c0c565b90965094506020870135915080821115611d2e575f80fd5b50611d3b87828801611c0c565b95989497509550505050565b634e487b7160e01b5f52604160045260245ffd5b610800810181811067ffffffffffffffff82111715611d7c57611d7c611d47565b60405250565b601f8201601f1916810167ffffffffffffffff81118282101715611da857611da8611d47565b6040525050565b604051610180810167ffffffffffffffff81118282101715611dd357611dd3611d47565b60405290565b5f67ffffffffffffffff821115611df257611df2611d47565b5060051b60200190565b5f82601f830112611e0b575f80fd5b81356020611e1882611dd9565b604051611e258282611d82565b83815260059390931b8501820192828101915086841115611e44575f80fd5b8286015b84811015611e5f5780358352918301918301611e48565b509695505050505050565b5f67ffffffffffffffff821115611e8357611e83611d47565b50601f01601f191660200190565b5f82601f830112611ea0575f80fd5b8135611eab81611e6a565b604051611eb88282611d82565b828152856020848701011115611ecc575f80fd5b826020860160208301375f92810160200192909252509392505050565b5f805f805f60a08688031215611efd575f80fd5b611f0686611a4d565b9450611f1460208701611a4d565b9350604086013567ffffffffffffffff80821115611f30575f80fd5b611f3c89838a01611dfc565b94506060880135915080821115611f51575f80fd5b611f5d89838a01611dfc565b93506080880135915080821115611f72575f80fd5b50611f7f88828901611e91565b9150509295509295909350565b5f805f60408486031215611f9e575f80fd5b611fa784611a4d565b9250602084013567ffffffffffffffff811115611fc2575f80fd5b611fce86828701611b5d565b9497909650939450505050565b5f8060408385031215611fec575f80fd5b823567ffffffffffffffff80821115612003575f80fd5b818501915085601f830112612016575f80fd5b8135602061202382611dd9565b6040516120308282611d82565b83815260059390931b850182019282810191508984111561204f575f80fd5b948201945b838610156120745761206586611a4d565b82529482019490820190612054565b96505086013592505080821115612089575f80fd5b5061209685828601611dfc565b9150509250929050565b5f8151808452602080850194508084015f5b838110156120ce578151875295820195908201906001016120b2565b509495945050505050565b602081525f611ac060208301846120a0565b5f80604083850312156120fc575f80fd5b823567ffffffffffffffff80821115612113575f80fd5b61211f86838701611dfc565b93506020850135915080821115612089575f80fd5b5f805f805f805f806080898b03121561214b575f80fd5b883567ffffffffffffffff80821115612162575f80fd5b61216e8c838d01611c0c565b909a50985060208b0135915080821115612186575f80fd5b6121928c838d01611c0c565b909850965060408b01359150808211156121aa575f80fd5b6121b68c838d01611c0c565b909650945060608b01359150808211156121ce575f80fd5b506121db8b828c01611c0c565b999c989b5096995094979396929594505050565b80151581146111c4575f80fd5b5f806040838503121561220d575f80fd5b61221683611a4d565b91506020830135612226816121ef565b809150509250929050565b5f8060408385031215612242575f80fd5b61224b83611a4d565b915061225960208401611a4d565b90509250929050565b5f805f805f60a08688031215612276575f80fd5b61227f86611a4d565b945061228d60208701611a4d565b93506040860135925060608601359150608086013567ffffffffffffffff8111156122b6575f80fd5b611f7f88828901611e91565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f826122f8576122f86122c2565b500490565b5f8261230b5761230b6122c2565b500690565b600181811c9082168061232457607f821691505b60208210810361119257634e487b7160e01b5f52602260045260245ffd5b5f82601f830112612351575f80fd5b815161235c81611e6a565b6040516123698282611d82565b82815285602084870101111561237d575f80fd5b61238e836020830160208801611ac7565b95945050505050565b805160ff81168114611a63575f80fd5b8051611a63816121ef565b805161ffff81168114611a63575f80fd5b5f608082840312156123d3575f80fd5b6040516080810167ffffffffffffffff82821081831117156123f7576123f7611d47565b81604052829350612407856123b2565b8352612415602086016123b2565b6020840152612426604086016123b2565b6040840152606085015191508082111561243e575f80fd5b5061244b85828601612342565b6060830152505092915050565b5f82601f830112612467575f80fd5b6040805161247481611d5b565b80610800850186811115612486575f80fd5b855b8181101561263357805167ffffffffffffffff808211156124a8575f8081fd5b90880190610180828b0312156124bd575f8081fd5b6124c5611daf565b8251815260206124d68185016123b2565b818301526124e58985016123a7565b89830152606080850151848111156124fc575f8081fd5b6125088e828801612342565b82850152505060808085015184811115612521575f8081fd5b61252d8e828801612342565b82850152505060a08085015184811115612546575f8081fd5b6125528e828801612342565b82850152505060c0808501518481111561256b575f8081fd5b6125778e828801612342565b82850152505060e08085015184811115612590575f8081fd5b61259c8e828801612342565b82850152505061010080850151848111156125b6575f8081fd5b6125c28e828801612342565b82850152505061012080850151848111156125dc575f8081fd5b6125e88e828801612342565b828501525050610140808501518184015250610160808501518481111561260e575f8081fd5b61261a8e8288016123c3565b9184019190915250908652909401935050602001612488565b50919695505050505050565b5f6020828403121561264f575f80fd5b815167ffffffffffffffff80821115612666575f80fd5b90830190610180828603121561267a575f80fd5b612682611daf565b82518152602083015182811115612697575f80fd5b6126a387828601612342565b6020830152506040830151828111156126ba575f80fd5b6126c687828601612342565b6040830152506126d860608401612397565b60608201526126e960808401612397565b60808201526126fa60a08401612397565b60a082015261270b60c08401612397565b60c082015261271c60e08401612397565b60e082015261010061272f8185016123a7565b908201526101206127418482016123a7565b908201526101406127538482016123a7565b90820152610160838101518381111561276a575f80fd5b61277688828701612458565b918301919091525095945050505050565b5f61ffff808351168452806020840151166020850152806040840151166040850152506060820151608060608501526127c36080850182611ae9565b949350505050565b5f826108008101835f5b60408082106127e45750612918565b84840388528251610180815186526020808301516128078289018261ffff169052565b508284015180151588860152506060935083830151828589015261282d83890182611ae9565b9450506080915081830151878503838901526128498582611ae9565b94505060a0915081830151878503838901526128658582611ae9565b94505060c0915081830151878503838901526128818582611ae9565b94505060e09150818301518785038389015261289d8582611ae9565b945050610100915081830151878503838901526128ba8582611ae9565b945050610120915081830151878503838901526128d78582611ae9565b61014085810151908a015261016094850151898203868b015290955093925061290290508484612787565b9a81019a965094909401935050506001016127d5565b509095945050505050565b60208152815160208201525f602083015161018080604085015261294b6101a0850183611ae9565b91506040850151601f19808685030160608701526129698483611ae9565b935060608701519150612981608087018360ff169052565b608087015160ff811660a0880152915060a087015160ff811660c0880152915060c087015160ff811660e0880152915060e087015191506101006129c98188018460ff169052565b87015191506101206129de8782018415159052565b87015191506101406129f38782018415159052565b8701519150610160612a088782018415159052565b870151868503909101838701529050612a2183826127cb565b9695505050505050565b5f60208284031215612a3b575f80fd5b815167ffffffffffffffff811115612a51575f80fd5b6127c384828501612342565b8082028115828204841417610507576105076122d6565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215612a98575f80fd5b611ac082611a4d565b5f60018201612ab257612ab26122d6565b5060010190565b80820180821115610507576105076122d6565b60208152816020820152818360408301375f818301604090810191909152601f909201601f19160101919050565b604081525f612b0c60408301856120a0565b828103602084015261238e81856120a0565b5f6001600160a01b03808816835280871660208401525084604083015283606083015260a06080830152612b5560a0830184611ae9565b979650505050505050565b5f60208284031215612b70575f80fd5b8151611ac081611a90565b5f60033d1115612b915760045f803e505f5160e01c5b90565b5f60443d1015612ba15790565b6040516003193d81016004833e81513d67ffffffffffffffff8160248401118184111715612bd157505050505090565b8285019150815181811115612be95750505050505090565b843d8701016020828501011115612c035750505050505090565b61291860208286010187611d82565b5f6001600160a01b03808816835280871660208401525060a06040830152612c3d60a08301866120a0565b8281036060840152612c4f81866120a0565b90508281036080840152612c638185611ae9565b9897505050505050505056fea26469706673582212208f1dec0001dd30a4328452be58dc810cbf520c3cd7e3a40477f8707b3dc8445e64736f6c63430008140033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005000000000000000000000000044a3ccddccae339d05200a8f4347f83a58847e52000000000000000000000000c31328e68ba9770d4c3375fd2b7c79c9904c711f000000000000000000000000c3c7ea560b5533da8eee31212a9595a419e6d63100000000000000000000000097b439db483bb0e02c709b2e948a32ee72daa82d000000000000000000000000b3b5102aee1557135449ec0d514f2b7334769af2000000000000000000000000184a973a0ed40b7c4ee187b844bd1455f2191a1d0000000000000000000000007637dcb54a019a027175964ad845763d3fc3b5cd00000000000000000000000078b05cc4f278662416083dfe211f7496abc3851800000000000000000000000069e68074f1aada957edd39c5eae0069973343f300000000000000000000000004b5fe817488d86f55ab1a4e40598a3cfbde95b6a0000000000000000000000001a1427a73b7cb0f4ea3f71c6c8090c4366c8ebe10000000000000000000000002177da04f9479496c2292d6344d306aa49beb34a000000000000000000000000f0d6999725115e3ead3d927eb3329d63afaec09b000000000000000000000000e11da9560b51f8918295edc5ab9c0a90e9ada20b000000000000000000000000047d0cb513a2ccb1ed44d4af271410a9c8d5248f00000000000000000000000012c29df62b1b254e1311bef777a37bf8c575b58d00000000000000000000000016a2ebd556af2a39eba349be7d6eba7a57c477110000000000000000000000001da5331994e781ab0e2af9f85bfce2037a5141700000000000000000000000001f8615a2caa4c8ab08bf1312e022341022c90e37000000000000000000000000243db4aaa62b3785df27c364090749b96e45f3ec000000000000000000000000324111baf9886e0456d74cef0ecbd49ed0779ee1000000000000000000000000343e73d33639d9c354fa215ca23ffcd0f5604ac1000000000000000000000000367dc97068ab54ba1dfbfc0fad12fbcb7b3a0d090000000000000000000000003c1bee74ff0d159ab06b6113417fc536499057c6000000000000000000000000461a5b8326ba0e2dfd133651a3b559dc8d3b04000000000000000000000000004f55fd3b7ec169a364e34eb7f523ca5ceb12c88800000000000000000000000051787a2c56d710c68140bdadefd3a98bff96feb400000000000000000000000059590178e9eddb027ed87bed9c1da8cd5129fed90000000000000000000000005efdb6d8c798c2c2bea5b1961982a5944f92a5c10000000000000000000000005f45c7ea2e094fea813a8a8813620ffcc4a19d0f000000000000000000000000626ffae9f5537d4fadb6065585213f095b106bfc00000000000000000000000065a4c69f4ea3fea89a0d4156c3d91c787472b67000000000000000000000000067164d8853d3dc9ab5d11cb6744e6f04401cf772000000000000000000000000679d5162bad71990abca0f18095948c12a2756b000000000000000000000000072915ad3110eb31768a562f540ac1ebcd51d3dc800000000000000000000000075432062a9bcc6bc5c294f44a8e3aa65bec8a64d0000000000000000000000007a3cf7122eb2e3f3820f0afaaac4206cdc50bd7e00000000000000000000000081eef2d7c4033c3224660b6a5d4b4a4727f1c762000000000000000000000000881475210e75b814d5b711090a064942b6f30605000000000000000000000000a3e0f18fec11b027bc23fd8a1cac729cffab11d9000000000000000000000000b69cd25391df0b18e6cafe9dd61b966388d6beec000000000000000000000000c0dcce9d4f0e5dbf20dc2631786550dbdeebf756000000000000000000000000c3d1b0445c7d62fdb86e02c467f4239478b37f20000000000000000000000000c8f8e2f59dd95ff67c3d39109eca2e2a017d4c8a000000000000000000000000d52fba65a52214a65c78dc7f95c9fee1f13a5955000000000000000000000000e2601273be4c89a729a3fe0af4bd6503bb20c27c000000000000000000000000e3603cf313dcd49cc3061c9850a474d40aa81159000000000000000000000000e5b0a257f0420ed4860d5d431e6ad6744da08405000000000000000000000000f035af8a3dff1f90aeb21f9623589ae1330e9e09000000000000000000000000fc8f57a04f4df6f167599162bf5fdaa098ac18cc000000000000000000000000962a7d642178c87eeec92240669ec98f868dc54e000000000000000000000000a5af072b89525ef22b60bb1aa2107a48f35d0cfe0000000000000000000000005d802e2fe48392c104ce0401c7eca8a4456f1f16000000000000000000000000aec4075e4fc8ce829bc4f0cfd5e2fa10dd2b12d1000000000000000000000000463fc06d16e146ec9e4cb2ab8c3077732c75f38b00000000000000000000000081590c16b9d1495d133cf881acf5cc0b56730b740000000000000000000000001aae1bc09e1785c8cb00650db0c6015bd73b0c7e000000000000000000000000c3f1d077fa590018d3924ce8da1a085b4eae506d0000000000000000000000008715ed9bbd4f8cfbed14f045556f19f39f11c75b000000000000000000000000d5a06056701c7cfba12b1a384294148b9d2d8bca0000000000000000000000009027bd5b0d32b0cb51dce93e8add64aca3a2491200000000000000000000000099b8226ec774c957ffe2747fdfbae8f22741e8990000000000000000000000009c81559aac49da60ff1e7755436dc2924d1a4c4f00000000000000000000000036ed861a319278e5b6c39028884b0ca93df105d0000000000000000000000000b2d2ecc7d94cfb8e70f60aeb97bf7f4c4cb8ef28000000000000000000000000c2322d5e0cb1dc57695ecae84e5f6868c17f1cb7000000000000000000000000b379b56bcacdd58ae0768654763881849bfaad94000000000000000000000000d2dea18d040152c580f29195b29670633b0c979600000000000000000000000036041d9f21901599b9825bf4ecdf03aee81be0a600000000000000000000000092890034a3dcb1c38c1184775788ba0f95c23f03000000000000000000000000cd64a3e77335b652f8582e081f02bf9c90f908a40000000000000000000000003348de5cc020eefa5d3b8212aefbc0c19d315f24000000000000000000000000d8208bbf403a5de65a61e45321580fd0e31d4432000000000000000000000000f6e9ccea1f646fee85e13ab3361c75959a94d5b000000000000000000000000097a6d7365e64d56b8a9aede0096a0fa2ace4eebc0000000000000000000000009adccfd429a7ba40e7945841164ea2cffa7611fd0000000000000000000000003689c216f8f6ce7e2ce2a27c81a23096a787f532000000000000000000000000d2498b4dc8402789736f7c94caf969ea65badfa20000000000000000000000000d0e328b8fbc4a148eeae9e7b4791d7a6a0d2d07000000000000000000000000f56345338cb4cddaf915ebef3bfde63e70fe3053

-----Decoded View---------------
Arg [0] : genesisRecipients (address[]): 0x44a3CCddccae339D05200a8f4347F83A58847E52,0xc31328e68bA9770D4C3375FD2B7c79C9904c711f,0xc3c7Ea560b5533DA8EEE31212a9595A419e6D631,0x97B439DB483bB0E02c709b2E948a32Ee72dAa82D,0xB3b5102aee1557135449eC0D514f2b7334769af2,0x184A973A0Ed40b7C4EE187b844bd1455F2191a1d,0x7637DCB54a019A027175964aD845763d3fC3b5cd,0x78b05cC4f278662416083dfE211f7496ABc38518,0x69E68074f1aadA957eDd39c5EAE0069973343f30,0x4B5fE817488D86F55aB1A4e40598a3cFbDE95b6a,0x1a1427A73b7Cb0F4ea3F71C6c8090c4366c8eBe1,0x2177dA04f9479496c2292D6344d306aA49BeB34A,0xf0D6999725115E3EAd3D927Eb3329D63AFAEC09b,0xe11Da9560b51f8918295edC5ab9c0a90E9ADa20B,0x047d0cB513A2CcB1ED44d4aF271410A9C8D5248F,0x12C29df62b1b254e1311Bef777a37Bf8C575b58D,0x16a2EBd556Af2a39eBa349be7D6eba7A57c47711,0x1DA5331994e781AB0E2AF9f85bfce2037A514170,0x1f8615a2caa4c8ab08bf1312e022341022C90e37,0x243db4aAa62b3785DF27c364090749B96E45f3Ec,0x324111bAF9886E0456d74ceF0ECbd49Ed0779ee1,0x343e73D33639d9c354FA215cA23fFCd0F5604Ac1,0x367dC97068aB54bA1dFBFC0fad12FBCB7B3A0d09,0x3c1BEE74Ff0D159AB06B6113417fc536499057C6,0x461A5B8326bA0e2DFd133651A3b559Dc8d3B0400,0x4f55FD3B7EC169a364E34Eb7f523Ca5CEB12C888,0x51787a2C56d710c68140bdAdeFD3A98BfF96FeB4,0x59590178E9eddb027eD87bEd9c1da8Cd5129fEd9,0x5efdB6D8c798c2c2Bea5b1961982a5944F92a5C1,0x5f45C7EA2E094FeA813A8a8813620FFCC4A19d0f,0x626ffAe9f5537d4faDB6065585213f095b106bfC,0x65a4C69f4EA3fEA89a0D4156c3D91C787472b670,0x67164D8853D3dC9Ab5d11cB6744e6f04401cf772,0x679d5162BaD71990ABCA0f18095948c12a2756B0,0x72915ad3110Eb31768A562F540aC1ebcd51d3Dc8,0x75432062a9bCc6bc5C294F44a8E3aa65bec8a64d,0x7A3Cf7122EB2E3F3820f0aFaaaC4206CDc50Bd7e,0x81Eef2d7C4033C3224660B6a5D4B4A4727f1c762,0x881475210E75b814D5b711090a064942b6f30605,0xa3E0F18FeC11B027bC23Fd8a1cac729CffaB11D9,0xB69cD25391Df0b18E6cafe9dd61B966388d6BEec,0xc0dccE9D4F0e5dBF20DC2631786550dBDEEBF756,0xC3D1b0445C7D62FdB86e02C467f4239478b37F20,0xc8f8e2F59Dd95fF67c3d39109ecA2e2A017D4c8a,0xD52fbA65a52214A65C78Dc7f95c9FeE1F13a5955,0xe2601273Be4c89A729a3fe0Af4BD6503BB20c27C,0xe3603cf313Dcd49CC3061C9850a474d40aa81159,0xE5b0a257f0420eD4860D5D431e6aD6744dA08405,0xf035Af8a3dFf1f90aeb21F9623589AE1330E9e09,0xFc8f57A04F4dF6F167599162BF5FDAA098Ac18CC,0x962A7D642178C87EeeC92240669Ec98f868DC54e,0xa5AF072B89525ef22B60bB1aA2107a48f35D0Cfe,0x5D802e2Fe48392c104Ce0401C7ECa8a4456f1F16,0xAEC4075e4fc8cE829BC4f0cFD5e2fA10dd2b12D1,0x463fC06d16E146eC9E4Cb2aB8C3077732c75F38B,0x81590c16B9d1495D133CF881AcF5cc0B56730b74,0x1aaE1bC09E1785C8CB00650db0c6015BD73b0C7E,0xC3f1D077fa590018d3924ce8dA1a085b4eaE506D,0x8715Ed9BbD4F8cfbed14F045556f19F39f11C75b,0xd5A06056701c7CFba12B1a384294148b9D2D8bCa,0x9027Bd5B0D32b0CB51dCE93E8aDd64aCA3a24912,0x99B8226ec774c957Ffe2747fDFBAE8F22741e899,0x9c81559AAc49DA60fF1e7755436DC2924d1A4C4F,0x36eD861a319278e5B6C39028884b0ca93df105D0,0xB2D2ECC7d94CFb8e70F60AeB97Bf7F4C4cB8eF28,0xc2322d5E0cB1Dc57695ECAE84E5f6868C17F1CB7,0xb379B56bcACdD58Ae0768654763881849bFAAd94,0xd2dea18D040152c580F29195B29670633b0C9796,0x36041D9F21901599B9825bF4EcDf03aEe81be0a6,0x92890034a3dCB1c38C1184775788bA0f95C23f03,0xcD64A3e77335B652f8582e081F02bf9c90f908A4,0x3348de5CC020eEfA5D3b8212aEfbC0c19d315f24,0xd8208BBF403a5De65a61E45321580Fd0e31D4432,0xf6E9ccEA1f646FEE85e13Ab3361c75959A94D5b0,0x97a6d7365E64d56b8a9AEDe0096a0FA2aCe4eeBc,0x9aDccfD429A7Ba40E7945841164eA2Cffa7611Fd,0x3689c216f8f6ce7e2CE2a27c81a23096A787F532,0xd2498b4Dc8402789736F7C94CAf969eA65BadFa2,0x0D0E328B8fBc4a148Eeae9E7b4791D7A6A0D2d07,0xf56345338Cb4CddaF915ebeF3bfde63E70FE3053

-----Encoded View---------------
82 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000050
Arg [2] : 00000000000000000000000044a3ccddccae339d05200a8f4347f83a58847e52
Arg [3] : 000000000000000000000000c31328e68ba9770d4c3375fd2b7c79c9904c711f
Arg [4] : 000000000000000000000000c3c7ea560b5533da8eee31212a9595a419e6d631
Arg [5] : 00000000000000000000000097b439db483bb0e02c709b2e948a32ee72daa82d
Arg [6] : 000000000000000000000000b3b5102aee1557135449ec0d514f2b7334769af2
Arg [7] : 000000000000000000000000184a973a0ed40b7c4ee187b844bd1455f2191a1d
Arg [8] : 0000000000000000000000007637dcb54a019a027175964ad845763d3fc3b5cd
Arg [9] : 00000000000000000000000078b05cc4f278662416083dfe211f7496abc38518
Arg [10] : 00000000000000000000000069e68074f1aada957edd39c5eae0069973343f30
Arg [11] : 0000000000000000000000004b5fe817488d86f55ab1a4e40598a3cfbde95b6a
Arg [12] : 0000000000000000000000001a1427a73b7cb0f4ea3f71c6c8090c4366c8ebe1
Arg [13] : 0000000000000000000000002177da04f9479496c2292d6344d306aa49beb34a
Arg [14] : 000000000000000000000000f0d6999725115e3ead3d927eb3329d63afaec09b
Arg [15] : 000000000000000000000000e11da9560b51f8918295edc5ab9c0a90e9ada20b
Arg [16] : 000000000000000000000000047d0cb513a2ccb1ed44d4af271410a9c8d5248f
Arg [17] : 00000000000000000000000012c29df62b1b254e1311bef777a37bf8c575b58d
Arg [18] : 00000000000000000000000016a2ebd556af2a39eba349be7d6eba7a57c47711
Arg [19] : 0000000000000000000000001da5331994e781ab0e2af9f85bfce2037a514170
Arg [20] : 0000000000000000000000001f8615a2caa4c8ab08bf1312e022341022c90e37
Arg [21] : 000000000000000000000000243db4aaa62b3785df27c364090749b96e45f3ec
Arg [22] : 000000000000000000000000324111baf9886e0456d74cef0ecbd49ed0779ee1
Arg [23] : 000000000000000000000000343e73d33639d9c354fa215ca23ffcd0f5604ac1
Arg [24] : 000000000000000000000000367dc97068ab54ba1dfbfc0fad12fbcb7b3a0d09
Arg [25] : 0000000000000000000000003c1bee74ff0d159ab06b6113417fc536499057c6
Arg [26] : 000000000000000000000000461a5b8326ba0e2dfd133651a3b559dc8d3b0400
Arg [27] : 0000000000000000000000004f55fd3b7ec169a364e34eb7f523ca5ceb12c888
Arg [28] : 00000000000000000000000051787a2c56d710c68140bdadefd3a98bff96feb4
Arg [29] : 00000000000000000000000059590178e9eddb027ed87bed9c1da8cd5129fed9
Arg [30] : 0000000000000000000000005efdb6d8c798c2c2bea5b1961982a5944f92a5c1
Arg [31] : 0000000000000000000000005f45c7ea2e094fea813a8a8813620ffcc4a19d0f
Arg [32] : 000000000000000000000000626ffae9f5537d4fadb6065585213f095b106bfc
Arg [33] : 00000000000000000000000065a4c69f4ea3fea89a0d4156c3d91c787472b670
Arg [34] : 00000000000000000000000067164d8853d3dc9ab5d11cb6744e6f04401cf772
Arg [35] : 000000000000000000000000679d5162bad71990abca0f18095948c12a2756b0
Arg [36] : 00000000000000000000000072915ad3110eb31768a562f540ac1ebcd51d3dc8
Arg [37] : 00000000000000000000000075432062a9bcc6bc5c294f44a8e3aa65bec8a64d
Arg [38] : 0000000000000000000000007a3cf7122eb2e3f3820f0afaaac4206cdc50bd7e
Arg [39] : 00000000000000000000000081eef2d7c4033c3224660b6a5d4b4a4727f1c762
Arg [40] : 000000000000000000000000881475210e75b814d5b711090a064942b6f30605
Arg [41] : 000000000000000000000000a3e0f18fec11b027bc23fd8a1cac729cffab11d9
Arg [42] : 000000000000000000000000b69cd25391df0b18e6cafe9dd61b966388d6beec
Arg [43] : 000000000000000000000000c0dcce9d4f0e5dbf20dc2631786550dbdeebf756
Arg [44] : 000000000000000000000000c3d1b0445c7d62fdb86e02c467f4239478b37f20
Arg [45] : 000000000000000000000000c8f8e2f59dd95ff67c3d39109eca2e2a017d4c8a
Arg [46] : 000000000000000000000000d52fba65a52214a65c78dc7f95c9fee1f13a5955
Arg [47] : 000000000000000000000000e2601273be4c89a729a3fe0af4bd6503bb20c27c
Arg [48] : 000000000000000000000000e3603cf313dcd49cc3061c9850a474d40aa81159
Arg [49] : 000000000000000000000000e5b0a257f0420ed4860d5d431e6ad6744da08405
Arg [50] : 000000000000000000000000f035af8a3dff1f90aeb21f9623589ae1330e9e09
Arg [51] : 000000000000000000000000fc8f57a04f4df6f167599162bf5fdaa098ac18cc
Arg [52] : 000000000000000000000000962a7d642178c87eeec92240669ec98f868dc54e
Arg [53] : 000000000000000000000000a5af072b89525ef22b60bb1aa2107a48f35d0cfe
Arg [54] : 0000000000000000000000005d802e2fe48392c104ce0401c7eca8a4456f1f16
Arg [55] : 000000000000000000000000aec4075e4fc8ce829bc4f0cfd5e2fa10dd2b12d1
Arg [56] : 000000000000000000000000463fc06d16e146ec9e4cb2ab8c3077732c75f38b
Arg [57] : 00000000000000000000000081590c16b9d1495d133cf881acf5cc0b56730b74
Arg [58] : 0000000000000000000000001aae1bc09e1785c8cb00650db0c6015bd73b0c7e
Arg [59] : 000000000000000000000000c3f1d077fa590018d3924ce8da1a085b4eae506d
Arg [60] : 0000000000000000000000008715ed9bbd4f8cfbed14f045556f19f39f11c75b
Arg [61] : 000000000000000000000000d5a06056701c7cfba12b1a384294148b9d2d8bca
Arg [62] : 0000000000000000000000009027bd5b0d32b0cb51dce93e8add64aca3a24912
Arg [63] : 00000000000000000000000099b8226ec774c957ffe2747fdfbae8f22741e899
Arg [64] : 0000000000000000000000009c81559aac49da60ff1e7755436dc2924d1a4c4f
Arg [65] : 00000000000000000000000036ed861a319278e5b6c39028884b0ca93df105d0
Arg [66] : 000000000000000000000000b2d2ecc7d94cfb8e70f60aeb97bf7f4c4cb8ef28
Arg [67] : 000000000000000000000000c2322d5e0cb1dc57695ecae84e5f6868c17f1cb7
Arg [68] : 000000000000000000000000b379b56bcacdd58ae0768654763881849bfaad94
Arg [69] : 000000000000000000000000d2dea18d040152c580f29195b29670633b0c9796
Arg [70] : 00000000000000000000000036041d9f21901599b9825bf4ecdf03aee81be0a6
Arg [71] : 00000000000000000000000092890034a3dcb1c38c1184775788ba0f95c23f03
Arg [72] : 000000000000000000000000cd64a3e77335b652f8582e081f02bf9c90f908a4
Arg [73] : 0000000000000000000000003348de5cc020eefa5d3b8212aefbc0c19d315f24
Arg [74] : 000000000000000000000000d8208bbf403a5de65a61e45321580fd0e31d4432
Arg [75] : 000000000000000000000000f6e9ccea1f646fee85e13ab3361c75959a94d5b0
Arg [76] : 00000000000000000000000097a6d7365e64d56b8a9aede0096a0fa2ace4eebc
Arg [77] : 0000000000000000000000009adccfd429a7ba40e7945841164ea2cffa7611fd
Arg [78] : 0000000000000000000000003689c216f8f6ce7e2ce2a27c81a23096a787f532
Arg [79] : 000000000000000000000000d2498b4dc8402789736f7c94caf969ea65badfa2
Arg [80] : 0000000000000000000000000d0e328b8fbc4a148eeae9e7b4791d7a6a0d2d07
Arg [81] : 000000000000000000000000f56345338cb4cddaf915ebef3bfde63e70fe3053


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.