ETH Price: $3,404.32 (+1.03%)

Token

Ailoverse Cats (AILOCAT)
 

Overview

Max Total Supply

2,300 AILOCAT

Holders

1,232

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
williampeartree.eth
Balance
1 AILOCAT
0xda8b44ee7b1f04affa8bc353a8215c67e51067f4
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Ailoverse is a Modular NFT2.0 Project, that consists of multiple NFTs. See the Ailobots Collection here: https://opensea.io/collection/ailoverse-robots, and assembled Ailosets here: https://opensea.io/collection/ailosets

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Contract

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-04-11
*/

// File: IWhitelist.sol


// Creator: OZ

pragma solidity ^0.8.4;

interface IWhitelist {
    function check(address addr) external view returns(bool);
}

// File: Errors.sol


// Creator: OZ using Chiru Labs

pragma solidity ^0.8.4;

error ApprovalQueryForNonexistentToken();
error ApproveToCaller();
error ApprovalToCurrentOwner();
error AssetCannotBeTransfered();
error AssetLocked();
error AssetNotLocked();
error BalanceQueryForZeroAddress();
error BurnedQueryForZeroAddress();
error CallerNotOwnerNorApproved();
error Err();
error LackOfMoney();
error LockCallerNotOwnerNorApproved();
error MintShouldBeOpened();
error MintToZeroAddress();
error MintZeroQuantity();
error MintedQueryForZeroAddress();
error OutOfMintBoundaries();
error OwnerIndexOutOfBounds();
error OwnerQueryForNonexistentToken();
error RootAddressError();
error TokenIndexOutOfBounds();
error TransferCallerNotOwnerNorApproved();
error TransferFromIncorrectOwner();
error TransferToNonERC721ReceiverImplementer();
error TransferToZeroAddress();
error URIQueryForNonexistentToken();
error WhitelistedOnly();

// File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol


// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = _efficientHash(computedHash, proofElement);
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = _efficientHash(proofElement, computedHash);
            }
        }
        return computedHash;
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

// File: Strings.sol


pragma solidity ^0.8.4;

/**
 * Libraries
 * Used https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol for Strings
 */

library Strings{

    bytes16 private constant _HEXSYMBOLS = "0123456789abcdef";

    function toString(address account) public pure returns(string memory) {
        return toString(abi.encodePacked(account));
    }

    function toString(bytes32 value) public pure returns(string memory) {
        return toString(abi.encodePacked(value));
    }

    function toString(bytes memory data) public pure returns(string memory) {
        bytes memory alphabet = "0123456789abcdef";

        bytes memory str = new bytes(2 + data.length * 2);
        str[0] = "0";
        str[1] = "x";
        for (uint i = 0; i < data.length; i++) {
            str[2+i*2] = alphabet[uint(uint8(data[i] >> 4))];
            str[3+i*2] = alphabet[uint(uint8(data[i] & 0x0f))];
        }
        return string(str);
    }

    function toString(uint256 value) internal pure returns(string memory)
    {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (0 == value) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (0 != temp) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (0 != value) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    function toHexString(uint256 value) internal pure returns(string memory)
    {
        if (0 == value) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (0 != temp) {
            length++;
            temp >>= 8;
        }
        return toHexString(value,length);
    }

    function toHexString(uint256 value,uint256 length) internal pure returns(string memory)
    {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEXSYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0);
        return string(buffer);
    }
    
    function concat(string memory self, string memory other) internal pure returns(string memory)
    {
        return string(
        abi.encodePacked(
            self,
            other
        ));
    }
    
}

// File: TokenStorage.sol


// Creator: OZ

pragma solidity ^0.8.4;

contract TokenStorage {

    enum MintStatus {
        NONE,
        PRESALE,
        SALE
    }

    // Compiler will pack this into a single 256bit word.
    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
    }

    // Compiler will pack this into a single 256bit word.
    struct AddressData {
        // Realistically, 2**64-1 is more than enough.
        uint64 balance;
        // Keeps track of mint count with minimal overhead for tokenomics.
        uint64 numberMinted;
        uint64 numberMintedOnPresale;
        // Keeps track of burn count with minimal overhead for tokenomics.
        uint64 numberBurned;
    }

    struct ContractData {
        // Token name
        string name;
        // Token description
        string description;
        // Token symbol
        string symbol;
        // Base URL for tokens metadata
        string baseURL;
        // Contract-level metadata URL
        string contractURL;
        // Whitelist Merkle tree root
        bytes32 wl;
        // Is it set or asset?
        bool isEnvelope;
        // Revealed?
        bool isRevealed;
        // Mint status managed by
        bool mintStatusAuto;
        // Status
        MintStatus mintStatus;
    }

    struct EnvelopeTypes {
        address envelope;
        address[] types;
    }

    struct MintSettings {
        uint8 mintOnPresale;
        uint8 maxMintPerUser;
        uint8 minMintPerUser;
        uint64 maxTokenSupply;
        uint256 priceOnPresale;
        uint256 priceOnSale;
        uint256 envelopeConcatPrice;
        uint256 envelopeSplitPrice;
        // MintStatus timing
        uint256 mintStatusPreale;
        uint256 mintStatusSale;
        uint256 mintStatusFinished;
    }

    // Contract root address
    address internal _root;

    // The tokenId of the next token to be minted.
    uint256 internal _currentIndex;

    // The number of tokens burned.
    uint256 internal _burnCounter;

    // Contract data
    ContractData internal _contractData;

    // Envelope data
    EnvelopeTypes internal _envelopeTypes;

    // Mint settings
    MintSettings internal _mintSettings;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned. See ownershipOf implementation for details.
    mapping(uint256 => TokenOwnership) internal _ownerships;

    // Mapping from token ID to approved address
    mapping(uint256 => address) internal _tokenApprovals;

    // Mapping owner address to address data
    mapping(address => AddressData) internal _addressData;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) internal _operatorApprovals;

    // Envelope container
    mapping(uint256 => mapping(address => uint256)) internal _assetsEnvelope;
    mapping(address => mapping(uint256 => bool)) internal _assetsEnveloped;

}
// File: @openzeppelin/contracts/utils/Address.sol


// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


// 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: @openzeppelin/contracts/utils/introspection/ERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


/**
 * @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: @openzeppelin/contracts/token/ERC721/IERC721.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

// File: @openzeppelin/contracts/utils/Context.sol


// 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: Array.sol


// Creator: OZ

pragma solidity ^0.8.4;

contract Array{

    function remove(uint256[] memory arr, uint256 e)
    internal pure
    {
        unchecked {
            uint idx = 0;
            for(uint i = 0; i < arr.length; i++) {
                if(arr[i] == e) {
                    idx = i;
                }
            }
            for (uint i = idx; i < arr.length-1; i++){
                arr[i] = arr[i+1];        
            }
            delete arr[arr.length - 1];
        }
    }
    
}
// File: Math.sol


pragma solidity ^0.8.4;

library Math{

    function max(uint256 a,uint256 b) internal pure returns(uint256)
    {
        return a >= b ? a : b;
    }

    function min(uint256 a,uint256 b) internal pure returns(uint256)
    {
        return a < b ? a : b;
    }

    function average(uint256 a,uint256 b) internal pure returns(uint256)
    {
        return (a & b) + (a ^ b) / 2;
    }

    function ceilDiv(uint256 a,uint256 b) internal pure returns(uint256)
    {
        return a / b + (a % b == 0 ? 0 : 1);
    }

    function mul(uint256 a,uint256 b) internal pure returns(uint256 c)
    {
        if (0 == a) {
            return 0;
        }
        c = a * b;
        assert(c / a == b);
        return c;
    }

    function div(uint256 a,uint256 b) internal pure returns(uint256)
    {
        assert(0 != b);
        return a / b;
    }

    function sub(uint256 a,uint256 b) internal pure returns(uint256)
    {
        assert(b <= a);
        return a - b;
    }

    function add(uint256 a,uint256 b) internal pure returns(uint256 c)
    {
        c = a + b;
        assert(c >= a);
        return c;
    }
}

// File: Quantity.sol


// Creator: OZ

pragma solidity ^0.8.4;



contract Quantity is TokenStorage {

    function quantityIsGood(uint256 _quantity,uint256 _minted,uint256 _mintedOnPresale)
    internal view
    returns(bool)
    {
        return
            (
                _contractData.mintStatus == MintStatus.PRESALE &&
                _mintSettings.mintOnPresale >= _quantity + _minted
            ) || (
                _contractData.mintStatus == MintStatus.SALE &&
                _mintSettings.maxMintPerUser >= _quantity + _minted - _mintedOnPresale &&
                _mintSettings.minMintPerUser <= _quantity
            )
            ;
    }

    function supplyIsGood()
    internal view
    returns(bool)
    {
        return
            _contractData.isEnvelope || (
                _contractData.isEnvelope == false &&
                _mintSettings.maxTokenSupply > _currentIndex
            )
            ;
    }

}
// File: IEnvelope.sol


// Creator: OZ

pragma solidity ^0.8.4;

interface IEnvelope {
    function locked(address _asset,uint256 _assetId) external view returns(bool);
    function ownerOfAsset(uint256 _assetId) external view returns(address);
    }

// File: Ownership.sol


// Creator: OZ using Chiru Labs

pragma solidity ^0.8.4;





contract Ownership is Context, TokenStorage {

    /**
     * Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around in the collection over time.
     */
    function ownershipOf(uint256 tokenId)
    internal view
    returns (TokenOwnership memory)
    {
        uint256 curr = tokenId;

        unchecked {
            if (curr < _currentIndex) {
                TokenOwnership memory ownership = _ownerships[curr];
                if (!ownership.burned) {
                    if (ownership.addr != address(0)) {
                        return ownership;
                    }
                    // Invariant: 
                    // There will always be an ownership that has an address and is not burned 
                    // before an ownership that does not have an address and is not burned.
                    // Hence, curr will not underflow.
                    while (true) {
                        curr--;
                        ownership = _ownerships[curr];
                        if (ownership.addr != address(0)) {
                            return ownership;
                        }
                    }
                }
            }
        }
        revert OwnerQueryForNonexistentToken();
    }

    uint256[] private __tokens__;

    function tokensOf(address _owner)
    external
    returns(uint256[] memory tokens)
    {
        unchecked {
            for(uint i=0;i<_currentIndex;i++) {
                TokenOwnership memory ownership = ownershipOf(i);
                if(ownership.addr == _owner) {
                    if (!ownership.burned) {
                        if(_contractData.isEnvelope) {
                            __tokens__.push(i);
                        } else {
                            if(!IEnvelope(_envelopeTypes.envelope).locked(address(this),i)) {
                                __tokens__.push(i);
                            }
                        }
                    }
                }
            }
            return __tokens__;
        }
    }

}
// File: AccessControl.sol


// Creator: OZ

pragma solidity ^0.8.4;




contract AccessControl is Ownership {

    function ActiveMint()
    internal view
    {
        if(MintStatus.NONE == _contractData.mintStatus)
            revert MintShouldBeOpened();
    }

    function ApprovedOnly(address owner)
    internal view
    {
        if (!_operatorApprovals[owner][_msgSender()])
            revert CallerNotOwnerNorApproved();
    }

    function BotProtection()
    internal view
    {
        if(tx.origin != msg.sender)
            revert Err();
    }

    function OwnerOnly(address owner,uint256 tokenId)
    internal view
    {
        if (owner != ownershipOf(tokenId).addr)
            revert CallerNotOwnerNorApproved();
    }

    function RootOnly()
    internal view
    {
        address sender = _msgSender();
        if(
            sender != _root &&
            sender != _envelopeTypes.envelope
        ) revert RootAddressError();
    }

    function Whitelisted(bytes32[] calldata _merkleProof)
    internal view
    {
        address sender = _msgSender();
        bool flag =
            _root == sender ||
            _contractData.mintStatus == MintStatus.SALE
        ;

        /**
         * Set merkle tree root
         */
        if(!flag)
            flag = MerkleProof.verify(_merkleProof, _contractData.wl, keccak256(abi.encodePacked(sender)));

        /**/
        if(!flag)
            revert WhitelistedOnly();
    }

    function setWLRoot(bytes32 _root)
    external
    {
        RootOnly();

        _contractData.wl = _root;
    }

}
// File: ERC721A.sol


// Creator: Chiru Labs

pragma solidity ^0.8.4;












//import "hardhat/console.sol";

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at 0 (e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
abstract contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, AccessControl, Quantity {
    using Address for address;
    using Strings for uint256;

    constructor(
        string memory name_,
        string memory description_,
        string memory symbol_,
        string memory baseURL_,
        string memory contractURL_
    ) {
        _contractData.name = name_;
        _contractData.description = description_;
        _contractData.symbol = symbol_;
        _contractData.baseURL = baseURL_;
        _contractData.contractURL = contractURL_;
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply()
    public view
    returns(uint256)
    {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than _currentIndex times
        unchecked {
            return _currentIndex - _burnCounter;    
        }
    }

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner)
    public view
    override
    returns(uint256)
    {
        if (owner == address(0))
            revert BalanceQueryForZeroAddress();
        return uint256(_addressData[owner].balance);
    }

    /**
     * returnsthe number of tokens minted by `owner`.
     */
    function _numberMinted(address owner)
    internal view
    returns(uint256)
    {
        if (owner == address(0))
            revert MintedQueryForZeroAddress();
        else return
            uint256(_addressData[owner].numberMinted);
    }

    function _numberMintedOnPresale(address owner)
    internal view
    returns(uint256)
    {
        if (owner == address(0))
            revert MintedQueryForZeroAddress();
        else return
            uint256(_addressData[owner].numberMintedOnPresale);
    }

    /**
     * returnsthe number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner)
    internal view
    returns(uint256)
    {
        if (owner == address(0))
            revert BurnedQueryForZeroAddress();
        else return
            uint256(_addressData[owner].numberBurned);
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId)
    public view
    override
    returns(address)
    {
        if(!_contractData.isEnvelope) {
            if(IEnvelope(_envelopeTypes.envelope).locked(address(this),tokenId)) {
                return address(0);
            }
        }
        return ownershipOf(tokenId).addr;
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId)
    public
    override
    {
        address owner = ERC721A.ownerOf(tokenId);
        if (to == owner)
            revert ApprovalToCurrentOwner();
        if (_msgSender() != owner && !isApprovedForAll(owner, _msgSender()))
            revert CallerNotOwnerNorApproved();
        _approve(to, tokenId, owner);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId)
    public view
    override
    returns(address)
    {
        if (!_exists(tokenId))
            revert ApprovalQueryForNonexistentToken();
        else return
            _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved)
    public
    override
    {
        if (operator == _msgSender())
            revert ApproveToCaller();
        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator)
    public view virtual
    override
    returns(bool)
    {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        if(!_contractData.isEnvelope)
            if(IEnvelope(_envelopeTypes.envelope).locked(address(this),tokenId))
                revert AssetLocked();
                
        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        if(!_contractData.isEnvelope)
            if(IEnvelope(_envelopeTypes.envelope).locked(address(this),tokenId))
                revert AssetLocked();

        _transfer(from, to, tokenId);
        if (!_checkOnERC721Received(from, to, tokenId, _data))
            revert TransferToNonERC721ReceiverImplementer();
    }

    /**
     * @dev returnswhether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     */
    function _exists(uint256 tokenId)
    internal view
    returns(bool)
    {
        return tokenId < _currentIndex && !_ownerships[tokenId].burned;
    }

    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, '');
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        _mint(to, quantity, _data, true);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _mint(
        address to,
        uint256 quantity,
        bytes memory _data,
        bool safe
    ) internal {
        uint256 startTokenId = _currentIndex;
        if(!supplyIsGood())
            revert OutOfMintBoundaries();
        if (to == address(0))
            revert MintToZeroAddress();
        if (quantity == 0)
            revert MintZeroQuantity();

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);
            if(_contractData.mintStatus == MintStatus.PRESALE)
                _addressData[to].numberMintedOnPresale = _addressData[to].numberMintedOnPresale + uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

            uint256 updatedIndex = startTokenId;
            for (uint256 i; i < quantity; i++) {
                emit Transfer(address(0), to, updatedIndex);
                if (safe && !_checkOnERC721Received(address(0), to, updatedIndex, _data))
                    revert TransferToNonERC721ReceiverImplementer();
                updatedIndex++;
            }

            _currentIndex = updatedIndex;
        }
    }

    /**
     * Transfer set and all its assets
     */
    function _transferEnvelope(address _to,uint256 _assetId)
    internal
    {
        unchecked {
            for (uint i = 0; i < _envelopeTypes.types.length; i++) {
                (bool success,bytes memory res) = _envelopeTypes.types[i].call(
                    abi.encodeWithSignature("unlock(uint256,address)",
                        _assetsEnvelope[_assetId][_envelopeTypes.types[i]],
                        _to)
                );
                if(!success)
                    revert AssetCannotBeTransfered();
            }
        }
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal {

        TokenOwnership memory prevOwnership = ownershipOf(tokenId);
        address sender = _msgSender();

        bool isApprovedOrOwner = (
            sender == _envelopeTypes.envelope ||
            sender == prevOwnership.addr ||
            sender == getApproved(tokenId) ||
            isApprovedForAll(prevOwnership.addr, sender)
        );

        if (!isApprovedOrOwner)
            revert TransferCallerNotOwnerNorApproved();
        if (prevOwnership.addr != from)
            revert TransferFromIncorrectOwner();
        if (to == address(0))
            revert TransferToZeroAddress();

        /*
        if(
            sender == prevOwnership.addr &&
            _contractData.isEnvelope
        ) _transferEnvelope(to,tokenId);
        */

        // Clear approvals from the previous owner
        _approve(address(0), tokenId, prevOwnership.addr);

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            _addressData[from].balance -= 1;
            _addressData[to].balance += 1;

            _ownerships[tokenId].addr = to;
            _ownerships[tokenId].startTimestamp = uint64(block.timestamp);

            // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            if (_ownerships[nextTokenId].addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId < _currentIndex) {
                    _ownerships[nextTokenId].addr = prevOwnership.addr;
                    _ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId)
    internal virtual
    {
        TokenOwnership memory prevOwnership = ownershipOf(tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId, prevOwnership.addr);

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            _addressData[prevOwnership.addr].balance -= 1;
            _addressData[prevOwnership.addr].numberBurned += 1;

            // Keep track of who burned the token, and the timestamp of burning.
            _ownerships[tokenId].addr = prevOwnership.addr;
            _ownerships[tokenId].startTimestamp = uint64(block.timestamp);
            _ownerships[tokenId].burned = true;

            // If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            if (_ownerships[nextTokenId].addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId < _currentIndex) {
                    _ownerships[nextTokenId].addr = prevOwnership.addr;
                    _ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

        emit Transfer(prevOwnership.addr, address(0), tokenId);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(
        address to,
        uint256 tokenId,
        address owner
    ) private {
        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns(bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns(bytes4 retval) {
                return retval == IERC721Receiver(to).onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert TransferToNonERC721ReceiverImplementer();
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    function getBalance()
    external view
    returns(uint256)
    {
        if(_root != _msgSender())
            revert RootAddressError();
        return address(this).balance;
    }

    function withdraw(address _to,uint256 _amount)
    external
    {
        if(_root != _msgSender())
            revert RootAddressError();
        if(address(this).balance < _amount)
            revert LackOfMoney();
        payable(_to).transfer(_amount);
    }

}

// File: ERC721AToken.sol


// Creator: Chiru Labs & OZ

pragma solidity ^0.8.4;




/**
 * @title ERC721A Base Token
 * @dev ERC721A Token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721AToken is Context, Ownership, ERC721A {
    using Strings for uint256;

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name()
    external view virtual
    override
    returns(string memory)
    {
        return _contractData.name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol()
    external view virtual
    override
    returns(string memory)
    {
        return _contractData.symbol;
    }

    function baseTokenURI()
    external view
    returns(string memory)
    {
        return _contractData.baseURL;
    }
  
    function contractURI()
    external view
    returns(string memory)
    {
        return _contractData.contractURL;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId)
    external view
    override
    returns(string memory)
    {
        if (!_exists(tokenId))
            revert URIQueryForNonexistentToken();

        return string(
                abi.encodePacked(
                    _contractData.baseURL,
                    "/",
                    Strings.toString(tokenId),
                    ".json"
                ));
    }

    function decimals()
    external pure
    returns(uint8)
    {
        return 0;
    }

    /**
     * @dev Burns `tokenId`. See {ERC721A-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId)
    internal
    {
        if(!_contractData.isEnvelope)
            if(IEnvelope(_envelopeTypes.envelope).locked(address(this),tokenId))
                revert AssetLocked();
                
        TokenOwnership memory prevOwnership = ownershipOf(tokenId);

        bool isApprovedOrOwner = (_msgSender() == prevOwnership.addr ||
            isApprovedForAll(prevOwnership.addr, _msgSender()) ||
            getApproved(tokenId) == _msgSender());

        if (!isApprovedOrOwner)
            revert TransferCallerNotOwnerNorApproved();

        _burn(tokenId);
    }

}
// File: IAsset.sol


// Creator: OZ

pragma solidity ^0.8.4;

interface IAsset {
    function checkMint(address _owner,uint256 _quantity) external returns(uint256);
    function locked(uint256 _assetId) external view returns(bool);
    function ownerOfAsset(uint256 _assetId) external view returns(address);
    }

// File: ERC721AEnvelope.sol


// Creator: OZ

pragma solidity ^0.8.4;





//import "hardhat/console.sol";

abstract contract ERC721AEnvelope is Array, Context, ERC721AToken {
    using Math for uint256;

    function _mintSetOfAssets(address _owner,uint _quantity)
    internal
    {
        unchecked {
            for(uint i = 0; i < _envelopeTypes.types.length; i++) {
                (bool success,bytes memory res) = _envelopeTypes.types[i].call(
                    abi.encodeWithSignature("safeMint(address,uint256)",
                        _owner,
                        _quantity
                        )
                );
                if(!success)
                    revert Err();
            }
        }
    }

    function _envelopeAssets(uint256 _envelopeId)
    internal view
    returns(address[] memory,uint256[] memory)
    {
        unchecked {
            uint len = 0;
            for (uint i = 0; i < _envelopeTypes.types.length; i++) {
                len++;
            }
            address[] memory addrs = new address[](len);
            uint256[] memory tokens = new uint256[](len);
            len = 0;
            for (uint i = 0; i < _envelopeTypes.types.length; i++) {
                addrs[len] = _envelopeTypes.types[i];
                tokens[len++] = _assetsEnvelope[_envelopeId][_envelopeTypes.types[i]];
            }
            return (addrs,tokens);
        }
    }

    function _envelopeSplit(address _owner,uint256 _envelopeId)
    internal
    returns(address[] memory,uint256[] memory)
    {
        OwnerOnly(_owner,_envelopeId);

        (address[] memory addrs,uint256[] memory tokens) = _envelopeAssets(_envelopeId);
        _burn(_envelopeId);
        _transferEnvelope(_owner,_envelopeId);
        unchecked {
            for(uint i = 0; i < addrs.length; i++) {
                _unlockEnvelopeAsset(
                        _envelopeId,
                        addrs[i],
                        tokens[i]
                        );
            }
        }
        return (addrs,tokens);
    }

    function _unlockEnvelopeAsset(uint256 _envelopeId,address _asset,uint256 _assetId)
    internal
    {
        if(!_locked(_asset,_assetId))
            revert AssetNotLocked();
        if(_msgSender() != IAsset(_asset).ownerOfAsset(_assetId))
            revert CallerNotOwnerNorApproved();

        delete _assetsEnveloped[_asset][_assetId];
        delete _assetsEnvelope[_envelopeId][_asset];
    }

    function _envelopeCreate(address _owner,address[] calldata _assets,uint256[] calldata _assetIds)
    internal
    returns(uint256)
    {
        if(
            _assets.length == 0 &&
            _assets.length != _assetIds.length
        ) revert Err();

        uint256 envelopeId = _currentIndex;
        _safeMint(_owner,1);
        unchecked {
            _assetsEnvelope[envelopeId][_envelopeTypes.envelope] = envelopeId;
            for(uint i = 0; i < _assets.length; i++) {
                if(_locked(_assets[i],_assetIds[i]))
                    revert AssetLocked();
                if(_owner != IAsset(_assets[i]).ownerOfAsset(_assetIds[i]))
                    revert CallerNotOwnerNorApproved();
                _assetsEnvelope[envelopeId][_assets[i]] = _assetIds[i];
                _assetsEnveloped[_assets[i]][_assetIds[i]] = true;
            }
        }
        return envelopeId;
    }

    function _locked(address _asset,uint256 _assetId)
    internal view
    returns(bool)
    {
        if (_contractData.isEnvelope)
            return _assetsEnveloped[_asset][_assetId];
        else
            return IAsset(_envelopeTypes.envelope).locked(_assetId);
    }

}

// File: Master.sol


// Creator: OZ

pragma solidity ^0.8.4;


abstract contract Master is ERC721AEnvelope {

    constructor() {
        _root = _msgSender();
        _contractData.isRevealed = false;
        _contractData.mintStatus = MintStatus.NONE;
        _contractData.mintStatusAuto = true;
        _mintSettings.mintOnPresale = 1; // number of tokens on presale
        _mintSettings.maxMintPerUser = 2; // max tokens on sale
        _mintSettings.minMintPerUser = 1; // min tokens on sale
        _mintSettings.maxTokenSupply = 5000;
        _mintSettings.priceOnPresale = 37500000000000000; // in wei, may be changed later
        _mintSettings.priceOnSale = 47500000000000000; // in wei, may be changed later
        _mintSettings.envelopeConcatPrice = 0; // in wei, may be changed later
        _mintSettings.envelopeSplitPrice = 0; // in wei, may be changed later
        _mintSettings.mintStatusPreale = 1649683800; // Monday, April 11, 2022 2:00:00 PM GMT
        _mintSettings.mintStatusSale = 1649734200; // Tuesday, April 12, 2022 3:30:00 AM
        _mintSettings.mintStatusFinished = 0; //does not specified
    }

    function exists(uint256 tokenId)
    external view
    returns(bool)
    {
        return _exists(tokenId);
    }

    function setRoot(address _owner)
    external
    {
        RootOnly();
        
        _root = _owner;
    }

    function getRoot()
    external view
    returns(address)
    {
        return _root;
    }

    function CheckMintStatus()
    internal
    {
        if(!_contractData.mintStatusAuto)
            return;
        
        uint256 mps = _mintSettings.mintStatusPreale;
        uint256 ms = _mintSettings.mintStatusSale;
        uint256 mf = _mintSettings.mintStatusFinished;
        if (mps <= block.timestamp && block.timestamp < ms) {
            _contractData.mintStatus = MintStatus.PRESALE;
        } else if (ms <= block.timestamp && (block.timestamp < mf || 0 == mf)) {
            _contractData.mintStatus = MintStatus.SALE;
        } else {
            _contractData.mintStatus = MintStatus.NONE;
        }
    }

    function toggleMintStatus(bool _mode)
    external
    {
        RootOnly();

        _contractData.mintStatusAuto = _mode;
    }

    function setMintingIsOnPresale()
    external
    {
        RootOnly();

        _contractData.mintStatus = MintStatus.PRESALE;
    }
    
    function setMintingIsOnSale()
    external
    {
        RootOnly();

        _contractData.mintStatus = MintStatus.SALE;
    }
     
    function stopMinting()
    external
    {
        RootOnly();

        _contractData.mintStatus = MintStatus.NONE;
    }

    function updateContract(
        uint256 _pricePresale,
        uint256 _priceSale,
        uint8 _minMint,
        uint8 _maxMint,
        uint64 _maxSupply
        )
    external
    {
        RootOnly();

        _mintSettings.priceOnPresale = _pricePresale;
        _mintSettings.priceOnSale = _priceSale;
        _mintSettings.maxMintPerUser = _maxMint;
        _mintSettings.minMintPerUser = _minMint;
        _mintSettings.maxTokenSupply = _maxSupply;
    }

    function setRevealed(string calldata _url)
    external
    {
        RootOnly();

        _contractData.isRevealed = true;
        _contractData.baseURL = _url;
    }

    function updateBaseURL(string calldata _url)
    external
    {
        RootOnly();

        _contractData.baseURL = _url;
    }

}
// File: Contract.sol


// Creator: OZ

pragma solidity ^0.8.4;




contract Contract is Master, IAsset {

    constructor(
        string memory name_,
        string memory description_,
        string memory symbol_,
        string memory baseURL_,
        string memory contractURL_
    ) ERC721A(
        name_,
        description_,
        symbol_,
        baseURL_,
        contractURL_
    ) Master() {
        _contractData.isEnvelope = false;
        for(uint i = 0; i < 20; i++)
            _safeMint(0x47Ae4dBf9fDBac0ebbc473Aacddb22dE13Ba0C38,5);
            //_safeMint(_msgSender(),5);
    }

    function addAssetType(address _asset)
    external
    {
        RootOnly();

        _envelopeTypes.envelope = _asset;
    }

    function safeMint(address _owner,uint256 _quantity)
    external
    {
        RootOnly();
        CheckMintStatus();
        ActiveMint();
        
        if (_root != _owner)
            _checkMint(_owner,_quantity);
        _safeMint(_owner,_quantity);
    }

    function checkMint(address _owner,uint256 _quantity)
    external view
    override
    returns(uint256)
    {
        _checkMint(_owner,_quantity);
        return _numberMinted(_owner) + _quantity;
    }

    function _checkMint(address _owner,uint256 _quantity)
    private view
    {
        if(!quantityIsGood(_quantity,_numberMinted(_owner),_numberMintedOnPresale(_owner)))
            revert OutOfMintBoundaries()
            ;
        if(!supplyIsGood())
            revert OutOfMintBoundaries()
            ;
    }

    function locked(uint256 _assetId)
    external view
    override
    returns(bool)
    {
        return IEnvelope(_envelopeTypes.envelope).locked(address(this),_assetId);
    }

    function ownerOfAsset(uint256 _assetId)
    public view
    override
    returns(address)
    {
        return ownershipOf(_assetId).addr;
    }

    function unlock(uint256 _assetId,address _owner)
    external
    {
        address sender = _msgSender();
        if (
            _root == sender || (
                _envelopeTypes.envelope == sender &&
                IEnvelope(_envelopeTypes.envelope).locked(address(this),_assetId)
            )
        ) {
            if(ownerOfAsset(_assetId) != _owner)
                _transfer(ownerOfAsset(_assetId),_owner,_assetId);
        } else revert AssetLocked();
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"description_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"string","name":"baseURL_","type":"string"},{"internalType":"string","name":"contractURL_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"AssetLocked","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"CallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"LackOfMoney","type":"error"},{"inputs":[],"name":"MintShouldBeOpened","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"MintedQueryForZeroAddress","type":"error"},{"inputs":[],"name":"OutOfMintBoundaries","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"RootAddressError","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"addAssetType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"checkMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRoot","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assetId","type":"uint256"}],"name":"locked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assetId","type":"uint256"}],"name":"ownerOfAsset","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"safeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setMintingIsOnPresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setMintingIsOnSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_url","type":"string"}],"name":"setRevealed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"setWLRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stopMinting","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":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_mode","type":"bool"}],"name":"toggleMintStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"tokensOf","outputs":[{"internalType":"uint256[]","name":"tokens","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assetId","type":"uint256"},{"internalType":"address","name":"_owner","type":"address"}],"name":"unlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_url","type":"string"}],"name":"updateBaseURL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pricePresale","type":"uint256"},{"internalType":"uint256","name":"_priceSale","type":"uint256"},{"internalType":"uint8","name":"_minMint","type":"uint8"},{"internalType":"uint8","name":"_maxMint","type":"uint8"},{"internalType":"uint64","name":"_maxSupply","type":"uint64"}],"name":"updateContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b506040516200520338038062005203833981810160405281019062000037919062000c21565b8484848484846003600001908051906020019062000057929190620009d4565b50836003600101908051906020019062000073929190620009d4565b5082600360020190805190602001906200008f929190620009d4565b5081600380019080519060200190620000aa929190620009d4565b508060036004019080519060200190620000c6929190620009d4565b505050505050620000dc620002e660201b60201c565b6000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600360060160016101000a81548160ff0219169083151502179055506000600360060160036101000a81548160ff0219169083600281111562000165576200016462000d44565b5b02179055506001600360060160026101000a81548160ff0219169083151502179055506001600c60000160006101000a81548160ff021916908360ff1602179055506002600c60000160016101000a81548160ff021916908360ff1602179055506001600c60000160026101000a81548160ff021916908360ff160217905550611388600c60000160036101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555066853a0d2313c000600c6001018190555066a8c0ff92d4c000600c600201819055506000600c600301819055506000600c600401819055506362542d58600c60050181905550636254f238600c600601819055506000600c600701819055506000600360060160006101000a81548160ff02191690831515021790555060005b6014811015620002da57620002c47347ae4dbf9fdbac0ebbc473aacddb22de13ba0c386005620002ee60201b60201c565b8080620002d19062000dac565b91505062000293565b50505050505062000ff3565b600033905090565b620003108282604051806020016040528060008152506200031460201b60201c565b5050565b6200032983838360016200032e60201b60201c565b505050565b6000600154905062000345620007a660201b60201c565b6200037c576040517f271c929900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603620003e3576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084036200041e576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83601660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555083601660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001600281111562000539576200053862000d44565b5b600360060160039054906101000a900460ff16600281111562000561576200056062000d44565b5b03620006295783601660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160109054906101000a900467ffffffffffffffff1601601660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160106101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b846014600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426014600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600081905060005b858110156200079657818773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48380156200074857506200074660008884886200081360201b60201c565b155b1562000780576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81806001019250508080600101915050620006c3565b5080600181905550505050505050565b6000600360060160009054906101000a900460ff16806200080e575060001515600360060160009054906101000a900460ff1615151480156200080d5750600154600c60000160039054906101000a900467ffffffffffffffff1667ffffffffffffffff16115b5b905090565b6000620008418473ffffffffffffffffffffffffffffffffffffffff16620009b160201b62001bc91760201c565b15620009a4578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0262000873620002e660201b60201c565b8786866040518563ffffffff1660e01b815260040162000897949392919062000eac565b6020604051808303816000875af1925050508015620008d657506040513d601f19601f82011682018060405250810190620008d3919062000f5d565b60015b62000953573d806000811462000909576040519150601f19603f3d011682016040523d82523d6000602084013e6200090e565b606091505b5060008151036200094b576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050620009a9565b600190505b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b828054620009e29062000fbe565b90600052602060002090601f01602090048101928262000a06576000855562000a52565b82601f1062000a2157805160ff191683800117855562000a52565b8280016001018555821562000a52579182015b8281111562000a5157825182559160200191906001019062000a34565b5b50905062000a61919062000a65565b5090565b5b8082111562000a8057600081600090555060010162000a66565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b62000aed8262000aa2565b810181811067ffffffffffffffff8211171562000b0f5762000b0e62000ab3565b5b80604052505050565b600062000b2462000a84565b905062000b32828262000ae2565b919050565b600067ffffffffffffffff82111562000b555762000b5462000ab3565b5b62000b608262000aa2565b9050602081019050919050565b60005b8381101562000b8d57808201518184015260208101905062000b70565b8381111562000b9d576000848401525b50505050565b600062000bba62000bb48462000b37565b62000b18565b90508281526020810184848401111562000bd95762000bd862000a9d565b5b62000be684828562000b6d565b509392505050565b600082601f83011262000c065762000c0562000a98565b5b815162000c1884826020860162000ba3565b91505092915050565b600080600080600060a0868803121562000c405762000c3f62000a8e565b5b600086015167ffffffffffffffff81111562000c615762000c6062000a93565b5b62000c6f8882890162000bee565b955050602086015167ffffffffffffffff81111562000c935762000c9262000a93565b5b62000ca18882890162000bee565b945050604086015167ffffffffffffffff81111562000cc55762000cc462000a93565b5b62000cd38882890162000bee565b935050606086015167ffffffffffffffff81111562000cf75762000cf662000a93565b5b62000d058882890162000bee565b925050608086015167ffffffffffffffff81111562000d295762000d2862000a93565b5b62000d378882890162000bee565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b600062000db98262000da2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362000dee5762000ded62000d73565b5b600182019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000e268262000df9565b9050919050565b62000e388162000e19565b82525050565b62000e498162000da2565b82525050565b600081519050919050565b600082825260208201905092915050565b600062000e788262000e4f565b62000e84818562000e5a565b935062000e9681856020860162000b6d565b62000ea18162000aa2565b840191505092915050565b600060808201905062000ec3600083018762000e2d565b62000ed2602083018662000e2d565b62000ee1604083018562000e3e565b818103606083015262000ef5818462000e6b565b905095945050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b62000f378162000f00565b811462000f4357600080fd5b50565b60008151905062000f578162000f2c565b92915050565b60006020828403121562000f765762000f7562000a8e565b5b600062000f868482850162000f46565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168062000fd757607f821691505b60208210810362000fed5762000fec62000f8f565b5b50919050565b61420080620010036000396000f3fe608060405234801561001057600080fd5b50600436106102265760003560e01c8063794100b911610130578063b45a3c0e116100b8578063e2898bd51161007c578063e2898bd514610637578063e8a3d48514610667578063e985e9c514610685578063f1d2ec1d146106b5578063f3fef3a3146106d157610226565b8063b45a3c0e14610593578063b4e99839146105c3578063b88d4fde146105cd578063c87b56dd146105e9578063d547cfb71461061957610226565b80639ece3398116100ff5780639ece339814610505578063a084c6ad1461050f578063a14481941461053f578063a22cb4651461055b578063b11c7f821461057757610226565b8063794100b914610493578063864aa866146104af578063870d6f9d146104cb57806395d89b41146104e757610226565b80633e3e0b12116101b35780635a3f2672116101825780635a3f2672146103c95780635ca1e165146103f95780636352211e1461041757806368d4e4ef1461044757806370a082311461046357610226565b80633e3e0b12146103575780633e6007e01461036157806342842e0e1461037d5780634f558e791461039957610226565b8063095ea7b3116101fa578063095ea7b3146102c557806312065fe0146102e157806318160ddd146102ff57806323b872dd1461031d578063313ce5671461033957610226565b80623ba1ed1461022b57806301ffc9a71461024757806306fdde0314610277578063081812fc14610295575b600080fd5b610245600480360381019061024091906133be565b6106ed565b005b610261600480360381019061025c9190613443565b610738565b60405161026e919061348b565b60405180910390f35b61027f61081a565b60405161028c919061353f565b60405180910390f35b6102af60048036038101906102aa9190613597565b6108af565b6040516102bc91906135d3565b60405180910390f35b6102df60048036038101906102da91906135ee565b61092b565b005b6102e9610a35565b6040516102f6919061363d565b60405180910390f35b610307610ac9565b604051610314919061363d565b60405180910390f35b61033760048036038101906103329190613658565b610ad7565b005b610341610bd7565b60405161034e91906136c7565b60405180910390f35b61035f610bdc565b005b61037b6004803603810190610376919061370e565b610c14565b005b61039760048036038101906103929190613658565b610c3c565b005b6103b360048036038101906103ae9190613597565b610c5c565b6040516103c0919061348b565b60405180910390f35b6103e360048036038101906103de91906133be565b610c6e565b6040516103f091906137f9565b60405180910390f35b610401610e49565b60405161040e91906135d3565b60405180910390f35b610431600480360381019061042c9190613597565b610e72565b60405161043e91906135d3565b60405180910390f35b610461600480360381019061045c91906133be565b610f50565b005b61047d600480360381019061047891906133be565b610f9f565b60405161048a919061363d565b60405180910390f35b6104ad60048036038101906104a89190613880565b61106e565b005b6104c960048036038101906104c49190613939565b6110ac565b005b6104e560048036038101906104e09190613880565b611137565b005b6104ef611157565b6040516104fc919061353f565b60405180910390f35b61050d6111ec565b005b61052960048036038101906105249190613597565b611224565b60405161053691906135d3565b60405180910390f35b610559600480360381019061055491906135ee565b61123a565b005b610575600480360381019061057091906139b4565b6112be565b005b610591600480360381019061058c9190613a2a565b611435565b005b6105ad60048036038101906105a89190613597565b61144a565b6040516105ba919061348b565b60405180910390f35b6105cb6114f4565b005b6105e760048036038101906105e29190613b87565b61152c565b005b61060360048036038101906105fe9190613597565b61166f565b604051610610919061353f565b60405180910390f35b6106216116e4565b60405161062e919061353f565b60405180910390f35b610651600480360381019061064c91906135ee565b611778565b60405161065e919061363d565b60405180910390f35b61066f6117a0565b60405161067c919061353f565b60405180910390f35b61069f600480360381019061069a9190613c0a565b611835565b6040516106ac919061348b565b60405180910390f35b6106cf60048036038101906106ca9190613c4a565b6118c9565b005b6106eb60048036038101906106e691906135ee565b611ab8565b005b6106f5611bec565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061080357507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610813575061081282611cdf565b5b9050919050565b60606003600001805461082c90613cb9565b80601f016020809104026020016040519081016040528092919081815260200182805461085890613cb9565b80156108a55780601f1061087a576101008083540402835291602001916108a5565b820191906000526020600020905b81548152906001019060200180831161088857829003601f168201915b5050505050905090565b60006108ba82611d49565b6108f0576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6015600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061093682610e72565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361099d576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166109bc611d84565b73ffffffffffffffffffffffffffffffffffffffff16141580156109ee57506109ec816109e7611d84565b611835565b155b15610a25576040517f4fb505aa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a30838383611d8c565b505050565b6000610a3f611d84565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ac3576040517f988a727000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b47905090565b600060025460015403905090565b600360060160009054906101000a900460ff16610bc757600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bf7bab7330836040518363ffffffff1660e01b8152600401610b4e929190613cea565b602060405180830381865afa158015610b6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8f9190613d28565b15610bc6576040517f1b73ba6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b610bd2838383611e3e565b505050565b600090565b610be4611bec565b6000600360060160036101000a81548160ff02191690836002811115610c0d57610c0c613d55565b5b0217905550565b610c1c611bec565b80600360060160026101000a81548160ff02191690831515021790555050565b610c578383836040518060200160405280600081525061152c565b505050565b6000610c6782611d49565b9050919050565b606060005b600154811015610df0576000610c8882612366565b90508373ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610de2578060400151610de157600360060160009054906101000a900460ff1615610d1057601a829080600181540180825580915050600190039060005260206000200160009091909190915055610de0565b600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bf7bab7330846040518363ffffffff1660e01b8152600401610d70929190613cea565b602060405180830381865afa158015610d8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db19190613d28565b610ddf57601a8290806001815401808255809150506001900390600052602060002001600090919091909150555b5b5b5b508080600101915050610c73565b50601a805480602002602001604051908101604052809291908181526020018280548015610e3d57602002820191906000526020600020905b815481526020019060010190808311610e29575b50505050509050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600360060160009054906101000a900460ff16610f3b57600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bf7bab7330846040518363ffffffff1660e01b8152600401610eeb929190613cea565b602060405180830381865afa158015610f08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2c9190613d28565b15610f3a5760009050610f4b565b5b610f4482612366565b6000015190505b919050565b610f58611bec565b80600a60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611006576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b611076611bec565b6001600360060160016101000a81548160ff02191690831515021790555081816003800191906110a7929190613266565b505050565b6110b4611bec565b84600c6001018190555083600c6002018190555081600c60000160016101000a81548160ff021916908360ff16021790555082600c60000160026101000a81548160ff021916908360ff16021790555080600c60000160036101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505050505050565b61113f611bec565b8181600380019190611152929190613266565b505050565b60606003600201805461116990613cb9565b80601f016020809104026020016040519081016040528092919081815260200182805461119590613cb9565b80156111e25780601f106111b7576101008083540402835291602001916111e2565b820191906000526020600020905b8154815290600101906020018083116111c557829003601f168201915b5050505050905090565b6111f4611bec565b6002600360060160036101000a81548160ff0219169083600281111561121d5761121c613d55565b5b0217905550565b600061122f82612366565b600001519050919050565b611242611bec565b61124a6125e2565b6112526126e7565b8173ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146112b0576112af8282612759565b5b6112ba82826127ec565b5050565b6112c6611d84565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361132a576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060176000611337611d84565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166113e4611d84565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611429919061348b565b60405180910390a35050565b61143d611bec565b8060036005018190555050565b6000600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bf7bab7330846040518363ffffffff1660e01b81526004016114ac929190613cea565b602060405180830381865afa1580156114c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ed9190613d28565b9050919050565b6114fc611bec565b6001600360060160036101000a81548160ff0219169083600281111561152557611524613d55565b5b0217905550565b600360060160009054906101000a900460ff1661161c57600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bf7bab7330846040518363ffffffff1660e01b81526004016115a3929190613cea565b602060405180830381865afa1580156115c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e49190613d28565b1561161b576040517f1b73ba6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b611627848484611e3e565b6116338484848461280a565b611669576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b606061167a82611d49565b6116b0576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380016116bd83612988565b6040516020016116ce929190613eec565b6040516020818303038152906040529050919050565b60606003800180546116f590613cb9565b80601f016020809104026020016040519081016040528092919081815260200182805461172190613cb9565b801561176e5780601f106117435761010080835404028352916020019161176e565b820191906000526020600020905b81548152906001019060200180831161175157829003601f168201915b5050505050905090565b60006117848383612759565b8161178e84612ae8565b6117989190613f55565b905092915050565b6060600360040180546117b290613cb9565b80601f01602080910402602001604051908101604052809291908181526020018280546117de90613cb9565b801561182b5780601f106118005761010080835404028352916020019161182b565b820191906000526020600020905b81548152906001019060200180831161180e57829003601f168201915b5050505050905090565b6000601760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60006118d3611d84565b90508073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480611a2857508073ffffffffffffffffffffffffffffffffffffffff16600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148015611a275750600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bf7bab7330856040518363ffffffff1660e01b81526004016119e5929190613cea565b602060405180830381865afa158015611a02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a269190613d28565b5b5b15611a81578173ffffffffffffffffffffffffffffffffffffffff16611a4d84611224565b73ffffffffffffffffffffffffffffffffffffffff1614611a7c57611a7b611a7484611224565b8385611e3e565b5b611ab3565b6040517f1b73ba6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b611ac0611d84565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611b44576040517f988a727000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80471015611b7e576040517fffec2f6f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611bc4573d6000803e3d6000fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000611bf6611d84565b905060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015611ca55750600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b15611cdc576040517f988a727000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600060015482108015611d7d575060146000838152602001908152602001600020600001601c9054906101000a900460ff16155b9050919050565b600033905090565b826015600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000611e4982612366565b90506000611e55611d84565b90506000600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480611ee75750826000015173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b80611f255750611ef6846108af565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b80611f3a5750611f39836000015183611835565b5b905080611f73576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614611fdc576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612042576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120526000858560000151611d8c565b6001601660008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160392506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001601660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550846014600086815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426014600086815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600185019050600073ffffffffffffffffffffffffffffffffffffffff166014600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603612302576001548110156123015783600001516014600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083602001516014600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b50838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b61236e6132ec565b60008290506001548110156125ab576000601460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff161515151581525050905080604001516125a957600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161461248d5780925050506125dd565b5b6001156125a857818060019003925050601460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16146125a35780925050506125dd565b61248e565b5b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600360060160029054906101000a900460ff16156126e5576000600c6005015490506000600c6006015490506000600c60070154905042831115801561262757508142105b1561265f576001600360060160036101000a81548160ff0219169083600281111561265557612654613d55565b5b02179055506126e1565b4282111580156126795750804210806126785750806000145b5b156126b1576002600360060160036101000a81548160ff021916908360028111156126a7576126a6613d55565b5b02179055506126e0565b6000600360060160036101000a81548160ff021916908360028111156126da576126d9613d55565b5b02179055505b5b5050505b565b600360060160039054906101000a900460ff16600281111561270c5761270b613d55565b5b600060028111156127205761271f613d55565b5b03612757576040517f08a69c7f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6127748161276684612ae8565b61276f85612bb7565b612c86565b6127aa576040517f271c929900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6127b2612d8f565b6127e8576040517f271c929900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b612806828260405180602001604052806000815250612dfa565b5050565b600061282b8473ffffffffffffffffffffffffffffffffffffffff16611bc9565b1561297b578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612854611d84565b8786866040518563ffffffff1660e01b81526004016128769493929190614000565b6020604051808303816000875af19250505080156128b257506040513d601f19601f820116820180604052508101906128af9190614061565b60015b61292b573d80600081146128e2576040519150601f19603f3d011682016040523d82523d6000602084013e6128e7565b606091505b506000815103612923576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612980565b600190505b949350505050565b6060816000036129cf576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612ae3565b600082905060005b81600014612a015780806129ea9061408e565b915050600a826129fa9190614105565b91506129d7565b60008167ffffffffffffffff811115612a1d57612a1c613a5c565b5b6040519080825280601f01601f191660200182016040528015612a4f5781602001600182028036833780820191505090505b5090505b84600014612adc57600182612a689190614136565b9150600a85612a77919061416a565b6030612a839190613f55565b60f81b818381518110612a9957612a9861419b565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612ad59190614105565b9450612a53565b8093505050505b919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612b4f576040517f35ebb31900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160089054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612c1e576040517f35ebb31900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b600060016002811115612c9c57612c9b613d55565b5b600360060160039054906101000a900460ff166002811115612cc157612cc0613d55565b5b148015612cee57508284612cd59190613f55565b600c60000160009054906101000a900460ff1660ff1610155b80612d865750600280811115612d0757612d06613d55565b5b600360060160039054906101000a900460ff166002811115612d2c57612d2b613d55565b5b148015612d645750818385612d419190613f55565b612d4b9190614136565b600c60000160019054906101000a900460ff1660ff1610155b8015612d85575083600c60000160029054906101000a900460ff1660ff1611155b5b90509392505050565b6000600360060160009054906101000a900460ff1680612df5575060001515600360060160009054906101000a900460ff161515148015612df45750600154600c60000160039054906101000a900467ffffffffffffffff1667ffffffffffffffff16115b5b905090565b612e078383836001612e0c565b505050565b60006001549050612e1b612d8f565b612e51576040517f271c929900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612eb7576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008403612ef1576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83601660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555083601660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001600281111561300957613008613d55565b5b600360060160039054906101000a900460ff16600281111561302e5761302d613d55565b5b036130f55783601660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160109054906101000a900467ffffffffffffffff1601601660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160106101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b846014600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426014600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600081905060005b8581101561325657818773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a483801561320a5750613208600088848861280a565b155b15613241576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8180600101925050808060010191505061318f565b5080600181905550505050505050565b82805461327290613cb9565b90600052602060002090601f01602090048101928261329457600085556132db565b82601f106132ad57803560ff19168380011785556132db565b828001600101855582156132db579182015b828111156132da5782358255916020019190600101906132bf565b5b5090506132e8919061332f565b5090565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681526020016000151581525090565b5b80821115613348576000816000905550600101613330565b5090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061338b82613360565b9050919050565b61339b81613380565b81146133a657600080fd5b50565b6000813590506133b881613392565b92915050565b6000602082840312156133d4576133d3613356565b5b60006133e2848285016133a9565b91505092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613420816133eb565b811461342b57600080fd5b50565b60008135905061343d81613417565b92915050565b60006020828403121561345957613458613356565b5b60006134678482850161342e565b91505092915050565b60008115159050919050565b61348581613470565b82525050565b60006020820190506134a0600083018461347c565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156134e05780820151818401526020810190506134c5565b838111156134ef576000848401525b50505050565b6000601f19601f8301169050919050565b6000613511826134a6565b61351b81856134b1565b935061352b8185602086016134c2565b613534816134f5565b840191505092915050565b600060208201905081810360008301526135598184613506565b905092915050565b6000819050919050565b61357481613561565b811461357f57600080fd5b50565b6000813590506135918161356b565b92915050565b6000602082840312156135ad576135ac613356565b5b60006135bb84828501613582565b91505092915050565b6135cd81613380565b82525050565b60006020820190506135e860008301846135c4565b92915050565b6000806040838503121561360557613604613356565b5b6000613613858286016133a9565b925050602061362485828601613582565b9150509250929050565b61363781613561565b82525050565b6000602082019050613652600083018461362e565b92915050565b60008060006060848603121561367157613670613356565b5b600061367f868287016133a9565b9350506020613690868287016133a9565b92505060406136a186828701613582565b9150509250925092565b600060ff82169050919050565b6136c1816136ab565b82525050565b60006020820190506136dc60008301846136b8565b92915050565b6136eb81613470565b81146136f657600080fd5b50565b600081359050613708816136e2565b92915050565b60006020828403121561372457613723613356565b5b6000613732848285016136f9565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61377081613561565b82525050565b60006137828383613767565b60208301905092915050565b6000602082019050919050565b60006137a68261373b565b6137b08185613746565b93506137bb83613757565b8060005b838110156137ec5781516137d38882613776565b97506137de8361378e565b9250506001810190506137bf565b5085935050505092915050565b60006020820190508181036000830152613813818461379b565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126138405761383f61381b565b5b8235905067ffffffffffffffff81111561385d5761385c613820565b5b60208301915083600182028301111561387957613878613825565b5b9250929050565b6000806020838503121561389757613896613356565b5b600083013567ffffffffffffffff8111156138b5576138b461335b565b5b6138c18582860161382a565b92509250509250929050565b6138d6816136ab565b81146138e157600080fd5b50565b6000813590506138f3816138cd565b92915050565b600067ffffffffffffffff82169050919050565b613916816138f9565b811461392157600080fd5b50565b6000813590506139338161390d565b92915050565b600080600080600060a0868803121561395557613954613356565b5b600061396388828901613582565b955050602061397488828901613582565b9450506040613985888289016138e4565b9350506060613996888289016138e4565b92505060806139a788828901613924565b9150509295509295909350565b600080604083850312156139cb576139ca613356565b5b60006139d9858286016133a9565b92505060206139ea858286016136f9565b9150509250929050565b6000819050919050565b613a07816139f4565b8114613a1257600080fd5b50565b600081359050613a24816139fe565b92915050565b600060208284031215613a4057613a3f613356565b5b6000613a4e84828501613a15565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613a94826134f5565b810181811067ffffffffffffffff82111715613ab357613ab2613a5c565b5b80604052505050565b6000613ac661334c565b9050613ad28282613a8b565b919050565b600067ffffffffffffffff821115613af257613af1613a5c565b5b613afb826134f5565b9050602081019050919050565b82818337600083830152505050565b6000613b2a613b2584613ad7565b613abc565b905082815260208101848484011115613b4657613b45613a57565b5b613b51848285613b08565b509392505050565b600082601f830112613b6e57613b6d61381b565b5b8135613b7e848260208601613b17565b91505092915050565b60008060008060808587031215613ba157613ba0613356565b5b6000613baf878288016133a9565b9450506020613bc0878288016133a9565b9350506040613bd187828801613582565b925050606085013567ffffffffffffffff811115613bf257613bf161335b565b5b613bfe87828801613b59565b91505092959194509250565b60008060408385031215613c2157613c20613356565b5b6000613c2f858286016133a9565b9250506020613c40858286016133a9565b9150509250929050565b60008060408385031215613c6157613c60613356565b5b6000613c6f85828601613582565b9250506020613c80858286016133a9565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613cd157607f821691505b602082108103613ce457613ce3613c8a565b5b50919050565b6000604082019050613cff60008301856135c4565b613d0c602083018461362e565b9392505050565b600081519050613d22816136e2565b92915050565b600060208284031215613d3e57613d3d613356565b5b6000613d4c84828501613d13565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600081905092915050565b60008190508160005260206000209050919050565b60008154613db181613cb9565b613dbb8186613d84565b94506001821660008114613dd65760018114613de757613e1a565b60ff19831686528186019350613e1a565b613df085613d8f565b60005b83811015613e1257815481890152600182019150602081019050613df3565b838801955050505b50505092915050565b7f2f00000000000000000000000000000000000000000000000000000000000000600082015250565b6000613e59600183613d84565b9150613e6482613e23565b600182019050919050565b6000613e7a826134a6565b613e848185613d84565b9350613e948185602086016134c2565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000613ed6600583613d84565b9150613ee182613ea0565b600582019050919050565b6000613ef88285613da4565b9150613f0382613e4c565b9150613f0f8284613e6f565b9150613f1a82613ec9565b91508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613f6082613561565b9150613f6b83613561565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613fa057613f9f613f26565b5b828201905092915050565b600081519050919050565b600082825260208201905092915050565b6000613fd282613fab565b613fdc8185613fb6565b9350613fec8185602086016134c2565b613ff5816134f5565b840191505092915050565b600060808201905061401560008301876135c4565b61402260208301866135c4565b61402f604083018561362e565b81810360608301526140418184613fc7565b905095945050505050565b60008151905061405b81613417565b92915050565b60006020828403121561407757614076613356565b5b60006140858482850161404c565b91505092915050565b600061409982613561565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036140cb576140ca613f26565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061411082613561565b915061411b83613561565b92508261412b5761412a6140d6565b5b828204905092915050565b600061414182613561565b915061414c83613561565b92508282101561415f5761415e613f26565b5b828203905092915050565b600061417582613561565b915061418083613561565b9250826141905761418f6140d6565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220341afd50eae57b9ccf93ed6bfdf3557e52a96465130c446f7cf2d4842705a49764736f6c634300080d003300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000e41696c6f7665727365204361747300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000741494c4f43415400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007568747470733a2f2f636f6c6c656374696f6e2e61696c6f76657273652e636f6d2f73746f726167652f66696c65732f746f6b656e2f643365303435653438393131663265326230353164643735626233663534313437396231396335653762653064386531366633623531323666386337383339640000000000000000000000000000000000000000000000000000000000000000000000000000000000007d68747470733a2f2f636f6c6c656374696f6e2e61696c6f76657273652e636f6d2f73746f726167652f66696c65732f636f6e74726163742f643365303435653438393131663265326230353164643735626233663534313437396231396335653762653064386531366633623531323666386337383339642e6a736f6e000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102265760003560e01c8063794100b911610130578063b45a3c0e116100b8578063e2898bd51161007c578063e2898bd514610637578063e8a3d48514610667578063e985e9c514610685578063f1d2ec1d146106b5578063f3fef3a3146106d157610226565b8063b45a3c0e14610593578063b4e99839146105c3578063b88d4fde146105cd578063c87b56dd146105e9578063d547cfb71461061957610226565b80639ece3398116100ff5780639ece339814610505578063a084c6ad1461050f578063a14481941461053f578063a22cb4651461055b578063b11c7f821461057757610226565b8063794100b914610493578063864aa866146104af578063870d6f9d146104cb57806395d89b41146104e757610226565b80633e3e0b12116101b35780635a3f2672116101825780635a3f2672146103c95780635ca1e165146103f95780636352211e1461041757806368d4e4ef1461044757806370a082311461046357610226565b80633e3e0b12146103575780633e6007e01461036157806342842e0e1461037d5780634f558e791461039957610226565b8063095ea7b3116101fa578063095ea7b3146102c557806312065fe0146102e157806318160ddd146102ff57806323b872dd1461031d578063313ce5671461033957610226565b80623ba1ed1461022b57806301ffc9a71461024757806306fdde0314610277578063081812fc14610295575b600080fd5b610245600480360381019061024091906133be565b6106ed565b005b610261600480360381019061025c9190613443565b610738565b60405161026e919061348b565b60405180910390f35b61027f61081a565b60405161028c919061353f565b60405180910390f35b6102af60048036038101906102aa9190613597565b6108af565b6040516102bc91906135d3565b60405180910390f35b6102df60048036038101906102da91906135ee565b61092b565b005b6102e9610a35565b6040516102f6919061363d565b60405180910390f35b610307610ac9565b604051610314919061363d565b60405180910390f35b61033760048036038101906103329190613658565b610ad7565b005b610341610bd7565b60405161034e91906136c7565b60405180910390f35b61035f610bdc565b005b61037b6004803603810190610376919061370e565b610c14565b005b61039760048036038101906103929190613658565b610c3c565b005b6103b360048036038101906103ae9190613597565b610c5c565b6040516103c0919061348b565b60405180910390f35b6103e360048036038101906103de91906133be565b610c6e565b6040516103f091906137f9565b60405180910390f35b610401610e49565b60405161040e91906135d3565b60405180910390f35b610431600480360381019061042c9190613597565b610e72565b60405161043e91906135d3565b60405180910390f35b610461600480360381019061045c91906133be565b610f50565b005b61047d600480360381019061047891906133be565b610f9f565b60405161048a919061363d565b60405180910390f35b6104ad60048036038101906104a89190613880565b61106e565b005b6104c960048036038101906104c49190613939565b6110ac565b005b6104e560048036038101906104e09190613880565b611137565b005b6104ef611157565b6040516104fc919061353f565b60405180910390f35b61050d6111ec565b005b61052960048036038101906105249190613597565b611224565b60405161053691906135d3565b60405180910390f35b610559600480360381019061055491906135ee565b61123a565b005b610575600480360381019061057091906139b4565b6112be565b005b610591600480360381019061058c9190613a2a565b611435565b005b6105ad60048036038101906105a89190613597565b61144a565b6040516105ba919061348b565b60405180910390f35b6105cb6114f4565b005b6105e760048036038101906105e29190613b87565b61152c565b005b61060360048036038101906105fe9190613597565b61166f565b604051610610919061353f565b60405180910390f35b6106216116e4565b60405161062e919061353f565b60405180910390f35b610651600480360381019061064c91906135ee565b611778565b60405161065e919061363d565b60405180910390f35b61066f6117a0565b60405161067c919061353f565b60405180910390f35b61069f600480360381019061069a9190613c0a565b611835565b6040516106ac919061348b565b60405180910390f35b6106cf60048036038101906106ca9190613c4a565b6118c9565b005b6106eb60048036038101906106e691906135ee565b611ab8565b005b6106f5611bec565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061080357507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610813575061081282611cdf565b5b9050919050565b60606003600001805461082c90613cb9565b80601f016020809104026020016040519081016040528092919081815260200182805461085890613cb9565b80156108a55780601f1061087a576101008083540402835291602001916108a5565b820191906000526020600020905b81548152906001019060200180831161088857829003601f168201915b5050505050905090565b60006108ba82611d49565b6108f0576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6015600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061093682610e72565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361099d576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166109bc611d84565b73ffffffffffffffffffffffffffffffffffffffff16141580156109ee57506109ec816109e7611d84565b611835565b155b15610a25576040517f4fb505aa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a30838383611d8c565b505050565b6000610a3f611d84565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ac3576040517f988a727000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b47905090565b600060025460015403905090565b600360060160009054906101000a900460ff16610bc757600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bf7bab7330836040518363ffffffff1660e01b8152600401610b4e929190613cea565b602060405180830381865afa158015610b6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8f9190613d28565b15610bc6576040517f1b73ba6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b610bd2838383611e3e565b505050565b600090565b610be4611bec565b6000600360060160036101000a81548160ff02191690836002811115610c0d57610c0c613d55565b5b0217905550565b610c1c611bec565b80600360060160026101000a81548160ff02191690831515021790555050565b610c578383836040518060200160405280600081525061152c565b505050565b6000610c6782611d49565b9050919050565b606060005b600154811015610df0576000610c8882612366565b90508373ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610de2578060400151610de157600360060160009054906101000a900460ff1615610d1057601a829080600181540180825580915050600190039060005260206000200160009091909190915055610de0565b600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bf7bab7330846040518363ffffffff1660e01b8152600401610d70929190613cea565b602060405180830381865afa158015610d8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db19190613d28565b610ddf57601a8290806001815401808255809150506001900390600052602060002001600090919091909150555b5b5b5b508080600101915050610c73565b50601a805480602002602001604051908101604052809291908181526020018280548015610e3d57602002820191906000526020600020905b815481526020019060010190808311610e29575b50505050509050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600360060160009054906101000a900460ff16610f3b57600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bf7bab7330846040518363ffffffff1660e01b8152600401610eeb929190613cea565b602060405180830381865afa158015610f08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2c9190613d28565b15610f3a5760009050610f4b565b5b610f4482612366565b6000015190505b919050565b610f58611bec565b80600a60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611006576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b611076611bec565b6001600360060160016101000a81548160ff02191690831515021790555081816003800191906110a7929190613266565b505050565b6110b4611bec565b84600c6001018190555083600c6002018190555081600c60000160016101000a81548160ff021916908360ff16021790555082600c60000160026101000a81548160ff021916908360ff16021790555080600c60000160036101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505050505050565b61113f611bec565b8181600380019190611152929190613266565b505050565b60606003600201805461116990613cb9565b80601f016020809104026020016040519081016040528092919081815260200182805461119590613cb9565b80156111e25780601f106111b7576101008083540402835291602001916111e2565b820191906000526020600020905b8154815290600101906020018083116111c557829003601f168201915b5050505050905090565b6111f4611bec565b6002600360060160036101000a81548160ff0219169083600281111561121d5761121c613d55565b5b0217905550565b600061122f82612366565b600001519050919050565b611242611bec565b61124a6125e2565b6112526126e7565b8173ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146112b0576112af8282612759565b5b6112ba82826127ec565b5050565b6112c6611d84565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361132a576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060176000611337611d84565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166113e4611d84565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611429919061348b565b60405180910390a35050565b61143d611bec565b8060036005018190555050565b6000600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bf7bab7330846040518363ffffffff1660e01b81526004016114ac929190613cea565b602060405180830381865afa1580156114c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ed9190613d28565b9050919050565b6114fc611bec565b6001600360060160036101000a81548160ff0219169083600281111561152557611524613d55565b5b0217905550565b600360060160009054906101000a900460ff1661161c57600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bf7bab7330846040518363ffffffff1660e01b81526004016115a3929190613cea565b602060405180830381865afa1580156115c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e49190613d28565b1561161b576040517f1b73ba6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b611627848484611e3e565b6116338484848461280a565b611669576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b606061167a82611d49565b6116b0576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380016116bd83612988565b6040516020016116ce929190613eec565b6040516020818303038152906040529050919050565b60606003800180546116f590613cb9565b80601f016020809104026020016040519081016040528092919081815260200182805461172190613cb9565b801561176e5780601f106117435761010080835404028352916020019161176e565b820191906000526020600020905b81548152906001019060200180831161175157829003601f168201915b5050505050905090565b60006117848383612759565b8161178e84612ae8565b6117989190613f55565b905092915050565b6060600360040180546117b290613cb9565b80601f01602080910402602001604051908101604052809291908181526020018280546117de90613cb9565b801561182b5780601f106118005761010080835404028352916020019161182b565b820191906000526020600020905b81548152906001019060200180831161180e57829003601f168201915b5050505050905090565b6000601760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60006118d3611d84565b90508073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480611a2857508073ffffffffffffffffffffffffffffffffffffffff16600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148015611a275750600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bf7bab7330856040518363ffffffff1660e01b81526004016119e5929190613cea565b602060405180830381865afa158015611a02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a269190613d28565b5b5b15611a81578173ffffffffffffffffffffffffffffffffffffffff16611a4d84611224565b73ffffffffffffffffffffffffffffffffffffffff1614611a7c57611a7b611a7484611224565b8385611e3e565b5b611ab3565b6040517f1b73ba6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b611ac0611d84565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611b44576040517f988a727000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80471015611b7e576040517fffec2f6f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611bc4573d6000803e3d6000fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000611bf6611d84565b905060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015611ca55750600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b15611cdc576040517f988a727000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600060015482108015611d7d575060146000838152602001908152602001600020600001601c9054906101000a900460ff16155b9050919050565b600033905090565b826015600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000611e4982612366565b90506000611e55611d84565b90506000600a60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480611ee75750826000015173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b80611f255750611ef6846108af565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b80611f3a5750611f39836000015183611835565b5b905080611f73576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614611fdc576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612042576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120526000858560000151611d8c565b6001601660008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160392506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001601660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550846014600086815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426014600086815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600185019050600073ffffffffffffffffffffffffffffffffffffffff166014600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603612302576001548110156123015783600001516014600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083602001516014600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b50838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b61236e6132ec565b60008290506001548110156125ab576000601460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff161515151581525050905080604001516125a957600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161461248d5780925050506125dd565b5b6001156125a857818060019003925050601460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16146125a35780925050506125dd565b61248e565b5b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600360060160029054906101000a900460ff16156126e5576000600c6005015490506000600c6006015490506000600c60070154905042831115801561262757508142105b1561265f576001600360060160036101000a81548160ff0219169083600281111561265557612654613d55565b5b02179055506126e1565b4282111580156126795750804210806126785750806000145b5b156126b1576002600360060160036101000a81548160ff021916908360028111156126a7576126a6613d55565b5b02179055506126e0565b6000600360060160036101000a81548160ff021916908360028111156126da576126d9613d55565b5b02179055505b5b5050505b565b600360060160039054906101000a900460ff16600281111561270c5761270b613d55565b5b600060028111156127205761271f613d55565b5b03612757576040517f08a69c7f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6127748161276684612ae8565b61276f85612bb7565b612c86565b6127aa576040517f271c929900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6127b2612d8f565b6127e8576040517f271c929900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b612806828260405180602001604052806000815250612dfa565b5050565b600061282b8473ffffffffffffffffffffffffffffffffffffffff16611bc9565b1561297b578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612854611d84565b8786866040518563ffffffff1660e01b81526004016128769493929190614000565b6020604051808303816000875af19250505080156128b257506040513d601f19601f820116820180604052508101906128af9190614061565b60015b61292b573d80600081146128e2576040519150601f19603f3d011682016040523d82523d6000602084013e6128e7565b606091505b506000815103612923576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612980565b600190505b949350505050565b6060816000036129cf576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612ae3565b600082905060005b81600014612a015780806129ea9061408e565b915050600a826129fa9190614105565b91506129d7565b60008167ffffffffffffffff811115612a1d57612a1c613a5c565b5b6040519080825280601f01601f191660200182016040528015612a4f5781602001600182028036833780820191505090505b5090505b84600014612adc57600182612a689190614136565b9150600a85612a77919061416a565b6030612a839190613f55565b60f81b818381518110612a9957612a9861419b565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612ad59190614105565b9450612a53565b8093505050505b919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612b4f576040517f35ebb31900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160089054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612c1e576040517f35ebb31900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b600060016002811115612c9c57612c9b613d55565b5b600360060160039054906101000a900460ff166002811115612cc157612cc0613d55565b5b148015612cee57508284612cd59190613f55565b600c60000160009054906101000a900460ff1660ff1610155b80612d865750600280811115612d0757612d06613d55565b5b600360060160039054906101000a900460ff166002811115612d2c57612d2b613d55565b5b148015612d645750818385612d419190613f55565b612d4b9190614136565b600c60000160019054906101000a900460ff1660ff1610155b8015612d85575083600c60000160029054906101000a900460ff1660ff1611155b5b90509392505050565b6000600360060160009054906101000a900460ff1680612df5575060001515600360060160009054906101000a900460ff161515148015612df45750600154600c60000160039054906101000a900467ffffffffffffffff1667ffffffffffffffff16115b5b905090565b612e078383836001612e0c565b505050565b60006001549050612e1b612d8f565b612e51576040517f271c929900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612eb7576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008403612ef1576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83601660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555083601660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001600281111561300957613008613d55565b5b600360060160039054906101000a900460ff16600281111561302e5761302d613d55565b5b036130f55783601660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160109054906101000a900467ffffffffffffffff1601601660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160106101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b846014600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426014600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600081905060005b8581101561325657818773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a483801561320a5750613208600088848861280a565b155b15613241576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8180600101925050808060010191505061318f565b5080600181905550505050505050565b82805461327290613cb9565b90600052602060002090601f01602090048101928261329457600085556132db565b82601f106132ad57803560ff19168380011785556132db565b828001600101855582156132db579182015b828111156132da5782358255916020019190600101906132bf565b5b5090506132e8919061332f565b5090565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681526020016000151581525090565b5b80821115613348576000816000905550600101613330565b5090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061338b82613360565b9050919050565b61339b81613380565b81146133a657600080fd5b50565b6000813590506133b881613392565b92915050565b6000602082840312156133d4576133d3613356565b5b60006133e2848285016133a9565b91505092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613420816133eb565b811461342b57600080fd5b50565b60008135905061343d81613417565b92915050565b60006020828403121561345957613458613356565b5b60006134678482850161342e565b91505092915050565b60008115159050919050565b61348581613470565b82525050565b60006020820190506134a0600083018461347c565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156134e05780820151818401526020810190506134c5565b838111156134ef576000848401525b50505050565b6000601f19601f8301169050919050565b6000613511826134a6565b61351b81856134b1565b935061352b8185602086016134c2565b613534816134f5565b840191505092915050565b600060208201905081810360008301526135598184613506565b905092915050565b6000819050919050565b61357481613561565b811461357f57600080fd5b50565b6000813590506135918161356b565b92915050565b6000602082840312156135ad576135ac613356565b5b60006135bb84828501613582565b91505092915050565b6135cd81613380565b82525050565b60006020820190506135e860008301846135c4565b92915050565b6000806040838503121561360557613604613356565b5b6000613613858286016133a9565b925050602061362485828601613582565b9150509250929050565b61363781613561565b82525050565b6000602082019050613652600083018461362e565b92915050565b60008060006060848603121561367157613670613356565b5b600061367f868287016133a9565b9350506020613690868287016133a9565b92505060406136a186828701613582565b9150509250925092565b600060ff82169050919050565b6136c1816136ab565b82525050565b60006020820190506136dc60008301846136b8565b92915050565b6136eb81613470565b81146136f657600080fd5b50565b600081359050613708816136e2565b92915050565b60006020828403121561372457613723613356565b5b6000613732848285016136f9565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61377081613561565b82525050565b60006137828383613767565b60208301905092915050565b6000602082019050919050565b60006137a68261373b565b6137b08185613746565b93506137bb83613757565b8060005b838110156137ec5781516137d38882613776565b97506137de8361378e565b9250506001810190506137bf565b5085935050505092915050565b60006020820190508181036000830152613813818461379b565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126138405761383f61381b565b5b8235905067ffffffffffffffff81111561385d5761385c613820565b5b60208301915083600182028301111561387957613878613825565b5b9250929050565b6000806020838503121561389757613896613356565b5b600083013567ffffffffffffffff8111156138b5576138b461335b565b5b6138c18582860161382a565b92509250509250929050565b6138d6816136ab565b81146138e157600080fd5b50565b6000813590506138f3816138cd565b92915050565b600067ffffffffffffffff82169050919050565b613916816138f9565b811461392157600080fd5b50565b6000813590506139338161390d565b92915050565b600080600080600060a0868803121561395557613954613356565b5b600061396388828901613582565b955050602061397488828901613582565b9450506040613985888289016138e4565b9350506060613996888289016138e4565b92505060806139a788828901613924565b9150509295509295909350565b600080604083850312156139cb576139ca613356565b5b60006139d9858286016133a9565b92505060206139ea858286016136f9565b9150509250929050565b6000819050919050565b613a07816139f4565b8114613a1257600080fd5b50565b600081359050613a24816139fe565b92915050565b600060208284031215613a4057613a3f613356565b5b6000613a4e84828501613a15565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613a94826134f5565b810181811067ffffffffffffffff82111715613ab357613ab2613a5c565b5b80604052505050565b6000613ac661334c565b9050613ad28282613a8b565b919050565b600067ffffffffffffffff821115613af257613af1613a5c565b5b613afb826134f5565b9050602081019050919050565b82818337600083830152505050565b6000613b2a613b2584613ad7565b613abc565b905082815260208101848484011115613b4657613b45613a57565b5b613b51848285613b08565b509392505050565b600082601f830112613b6e57613b6d61381b565b5b8135613b7e848260208601613b17565b91505092915050565b60008060008060808587031215613ba157613ba0613356565b5b6000613baf878288016133a9565b9450506020613bc0878288016133a9565b9350506040613bd187828801613582565b925050606085013567ffffffffffffffff811115613bf257613bf161335b565b5b613bfe87828801613b59565b91505092959194509250565b60008060408385031215613c2157613c20613356565b5b6000613c2f858286016133a9565b9250506020613c40858286016133a9565b9150509250929050565b60008060408385031215613c6157613c60613356565b5b6000613c6f85828601613582565b9250506020613c80858286016133a9565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613cd157607f821691505b602082108103613ce457613ce3613c8a565b5b50919050565b6000604082019050613cff60008301856135c4565b613d0c602083018461362e565b9392505050565b600081519050613d22816136e2565b92915050565b600060208284031215613d3e57613d3d613356565b5b6000613d4c84828501613d13565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600081905092915050565b60008190508160005260206000209050919050565b60008154613db181613cb9565b613dbb8186613d84565b94506001821660008114613dd65760018114613de757613e1a565b60ff19831686528186019350613e1a565b613df085613d8f565b60005b83811015613e1257815481890152600182019150602081019050613df3565b838801955050505b50505092915050565b7f2f00000000000000000000000000000000000000000000000000000000000000600082015250565b6000613e59600183613d84565b9150613e6482613e23565b600182019050919050565b6000613e7a826134a6565b613e848185613d84565b9350613e948185602086016134c2565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000613ed6600583613d84565b9150613ee182613ea0565b600582019050919050565b6000613ef88285613da4565b9150613f0382613e4c565b9150613f0f8284613e6f565b9150613f1a82613ec9565b91508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613f6082613561565b9150613f6b83613561565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613fa057613f9f613f26565b5b828201905092915050565b600081519050919050565b600082825260208201905092915050565b6000613fd282613fab565b613fdc8185613fb6565b9350613fec8185602086016134c2565b613ff5816134f5565b840191505092915050565b600060808201905061401560008301876135c4565b61402260208301866135c4565b61402f604083018561362e565b81810360608301526140418184613fc7565b905095945050505050565b60008151905061405b81613417565b92915050565b60006020828403121561407757614076613356565b5b60006140858482850161404c565b91505092915050565b600061409982613561565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036140cb576140ca613f26565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061411082613561565b915061411b83613561565b92508261412b5761412a6140d6565b5b828204905092915050565b600061414182613561565b915061414c83613561565b92508282101561415f5761415e613f26565b5b828203905092915050565b600061417582613561565b915061418083613561565b9250826141905761418f6140d6565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220341afd50eae57b9ccf93ed6bfdf3557e52a96465130c446f7cf2d4842705a49764736f6c634300080d0033

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

00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000e41696c6f7665727365204361747300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000741494c4f43415400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007568747470733a2f2f636f6c6c656374696f6e2e61696c6f76657273652e636f6d2f73746f726167652f66696c65732f746f6b656e2f643365303435653438393131663265326230353164643735626233663534313437396231396335653762653064386531366633623531323666386337383339640000000000000000000000000000000000000000000000000000000000000000000000000000000000007d68747470733a2f2f636f6c6c656374696f6e2e61696c6f76657273652e636f6d2f73746f726167652f66696c65732f636f6e74726163742f643365303435653438393131663265326230353164643735626233663534313437396231396335653762653064386531366633623531323666386337383339642e6a736f6e000000

-----Decoded View---------------
Arg [0] : name_ (string): Ailoverse Cats
Arg [1] : description_ (string):
Arg [2] : symbol_ (string): AILOCAT
Arg [3] : baseURL_ (string): https://collection.ailoverse.com/storage/files/token/d3e045e48911f2e2b051dd75bb3f541479b19c5e7be0d8e16f3b5126f8c7839d
Arg [4] : contractURL_ (string): https://collection.ailoverse.com/storage/files/contract/d3e045e48911f2e2b051dd75bb3f541479b19c5e7be0d8e16f3b5126f8c7839d.json

-----Encoded View---------------
21 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000200
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [6] : 41696c6f76657273652043617473000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [10] : 41494c4f43415400000000000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000075
Arg [12] : 68747470733a2f2f636f6c6c656374696f6e2e61696c6f76657273652e636f6d
Arg [13] : 2f73746f726167652f66696c65732f746f6b656e2f6433653034356534383931
Arg [14] : 3166326532623035316464373562623366353431343739623139633565376265
Arg [15] : 3064386531366633623531323666386337383339640000000000000000000000
Arg [16] : 000000000000000000000000000000000000000000000000000000000000007d
Arg [17] : 68747470733a2f2f636f6c6c656374696f6e2e61696c6f76657273652e636f6d
Arg [18] : 2f73746f726167652f66696c65732f636f6e74726163742f6433653034356534
Arg [19] : 3839313166326532623035316464373562623366353431343739623139633565
Arg [20] : 3762653064386531366633623531323666386337383339642e6a736f6e000000


Deployed Bytecode Sourcemap

62264:2370:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59926:116;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;37257:324;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52518:134;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39737:252;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39297:374;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51676:190;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36900:285;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40687:348;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53626:91;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61241:126;;;:::i;:::-;;60801:135;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;41106:185;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;59800:118;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33185:775;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60050:96;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38905:330;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62829:131;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;37645:238;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61863:174;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;61375:480;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;62045:134;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;52721:138;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61095:133;;;:::i;:::-;;63986:150;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62968:272;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;40061:305;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35502:119;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63796:182;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60944:139;;;:::i;:::-;;41362:491;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53197:421;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52867:123;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63248:211;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53000:126;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40437:183;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64144:485;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51874:270;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;59926:116;59989:10;:8;:10::i;:::-;60028:6;60020:5;;:14;;;;;;;;;;;;;;;;;;59926:116;:::o;37257:324::-;37373:4;37430:25;37415:40;;;:11;:40;;;;:105;;;;37487:33;37472:48;;;:11;:48;;;;37415:105;:158;;;;37537:36;37561:11;37537:23;:36::i;:::-;37415:158;37395:178;;37257:324;;;:::o;52518:134::-;52588:13;52626;:18;;52619:25;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52518:134;:::o;39737:252::-;39819:7;39849:16;39857:7;39849;:16::i;:::-;39844:137;;39887:34;;;;;;;;;;;;;;39844:137;39957:15;:24;39973:7;39957:24;;;;;;;;;;;;;;;;;;;;;39937:44;;39737:252;;;:::o;39297:374::-;39385:13;39401:24;39417:7;39401:15;:24::i;:::-;39385:40;;39446:5;39440:11;;:2;:11;;;39436:61;;39473:24;;;;;;;;;;;;;;39436:61;39528:5;39512:21;;:12;:10;:12::i;:::-;:21;;;;:63;;;;;39538:37;39555:5;39562:12;:10;:12::i;:::-;39538:16;:37::i;:::-;39537:38;39512:63;39508:116;;;39597:27;;;;;;;;;;;;;;39508:116;39635:28;39644:2;39648:7;39657:5;39635:8;:28::i;:::-;39374:297;39297:374;;:::o;51676:190::-;51730:7;51767:12;:10;:12::i;:::-;51758:21;;:5;;;;;;;;;;:21;;;51755:64;;51801:18;;;;;;;;;;;;;;51755:64;51837:21;51830:28;;51676:190;:::o;36900:285::-;36953:7;37150:12;;37134:13;;:28;37127:35;;36900:285;:::o;40687:348::-;40825:13;:24;;;;;;;;;;;;40821:149;;40877:14;:23;;;;;;;;;;;;40867:41;;;40917:4;40923:7;40867:64;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40864:106;;;40957:13;;;;;;;;;;;;;;40864:106;40821:149;40999:28;41009:4;41015:2;41019:7;40999:9;:28::i;:::-;40687:348;;;:::o;53626:91::-;53678:5;53626:91;:::o;61241:126::-;61294:10;:8;:10::i;:::-;61344:15;61317:13;:24;;;:42;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;61241:126::o;60801:135::-;60869:10;:8;:10::i;:::-;60923:5;60892:13;:28;;;:36;;;;;;;;;;;;;;;;;;60801:135;:::o;41106:185::-;41244:39;41261:4;41267:2;41271:7;41244:39;;;;;;;;;;;;:16;:39::i;:::-;41106:185;;;:::o;59800:118::-;59865:4;59894:16;59902:7;59894;:16::i;:::-;59887:23;;59800:118;;;:::o;33185:775::-;33246:23;33316:6;33312:598;33327:13;;33325:1;:15;33312:598;;;33365:31;33399:14;33411:1;33399:11;:14::i;:::-;33365:48;;33453:6;33435:24;;:9;:14;;;:24;;;33432:463;;33489:9;:16;;;33484:392;;33537:13;:24;;;;;;;;;;;;33534:319;;;33594:10;33610:1;33594:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33534:319;;;33691:14;:23;;;;;;;;;;;;33681:41;;;33731:4;33737:1;33681:58;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;33677:149;;33776:10;33792:1;33776:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33677:149;33534:319;33484:392;33432:463;33346:564;33341:3;;;;;;;33312:598;;;;33931:10;33924:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33185:775;;;:::o;60050:96::-;60101:7;60133:5;;;;;;;;;;;60126:12;;60050:96;:::o;38905:330::-;38983:7;39012:13;:24;;;;;;;;;;;;39008:177;;39066:14;:23;;;;;;;;;;;;39056:41;;;39106:4;39112:7;39056:64;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39053:121;;;39156:1;39141:17;;;;39053:121;39008:177;39202:20;39214:7;39202:11;:20::i;:::-;:25;;;39195:32;;38905:330;;;;:::o;62829:131::-;62897:10;:8;:10::i;:::-;62946:6;62920:14;:23;;;:32;;;;;;;;;;;;;;;;;;62829:131;:::o;37645:238::-;37723:7;37769:1;37752:19;;:5;:19;;;37748:73;;37793:28;;;;;;;;;;;;;;37748:73;37847:12;:19;37860:5;37847:19;;;;;;;;;;;;;;;:27;;;;;;;;;;;;37839:36;;37832:43;;37645:238;;;:::o;61863:174::-;61936:10;:8;:10::i;:::-;61986:4;61959:13;:24;;;:31;;;;;;;;;;;;;;;;;;62025:4;;62001:13;:21;;:28;;;;;;;:::i;:::-;;61863:174;;:::o;61375:480::-;61579:10;:8;:10::i;:::-;61633:13;61602;:28;;:44;;;;61685:10;61657:13;:25;;:38;;;;61737:8;61706:13;:28;;;:39;;;;;;;;;;;;;;;;;;61787:8;61756:13;:28;;;:39;;;;;;;;;;;;;;;;;;61837:10;61806:13;:28;;;:41;;;;;;;;;;;;;;;;;;61375:480;;;;;:::o;62045:134::-;62120:10;:8;:10::i;:::-;62167:4;;62143:13;:21;;:28;;;;;;;:::i;:::-;;62045:134;;:::o;52721:138::-;52793:13;52831;:20;;52824:27;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52721:138;:::o;61095:133::-;61155:10;:8;:10::i;:::-;61205:15;61178:13;:24;;;:42;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;61095:133::o;63986:150::-;64070:7;64102:21;64114:8;64102:11;:21::i;:::-;:26;;;64095:33;;63986:150;;;:::o;62968:272::-;63050:10;:8;:10::i;:::-;63071:17;:15;:17::i;:::-;63099:12;:10;:12::i;:::-;63145:6;63136:15;;:5;;;;;;;;;;:15;;;63132:62;;63166:28;63177:6;63184:9;63166:10;:28::i;:::-;63132:62;63205:27;63215:6;63222:9;63205;:27::i;:::-;62968:272;;:::o;40061:305::-;40179:12;:10;:12::i;:::-;40167:24;;:8;:24;;;40163:67;;40213:17;;;;;;;;;;;;;;40163:67;40286:8;40241:18;:32;40260:12;:10;:12::i;:::-;40241:32;;;;;;;;;;;;;;;:42;40274:8;40241:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;40339:8;40310:48;;40325:12;:10;:12::i;:::-;40310:48;;;40349:8;40310:48;;;;;;:::i;:::-;;;;;;;;40061:305;;:::o;35502:119::-;35566:10;:8;:10::i;:::-;35608:5;35589:13;:16;;:24;;;;35502:119;:::o;63796:182::-;63876:4;63915:14;:23;;;;;;;;;;;;63905:41;;;63955:4;63961:8;63905:65;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63898:72;;63796:182;;;:::o;60944:139::-;61007:10;:8;:10::i;:::-;61057:18;61030:13;:24;;;:45;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;60944:139::o;41362:491::-;41533:13;:24;;;;;;;;;;;;41529:149;;41585:14;:23;;;;;;;;;;;;41575:41;;;41625:4;41631:7;41575:64;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41572:106;;;41665:13;;;;;;;;;;;;;;41572:106;41529:149;41691:28;41701:4;41707:2;41711:7;41691:9;:28::i;:::-;41735:48;41758:4;41764:2;41768:7;41777:5;41735:22;:48::i;:::-;41730:115;;41805:40;;;;;;;;;;;;;;41730:115;41362:491;;;;:::o;53197:421::-;53278:13;53314:16;53322:7;53314;:16::i;:::-;53309:72;;53352:29;;;;;;;;;;;;;;53309:72;53465:13;:21;;53535:25;53552:7;53535:16;:25::i;:::-;53426:183;;;;;;;;;:::i;:::-;;;;;;;;;;;;;53394:216;;53197:421;;;:::o;52867:123::-;52923:13;52961;:21;;52954:28;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52867:123;:::o;63248:211::-;63347:7;63372:28;63383:6;63390:9;63372:10;:28::i;:::-;63442:9;63418:21;63432:6;63418:13;:21::i;:::-;:33;;;;:::i;:::-;63411:40;;63248:211;;;;:::o;53000:126::-;53055:13;53093;:25;;53086:32;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53000:126;:::o;40437:183::-;40548:4;40577:18;:25;40596:5;40577:25;;;;;;;;;;;;;;;:35;40603:8;40577:35;;;;;;;;;;;;;;;;;;;;;;;;;40570:42;;40437:183;;;;:::o;64144:485::-;64223:14;64240:12;:10;:12::i;:::-;64223:29;;64290:6;64281:15;;:5;;;;;;;;;;:15;;;:172;;;;64346:6;64319:33;;:14;:23;;;;;;;;;;;;:33;;;:119;;;;;64383:14;:23;;;;;;;;;;;;64373:41;;;64423:4;64429:8;64373:65;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64319:119;64281:172;64263:358;;;64509:6;64483:32;;:22;64496:8;64483:12;:22::i;:::-;:32;;;64480:103;;64534:49;64544:22;64557:8;64544:12;:22::i;:::-;64567:6;64574:8;64534:9;:49::i;:::-;64480:103;64263:358;;;64608:13;;;;;;;;;;;;;;64263:358;64212:417;64144:485;;:::o;51874:270::-;51963:12;:10;:12::i;:::-;51954:21;;:5;;;;;;;;;;:21;;;51951:64;;51997:18;;;;;;;;;;;;;;51951:64;52053:7;52029:21;:31;52026:69;;;52082:13;;;;;;;;;;;;;;52026:69;52114:3;52106:21;;:30;52128:7;52106:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51874:270;;:::o;10805:326::-;10865:4;11122:1;11100:7;:19;;;:23;11093:30;;10805:326;;;:::o;34754:222::-;34809:14;34826:12;:10;:12::i;:::-;34809:29;;34876:5;;;;;;;;;;34866:15;;:6;:15;;;;:65;;;;;34908:14;:23;;;;;;;;;;;;34898:33;;:6;:33;;;;34866:65;34849:119;;;34950:18;;;;;;;;;;;;;;34849:119;34798:178;34754:222::o;20888:157::-;20973:4;21012:25;20997:40;;;:11;:40;;;;20990:47;;20888:157;;;:::o;42107:158::-;42173:4;42212:13;;42202:7;:23;:55;;;;;42230:11;:20;42242:7;42230:20;;;;;;;;;;;:27;;;;;;;;;;;;42229:28;42202:55;42195:62;;42107:158;;;:::o;28486:98::-;28539:7;28566:10;28559:17;;28486:98;:::o;50119:196::-;50261:2;50234:15;:24;50250:7;50234:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;50299:7;50295:2;50279:28;;50288:5;50279:28;;;;;;;;;;;;50119:196;;;:::o;45571:2305::-;45689:35;45727:20;45739:7;45727:11;:20::i;:::-;45689:58;;45758:14;45775:12;:10;:12::i;:::-;45758:29;;45800:22;45850:14;:23;;;;;;;;;;;;45840:33;;:6;:33;;;:78;;;;45900:13;:18;;;45890:28;;:6;:28;;;45840:78;:125;;;;45945:20;45957:7;45945:11;:20::i;:::-;45935:30;;:6;:30;;;45840:125;:186;;;;45982:44;45999:13;:18;;;46019:6;45982:16;:44::i;:::-;45840:186;45800:237;;46055:17;46050:79;;46094:35;;;;;;;;;;;;;;46050:79;46166:4;46144:26;;:13;:18;;;:26;;;46140:80;;46192:28;;;;;;;;;;;;;;46140:80;46249:1;46235:16;;:2;:16;;;46231:65;;46273:23;;;;;;;;;;;;;;46231:65;46525:49;46542:1;46546:7;46555:13;:18;;;46525:8;:49::i;:::-;46900:1;46870:12;:18;46883:4;46870:18;;;;;;;;;;;;;;;:26;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46944:1;46916:12;:16;46929:2;46916:16;;;;;;;;;;;;;;;:24;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46990:2;46962:11;:20;46974:7;46962:20;;;;;;;;;;;:25;;;:30;;;;;;;;;;;;;;;;;;47052:15;47007:11;:20;47019:7;47007:20;;;;;;;;;;;:35;;;:61;;;;;;;;;;;;;;;;;;47320:19;47352:1;47342:7;:11;47320:33;;47413:1;47372:43;;:11;:24;47384:11;47372:24;;;;;;;;;;;:29;;;;;;;;;;;;:43;;;47368:445;;47597:13;;47583:11;:27;47579:219;;;47667:13;:18;;;47635:11;:24;47647:11;47635:24;;;;;;;;;;;:29;;;:50;;;;;;;;;;;;;;;;;;47750:13;:28;;;47708:11;:24;47720:11;47708:24;;;;;;;;;;;:39;;;:70;;;;;;;;;;;;;;;;;;47579:219;47368:445;46845:979;47860:7;47856:2;47841:27;;47850:4;47841:27;;;;;;;;;;;;45676:2200;;;45571:2305;;;:::o;32042:1098::-;32113:21;;:::i;:::-;32152:12;32167:7;32152:22;;32223:13;;32216:4;:20;32212:861;;;32257:31;32291:11;:17;32303:4;32291:17;;;;;;;;;;;32257:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32332:9;:16;;;32327:731;;32403:1;32377:28;;:9;:14;;;:28;;;32373:101;;32441:9;32434:16;;;;;;32373:101;32778:261;32785:4;32778:261;;;32818:6;;;;;;;;32863:11;:17;32875:4;32863:17;;;;;;;;;;;32851:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32937:1;32911:28;;:9;:14;;;:28;;;32907:109;;32979:9;32972:16;;;;;;32907:109;32778:261;;;32327:731;32238:835;32212:861;33101:31;;;;;;;;;;;;;;32042:1098;;;;:::o;60154:639::-;60215:13;:28;;;;;;;;;;;;60211:54;60258:7;60211:54;60285:11;60299:13;:30;;;60285:44;;60340:10;60353:13;:28;;;60340:41;;60392:10;60405:13;:32;;;60392:45;;60459:15;60452:3;:22;;:46;;;;;60496:2;60478:15;:20;60452:46;60448:338;;;60542:18;60515:13;:24;;;:45;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;60448:338;;;60588:15;60582:2;:21;;:58;;;;;60626:2;60608:15;:20;:31;;;;60637:2;60632:1;:7;60608:31;60582:58;60578:208;;;60684:15;60657:13;:24;;;:42;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;60578:208;;;60759:15;60732:13;:24;;;:42;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;60578:208;60448:338;60200:593;;;60154:639;:::o;34095:153::-;34174:13;:24;;;;;;;;;;;;34155:43;;;;;;;;:::i;:::-;;:15;:43;;;;;;;;:::i;:::-;;;34152:88;;34220:20;;;;;;;;;;;;;;34152:88;34095:153::o;63467:321::-;63559:78;63574:9;63584:21;63598:6;63584:13;:21::i;:::-;63606:30;63629:6;63606:22;:30::i;:::-;63559:14;:78::i;:::-;63555:125;;63659:21;;;;;;;;;;;;;;63555:125;63709:14;:12;:14::i;:::-;63705:61;;63745:21;;;;;;;;;;;;;;63705:61;63467:321;;:::o;42273:104::-;42342:27;42352:2;42356:8;42342:27;;;;;;;;;;;;:9;:27::i;:::-;42273:104;;:::o;50880:788::-;51034:4;51055:15;:2;:13;;;:15::i;:::-;51051:610;;;51107:2;51091:36;;;51128:12;:10;:12::i;:::-;51142:4;51148:7;51157:5;51091:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;51087:519;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51353:1;51336:6;:13;:18;51332:259;;51386:40;;;;;;;;;;;;;;51332:259;51541:6;51535:13;51526:6;51522:2;51518:15;51511:38;51087:519;51223:45;;;51213:55;;;:6;:55;;;;51206:62;;;;;51051:610;51645:4;51638:11;;50880:788;;;;;;;:::o;4545:727::-;4600:13;4831:5;4826:1;:10;4822:53;;4853:10;;;;;;;;;;;;;;;;;;;;;4822:53;4885:12;4900:5;4885:20;;4916:14;4941:78;4953:4;4948:1;:9;4941:78;;4974:8;;;;;:::i;:::-;;;;5005:2;4997:10;;;;;:::i;:::-;;;4941:78;;;5029:19;5061:6;5051:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5029:39;;5079:154;5091:5;5086:1;:10;5079:154;;5123:1;5113:11;;;;;:::i;:::-;;;5190:2;5182:5;:10;;;;:::i;:::-;5169:2;:24;;;;:::i;:::-;5156:39;;5139:6;5146;5139:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;5219:2;5210:11;;;;;:::i;:::-;;;5079:154;;;5257:6;5243:21;;;;;4545:727;;;;:::o;37964:252::-;38034:7;38080:1;38063:19;;:5;:19;;;38059:149;;38104:27;;;;;;;;;;;;;;38059:149;38175:12;:19;38188:5;38175:19;;;;;;;;;;;;;;;:32;;;;;;;;;;;;38167:41;;38147:61;;37964:252;;;:::o;38224:270::-;38303:7;38349:1;38332:19;;:5;:19;;;38328:158;;38373:27;;;;;;;;;;;;;;38328:158;38444:12;:19;38457:5;38444:19;;;;;;;;;;;;;;;:41;;;;;;;;;;;;38436:50;;38416:70;;38224:270;;;:::o;30572:565::-;30688:4;30777:18;30749:46;;;;;;;;:::i;:::-;;:13;:24;;;;;;;;;;;;:46;;;;;;;;:::i;:::-;;;:117;;;;;30859:7;30847:9;:19;;;;:::i;:::-;30816:13;:27;;;;;;;;;;;;:50;;;;30749:117;30730:385;;;;30932:15;30904:43;;;;;;;;:::i;:::-;;:13;:24;;;;;;;;;;;;:43;;;;;;;;:::i;:::-;;;:134;;;;;31022:16;31012:7;31000:9;:19;;;;:::i;:::-;:38;;;;:::i;:::-;30968:13;:28;;;;;;;;;;;;:70;;;;30904:134;:196;;;;;31091:9;31059:13;:28;;;;;;;;;;;;:41;;;;30904:196;30730:385;30710:405;;30572:565;;;;;:::o;31145:280::-;31201:4;31243:13;:24;;;;;;;;;;;;:160;;;;31318:5;31290:33;;:13;:24;;;;;;;;;;;;:33;;;:98;;;;;31375:13;;31344;:28;;;;;;;;;;;;:44;;;31290:98;31243:160;31223:180;;31145:280;:::o;42740:163::-;42863:32;42869:2;42873:8;42883:5;42890:4;42863:5;:32::i;:::-;42740:163;;;:::o;43162:1523::-;43301:20;43324:13;;43301:36;;43352:14;:12;:14::i;:::-;43348:61;;43388:21;;;;;;;;;;;;;;43348:61;43438:1;43424:16;;:2;:16;;;43420:61;;43462:19;;;;;;;;;;;;;;43420:61;43508:1;43496:8;:13;43492:57;;43531:18;;;;;;;;;;;;;;43492:57;43861:8;43826:12;:16;43839:2;43826:16;;;;;;;;;;;;;;;:24;;;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43925:8;43885:12;:16;43898:2;43885:16;;;;;;;;;;;;;;;:29;;;:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43980:18;43952:46;;;;;;;;:::i;:::-;;:13;:24;;;;;;;;;;;;:46;;;;;;;;:::i;:::-;;;43949:166;;44106:8;44058:12;:16;44071:2;44058:16;;;;;;;;;;;;;;;:38;;;;;;;;;;;;:57;44017:12;:16;44030:2;44017:16;;;;;;;;;;;;;;;:38;;;:98;;;;;;;;;;;;;;;;;;43949:166;44165:2;44132:11;:25;44144:12;44132:25;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;44232:15;44182:11;:25;44194:12;44182:25;;;;;;;;;;;:40;;;:66;;;;;;;;;;;;;;;;;;44265:20;44288:12;44265:35;;44320:9;44315:307;44335:8;44331:1;:12;44315:307;;;44399:12;44395:2;44374:38;;44391:1;44374:38;;;;;;;;;;;;44435:4;:68;;;;;44444:59;44475:1;44479:2;44483:12;44497:5;44444:22;:59::i;:::-;44443:60;44435:68;44431:142;;;44533:40;;;;;;;;;;;;;;44431:142;44592:14;;;;;;;44345:3;;;;;;;44315:307;;;;44654:12;44638:13;:28;;;;43801:877;43290:1395;43162:1523;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:126;371:7;411:42;404:5;400:54;389:65;;334:126;;;:::o;466:96::-;503:7;532:24;550:5;532:24;:::i;:::-;521:35;;466:96;;;:::o;568:122::-;641:24;659:5;641:24;:::i;:::-;634:5;631:35;621:63;;680:1;677;670:12;621:63;568:122;:::o;696:139::-;742:5;780:6;767:20;758:29;;796:33;823:5;796:33;:::i;:::-;696:139;;;;:::o;841:329::-;900:6;949:2;937:9;928:7;924:23;920:32;917:119;;;955:79;;:::i;:::-;917:119;1075:1;1100:53;1145:7;1136:6;1125:9;1121:22;1100:53;:::i;:::-;1090:63;;1046:117;841:329;;;;:::o;1176:149::-;1212:7;1252:66;1245:5;1241:78;1230:89;;1176:149;;;:::o;1331:120::-;1403:23;1420:5;1403:23;:::i;:::-;1396:5;1393:34;1383:62;;1441:1;1438;1431:12;1383:62;1331:120;:::o;1457:137::-;1502:5;1540:6;1527:20;1518:29;;1556:32;1582:5;1556:32;:::i;:::-;1457:137;;;;:::o;1600:327::-;1658:6;1707:2;1695:9;1686:7;1682:23;1678:32;1675:119;;;1713:79;;:::i;:::-;1675:119;1833:1;1858:52;1902:7;1893:6;1882:9;1878:22;1858:52;:::i;:::-;1848:62;;1804:116;1600:327;;;;:::o;1933:90::-;1967:7;2010:5;2003:13;1996:21;1985:32;;1933:90;;;:::o;2029:109::-;2110:21;2125:5;2110:21;:::i;:::-;2105:3;2098:34;2029:109;;:::o;2144:210::-;2231:4;2269:2;2258:9;2254:18;2246:26;;2282:65;2344:1;2333:9;2329:17;2320:6;2282:65;:::i;:::-;2144:210;;;;:::o;2360:99::-;2412:6;2446:5;2440:12;2430:22;;2360:99;;;:::o;2465:169::-;2549:11;2583:6;2578:3;2571:19;2623:4;2618:3;2614:14;2599:29;;2465:169;;;;:::o;2640:307::-;2708:1;2718:113;2732:6;2729:1;2726:13;2718:113;;;2817:1;2812:3;2808:11;2802:18;2798:1;2793:3;2789:11;2782:39;2754:2;2751:1;2747:10;2742:15;;2718:113;;;2849:6;2846:1;2843:13;2840:101;;;2929:1;2920:6;2915:3;2911:16;2904:27;2840:101;2689:258;2640:307;;;:::o;2953:102::-;2994:6;3045:2;3041:7;3036:2;3029:5;3025:14;3021:28;3011:38;;2953:102;;;:::o;3061:364::-;3149:3;3177:39;3210:5;3177:39;:::i;:::-;3232:71;3296:6;3291:3;3232:71;:::i;:::-;3225:78;;3312:52;3357:6;3352:3;3345:4;3338:5;3334:16;3312:52;:::i;:::-;3389:29;3411:6;3389:29;:::i;:::-;3384:3;3380:39;3373:46;;3153:272;3061:364;;;;:::o;3431:313::-;3544:4;3582:2;3571:9;3567:18;3559:26;;3631:9;3625:4;3621:20;3617:1;3606:9;3602:17;3595:47;3659:78;3732:4;3723:6;3659:78;:::i;:::-;3651:86;;3431:313;;;;:::o;3750:77::-;3787:7;3816:5;3805:16;;3750:77;;;:::o;3833:122::-;3906:24;3924:5;3906:24;:::i;:::-;3899:5;3896:35;3886:63;;3945:1;3942;3935:12;3886:63;3833:122;:::o;3961:139::-;4007:5;4045:6;4032:20;4023:29;;4061:33;4088:5;4061:33;:::i;:::-;3961:139;;;;:::o;4106:329::-;4165:6;4214:2;4202:9;4193:7;4189:23;4185:32;4182:119;;;4220:79;;:::i;:::-;4182:119;4340:1;4365:53;4410:7;4401:6;4390:9;4386:22;4365:53;:::i;:::-;4355:63;;4311:117;4106:329;;;;:::o;4441:118::-;4528:24;4546:5;4528:24;:::i;:::-;4523:3;4516:37;4441:118;;:::o;4565:222::-;4658:4;4696:2;4685:9;4681:18;4673:26;;4709:71;4777:1;4766:9;4762:17;4753:6;4709:71;:::i;:::-;4565:222;;;;:::o;4793:474::-;4861:6;4869;4918:2;4906:9;4897:7;4893:23;4889:32;4886:119;;;4924:79;;:::i;:::-;4886:119;5044:1;5069:53;5114:7;5105:6;5094:9;5090:22;5069:53;:::i;:::-;5059:63;;5015:117;5171:2;5197:53;5242:7;5233:6;5222:9;5218:22;5197:53;:::i;:::-;5187:63;;5142:118;4793:474;;;;;:::o;5273:118::-;5360:24;5378:5;5360:24;:::i;:::-;5355:3;5348:37;5273:118;;:::o;5397:222::-;5490:4;5528:2;5517:9;5513:18;5505:26;;5541:71;5609:1;5598:9;5594:17;5585:6;5541:71;:::i;:::-;5397:222;;;;:::o;5625:619::-;5702:6;5710;5718;5767:2;5755:9;5746:7;5742:23;5738:32;5735:119;;;5773:79;;:::i;:::-;5735:119;5893:1;5918:53;5963:7;5954:6;5943:9;5939:22;5918:53;:::i;:::-;5908:63;;5864:117;6020:2;6046:53;6091:7;6082:6;6071:9;6067:22;6046:53;:::i;:::-;6036:63;;5991:118;6148:2;6174:53;6219:7;6210:6;6199:9;6195:22;6174:53;:::i;:::-;6164:63;;6119:118;5625:619;;;;;:::o;6250:86::-;6285:7;6325:4;6318:5;6314:16;6303:27;;6250:86;;;:::o;6342:112::-;6425:22;6441:5;6425:22;:::i;:::-;6420:3;6413:35;6342:112;;:::o;6460:214::-;6549:4;6587:2;6576:9;6572:18;6564:26;;6600:67;6664:1;6653:9;6649:17;6640:6;6600:67;:::i;:::-;6460:214;;;;:::o;6680:116::-;6750:21;6765:5;6750:21;:::i;:::-;6743:5;6740:32;6730:60;;6786:1;6783;6776:12;6730:60;6680:116;:::o;6802:133::-;6845:5;6883:6;6870:20;6861:29;;6899:30;6923:5;6899:30;:::i;:::-;6802:133;;;;:::o;6941:323::-;6997:6;7046:2;7034:9;7025:7;7021:23;7017:32;7014:119;;;7052:79;;:::i;:::-;7014:119;7172:1;7197:50;7239:7;7230:6;7219:9;7215:22;7197:50;:::i;:::-;7187:60;;7143:114;6941:323;;;;:::o;7270:114::-;7337:6;7371:5;7365:12;7355:22;;7270:114;;;:::o;7390:184::-;7489:11;7523:6;7518:3;7511:19;7563:4;7558:3;7554:14;7539:29;;7390:184;;;;:::o;7580:132::-;7647:4;7670:3;7662:11;;7700:4;7695:3;7691:14;7683:22;;7580:132;;;:::o;7718:108::-;7795:24;7813:5;7795:24;:::i;:::-;7790:3;7783:37;7718:108;;:::o;7832:179::-;7901:10;7922:46;7964:3;7956:6;7922:46;:::i;:::-;8000:4;7995:3;7991:14;7977:28;;7832:179;;;;:::o;8017:113::-;8087:4;8119;8114:3;8110:14;8102:22;;8017:113;;;:::o;8166:732::-;8285:3;8314:54;8362:5;8314:54;:::i;:::-;8384:86;8463:6;8458:3;8384:86;:::i;:::-;8377:93;;8494:56;8544:5;8494:56;:::i;:::-;8573:7;8604:1;8589:284;8614:6;8611:1;8608:13;8589:284;;;8690:6;8684:13;8717:63;8776:3;8761:13;8717:63;:::i;:::-;8710:70;;8803:60;8856:6;8803:60;:::i;:::-;8793:70;;8649:224;8636:1;8633;8629:9;8624:14;;8589:284;;;8593:14;8889:3;8882:10;;8290:608;;;8166:732;;;;:::o;8904:373::-;9047:4;9085:2;9074:9;9070:18;9062:26;;9134:9;9128:4;9124:20;9120:1;9109:9;9105:17;9098:47;9162:108;9265:4;9256:6;9162:108;:::i;:::-;9154:116;;8904:373;;;;:::o;9283:117::-;9392:1;9389;9382:12;9406:117;9515:1;9512;9505:12;9529:117;9638:1;9635;9628:12;9666:553;9724:8;9734:6;9784:3;9777:4;9769:6;9765:17;9761:27;9751:122;;9792:79;;:::i;:::-;9751:122;9905:6;9892:20;9882:30;;9935:18;9927:6;9924:30;9921:117;;;9957:79;;:::i;:::-;9921:117;10071:4;10063:6;10059:17;10047:29;;10125:3;10117:4;10109:6;10105:17;10095:8;10091:32;10088:41;10085:128;;;10132:79;;:::i;:::-;10085:128;9666:553;;;;;:::o;10225:529::-;10296:6;10304;10353:2;10341:9;10332:7;10328:23;10324:32;10321:119;;;10359:79;;:::i;:::-;10321:119;10507:1;10496:9;10492:17;10479:31;10537:18;10529:6;10526:30;10523:117;;;10559:79;;:::i;:::-;10523:117;10672:65;10729:7;10720:6;10709:9;10705:22;10672:65;:::i;:::-;10654:83;;;;10450:297;10225:529;;;;;:::o;10760:118::-;10831:22;10847:5;10831:22;:::i;:::-;10824:5;10821:33;10811:61;;10868:1;10865;10858:12;10811:61;10760:118;:::o;10884:135::-;10928:5;10966:6;10953:20;10944:29;;10982:31;11007:5;10982:31;:::i;:::-;10884:135;;;;:::o;11025:101::-;11061:7;11101:18;11094:5;11090:30;11079:41;;11025:101;;;:::o;11132:120::-;11204:23;11221:5;11204:23;:::i;:::-;11197:5;11194:34;11184:62;;11242:1;11239;11232:12;11184:62;11132:120;:::o;11258:137::-;11303:5;11341:6;11328:20;11319:29;;11357:32;11383:5;11357:32;:::i;:::-;11258:137;;;;:::o;11401:901::-;11491:6;11499;11507;11515;11523;11572:3;11560:9;11551:7;11547:23;11543:33;11540:120;;;11579:79;;:::i;:::-;11540:120;11699:1;11724:53;11769:7;11760:6;11749:9;11745:22;11724:53;:::i;:::-;11714:63;;11670:117;11826:2;11852:53;11897:7;11888:6;11877:9;11873:22;11852:53;:::i;:::-;11842:63;;11797:118;11954:2;11980:51;12023:7;12014:6;12003:9;11999:22;11980:51;:::i;:::-;11970:61;;11925:116;12080:2;12106:51;12149:7;12140:6;12129:9;12125:22;12106:51;:::i;:::-;12096:61;;12051:116;12206:3;12233:52;12277:7;12268:6;12257:9;12253:22;12233:52;:::i;:::-;12223:62;;12177:118;11401:901;;;;;;;;:::o;12308:468::-;12373:6;12381;12430:2;12418:9;12409:7;12405:23;12401:32;12398:119;;;12436:79;;:::i;:::-;12398:119;12556:1;12581:53;12626:7;12617:6;12606:9;12602:22;12581:53;:::i;:::-;12571:63;;12527:117;12683:2;12709:50;12751:7;12742:6;12731:9;12727:22;12709:50;:::i;:::-;12699:60;;12654:115;12308:468;;;;;:::o;12782:77::-;12819:7;12848:5;12837:16;;12782:77;;;:::o;12865:122::-;12938:24;12956:5;12938:24;:::i;:::-;12931:5;12928:35;12918:63;;12977:1;12974;12967:12;12918:63;12865:122;:::o;12993:139::-;13039:5;13077:6;13064:20;13055:29;;13093:33;13120:5;13093:33;:::i;:::-;12993:139;;;;:::o;13138:329::-;13197:6;13246:2;13234:9;13225:7;13221:23;13217:32;13214:119;;;13252:79;;:::i;:::-;13214:119;13372:1;13397:53;13442:7;13433:6;13422:9;13418:22;13397:53;:::i;:::-;13387:63;;13343:117;13138:329;;;;:::o;13473:117::-;13582:1;13579;13572:12;13596:180;13644:77;13641:1;13634:88;13741:4;13738:1;13731:15;13765:4;13762:1;13755:15;13782:281;13865:27;13887:4;13865:27;:::i;:::-;13857:6;13853:40;13995:6;13983:10;13980:22;13959:18;13947:10;13944:34;13941:62;13938:88;;;14006:18;;:::i;:::-;13938:88;14046:10;14042:2;14035:22;13825:238;13782:281;;:::o;14069:129::-;14103:6;14130:20;;:::i;:::-;14120:30;;14159:33;14187:4;14179:6;14159:33;:::i;:::-;14069:129;;;:::o;14204:307::-;14265:4;14355:18;14347:6;14344:30;14341:56;;;14377:18;;:::i;:::-;14341:56;14415:29;14437:6;14415:29;:::i;:::-;14407:37;;14499:4;14493;14489:15;14481:23;;14204:307;;;:::o;14517:154::-;14601:6;14596:3;14591;14578:30;14663:1;14654:6;14649:3;14645:16;14638:27;14517:154;;;:::o;14677:410::-;14754:5;14779:65;14795:48;14836:6;14795:48;:::i;:::-;14779:65;:::i;:::-;14770:74;;14867:6;14860:5;14853:21;14905:4;14898:5;14894:16;14943:3;14934:6;14929:3;14925:16;14922:25;14919:112;;;14950:79;;:::i;:::-;14919:112;15040:41;15074:6;15069:3;15064;15040:41;:::i;:::-;14760:327;14677:410;;;;;:::o;15106:338::-;15161:5;15210:3;15203:4;15195:6;15191:17;15187:27;15177:122;;15218:79;;:::i;:::-;15177:122;15335:6;15322:20;15360:78;15434:3;15426:6;15419:4;15411:6;15407:17;15360:78;:::i;:::-;15351:87;;15167:277;15106:338;;;;:::o;15450:943::-;15545:6;15553;15561;15569;15618:3;15606:9;15597:7;15593:23;15589:33;15586:120;;;15625:79;;:::i;:::-;15586:120;15745:1;15770:53;15815:7;15806:6;15795:9;15791:22;15770:53;:::i;:::-;15760:63;;15716:117;15872:2;15898:53;15943:7;15934:6;15923:9;15919:22;15898:53;:::i;:::-;15888:63;;15843:118;16000:2;16026:53;16071:7;16062:6;16051:9;16047:22;16026:53;:::i;:::-;16016:63;;15971:118;16156:2;16145:9;16141:18;16128:32;16187:18;16179:6;16176:30;16173:117;;;16209:79;;:::i;:::-;16173:117;16314:62;16368:7;16359:6;16348:9;16344:22;16314:62;:::i;:::-;16304:72;;16099:287;15450:943;;;;;;;:::o;16399:474::-;16467:6;16475;16524:2;16512:9;16503:7;16499:23;16495:32;16492:119;;;16530:79;;:::i;:::-;16492:119;16650:1;16675:53;16720:7;16711:6;16700:9;16696:22;16675:53;:::i;:::-;16665:63;;16621:117;16777:2;16803:53;16848:7;16839:6;16828:9;16824:22;16803:53;:::i;:::-;16793:63;;16748:118;16399:474;;;;;:::o;16879:::-;16947:6;16955;17004:2;16992:9;16983:7;16979:23;16975:32;16972:119;;;17010:79;;:::i;:::-;16972:119;17130:1;17155:53;17200:7;17191:6;17180:9;17176:22;17155:53;:::i;:::-;17145:63;;17101:117;17257:2;17283:53;17328:7;17319:6;17308:9;17304:22;17283:53;:::i;:::-;17273:63;;17228:118;16879:474;;;;;:::o;17359:180::-;17407:77;17404:1;17397:88;17504:4;17501:1;17494:15;17528:4;17525:1;17518:15;17545:320;17589:6;17626:1;17620:4;17616:12;17606:22;;17673:1;17667:4;17663:12;17694:18;17684:81;;17750:4;17742:6;17738:17;17728:27;;17684:81;17812:2;17804:6;17801:14;17781:18;17778:38;17775:84;;17831:18;;:::i;:::-;17775:84;17596:269;17545:320;;;:::o;17871:332::-;17992:4;18030:2;18019:9;18015:18;18007:26;;18043:71;18111:1;18100:9;18096:17;18087:6;18043:71;:::i;:::-;18124:72;18192:2;18181:9;18177:18;18168:6;18124:72;:::i;:::-;17871:332;;;;;:::o;18209:137::-;18263:5;18294:6;18288:13;18279:22;;18310:30;18334:5;18310:30;:::i;:::-;18209:137;;;;:::o;18352:345::-;18419:6;18468:2;18456:9;18447:7;18443:23;18439:32;18436:119;;;18474:79;;:::i;:::-;18436:119;18594:1;18619:61;18672:7;18663:6;18652:9;18648:22;18619:61;:::i;:::-;18609:71;;18565:125;18352:345;;;;:::o;18703:180::-;18751:77;18748:1;18741:88;18848:4;18845:1;18838:15;18872:4;18869:1;18862:15;18889:148;18991:11;19028:3;19013:18;;18889:148;;;;:::o;19043:141::-;19092:4;19115:3;19107:11;;19138:3;19135:1;19128:14;19172:4;19169:1;19159:18;19151:26;;19043:141;;;:::o;19214:845::-;19317:3;19354:5;19348:12;19383:36;19409:9;19383:36;:::i;:::-;19435:89;19517:6;19512:3;19435:89;:::i;:::-;19428:96;;19555:1;19544:9;19540:17;19571:1;19566:137;;;;19717:1;19712:341;;;;19533:520;;19566:137;19650:4;19646:9;19635;19631:25;19626:3;19619:38;19686:6;19681:3;19677:16;19670:23;;19566:137;;19712:341;19779:38;19811:5;19779:38;:::i;:::-;19839:1;19853:154;19867:6;19864:1;19861:13;19853:154;;;19941:7;19935:14;19931:1;19926:3;19922:11;19915:35;19991:1;19982:7;19978:15;19967:26;;19889:4;19886:1;19882:12;19877:17;;19853:154;;;20036:6;20031:3;20027:16;20020:23;;19719:334;;19533:520;;19321:738;;19214:845;;;;:::o;20065:151::-;20205:3;20201:1;20193:6;20189:14;20182:27;20065:151;:::o;20222:400::-;20382:3;20403:84;20485:1;20480:3;20403:84;:::i;:::-;20396:91;;20496:93;20585:3;20496:93;:::i;:::-;20614:1;20609:3;20605:11;20598:18;;20222:400;;;:::o;20628:377::-;20734:3;20762:39;20795:5;20762:39;:::i;:::-;20817:89;20899:6;20894:3;20817:89;:::i;:::-;20810:96;;20915:52;20960:6;20955:3;20948:4;20941:5;20937:16;20915:52;:::i;:::-;20992:6;20987:3;20983:16;20976:23;;20738:267;20628:377;;;;:::o;21011:155::-;21151:7;21147:1;21139:6;21135:14;21128:31;21011:155;:::o;21172:400::-;21332:3;21353:84;21435:1;21430:3;21353:84;:::i;:::-;21346:91;;21446:93;21535:3;21446:93;:::i;:::-;21564:1;21559:3;21555:11;21548:18;;21172:400;;;:::o;21578:961::-;21957:3;21979:92;22067:3;22058:6;21979:92;:::i;:::-;21972:99;;22088:148;22232:3;22088:148;:::i;:::-;22081:155;;22253:95;22344:3;22335:6;22253:95;:::i;:::-;22246:102;;22365:148;22509:3;22365:148;:::i;:::-;22358:155;;22530:3;22523:10;;21578:961;;;;;:::o;22545:180::-;22593:77;22590:1;22583:88;22690:4;22687:1;22680:15;22714:4;22711:1;22704:15;22731:305;22771:3;22790:20;22808:1;22790:20;:::i;:::-;22785:25;;22824:20;22842:1;22824:20;:::i;:::-;22819:25;;22978:1;22910:66;22906:74;22903:1;22900:81;22897:107;;;22984:18;;:::i;:::-;22897:107;23028:1;23025;23021:9;23014:16;;22731:305;;;;:::o;23042:98::-;23093:6;23127:5;23121:12;23111:22;;23042:98;;;:::o;23146:168::-;23229:11;23263:6;23258:3;23251:19;23303:4;23298:3;23294:14;23279:29;;23146:168;;;;:::o;23320:360::-;23406:3;23434:38;23466:5;23434:38;:::i;:::-;23488:70;23551:6;23546:3;23488:70;:::i;:::-;23481:77;;23567:52;23612:6;23607:3;23600:4;23593:5;23589:16;23567:52;:::i;:::-;23644:29;23666:6;23644:29;:::i;:::-;23639:3;23635:39;23628:46;;23410:270;23320:360;;;;:::o;23686:640::-;23881:4;23919:3;23908:9;23904:19;23896:27;;23933:71;24001:1;23990:9;23986:17;23977:6;23933:71;:::i;:::-;24014:72;24082:2;24071:9;24067:18;24058:6;24014:72;:::i;:::-;24096;24164:2;24153:9;24149:18;24140:6;24096:72;:::i;:::-;24215:9;24209:4;24205:20;24200:2;24189:9;24185:18;24178:48;24243:76;24314:4;24305:6;24243:76;:::i;:::-;24235:84;;23686:640;;;;;;;:::o;24332:141::-;24388:5;24419:6;24413:13;24404:22;;24435:32;24461:5;24435:32;:::i;:::-;24332:141;;;;:::o;24479:349::-;24548:6;24597:2;24585:9;24576:7;24572:23;24568:32;24565:119;;;24603:79;;:::i;:::-;24565:119;24723:1;24748:63;24803:7;24794:6;24783:9;24779:22;24748:63;:::i;:::-;24738:73;;24694:127;24479:349;;;;:::o;24834:233::-;24873:3;24896:24;24914:5;24896:24;:::i;:::-;24887:33;;24942:66;24935:5;24932:77;24929:103;;25012:18;;:::i;:::-;24929:103;25059:1;25052:5;25048:13;25041:20;;24834:233;;;:::o;25073:180::-;25121:77;25118:1;25111:88;25218:4;25215:1;25208:15;25242:4;25239:1;25232:15;25259:185;25299:1;25316:20;25334:1;25316:20;:::i;:::-;25311:25;;25350:20;25368:1;25350:20;:::i;:::-;25345:25;;25389:1;25379:35;;25394:18;;:::i;:::-;25379:35;25436:1;25433;25429:9;25424:14;;25259:185;;;;:::o;25450:191::-;25490:4;25510:20;25528:1;25510:20;:::i;:::-;25505:25;;25544:20;25562:1;25544:20;:::i;:::-;25539:25;;25583:1;25580;25577:8;25574:34;;;25588:18;;:::i;:::-;25574:34;25633:1;25630;25626:9;25618:17;;25450:191;;;;:::o;25647:176::-;25679:1;25696:20;25714:1;25696:20;:::i;:::-;25691:25;;25730:20;25748:1;25730:20;:::i;:::-;25725:25;;25769:1;25759:35;;25774:18;;:::i;:::-;25759:35;25815:1;25812;25808:9;25803:14;;25647:176;;;;:::o;25829:180::-;25877:77;25874:1;25867:88;25974:4;25971:1;25964:15;25998:4;25995:1;25988:15

Swarm Source

ipfs://341afd50eae57b9ccf93ed6bfdf3557e52a96465130c446f7cf2d4842705a497
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.