ETH Price: $3,352.72 (-1.07%)

Token

Pixelated Heroes (PH)
 

Overview

Max Total Supply

1,280 PH

Holders

162

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 PH
0x8fabeBF75d01627Ba72F774A755347EFBE18a2B1
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
CollectionCore

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-07-06
*/

// File: VaultCoreInterface.sol



pragma solidity 0.8.9;

abstract contract VaultCoreInterface {
    function getVersion() public pure virtual returns (uint);
    function typeOfContract() public pure virtual returns (bytes32);
    function approveToken(
        uint256 _tokenId,
        address _tokenContractAddress) external virtual;
}
// File: RoyaltyRegistryInterface.sol



pragma solidity 0.8.9;


/**
 * Interface to the RoyaltyRegistry responsible for looking payout addresses
 */
abstract contract RoyaltyRegistryInterface {
    function getAddress(address custodial) external view virtual returns (address);
    function getMediaCustomPercentage(uint256 mediaId, address tokenAddress) external view virtual returns(uint16);
    function getExternalTokenPercentage(uint256 tokenId, address tokenAddress) external view virtual returns(uint16, uint16);
    function typeOfContract() virtual public pure returns (string calldata);
    function VERSION() virtual public pure returns (uint8);
}
// File: ApprovedCreatorRegistryInterface.sol



pragma solidity 0.8.9;


/**
 * Interface to the digital media store external contract that is
 * responsible for storing the common digital media and collection data.
 * This allows for new token contracts to be deployed and continue to reference
 * the digital media and collection data.
 */
abstract contract ApprovedCreatorRegistryInterface {

    function getVersion() virtual public pure returns (uint);
    function typeOfContract() virtual public pure returns (string calldata);
    function isOperatorApprovedForCustodialAccount(
        address _operator,
        address _custodialAddress) virtual public view returns (bool);

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


// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    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 (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed 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] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

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


// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;


/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

// 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: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: OBOControl.sol



pragma solidity 0.8.9;



contract OBOControl is Ownable {
    address public oboAdmin;
    uint256 constant public newAddressWaitPeriod = 1 days;
    bool public canAddOBOImmediately = true;

    // List of approved on behalf of users.
    mapping (address => uint256) public approvedOBOs;

    event NewOBOAddressEvent(
        address OBOAddress,
        bool action);

    event NewOBOAdminAddressEvent(
        address oboAdminAddress);

    modifier onlyOBOAdmin() {
        require(owner() == _msgSender() || oboAdmin == _msgSender(), "not oboAdmin");
        _;
    }

    function setOBOAdmin(address _oboAdmin) external onlyOwner {
        oboAdmin = _oboAdmin;
        emit NewOBOAdminAddressEvent(_oboAdmin);
    }

    /**
     * Add a new approvedOBO address. The address can be used after wait period.
     */
    function addApprovedOBO(address _oboAddress) external onlyOBOAdmin {
        require(_oboAddress != address(0), "cant set to 0x");
        require(approvedOBOs[_oboAddress] == 0, "already added");
        approvedOBOs[_oboAddress] = block.timestamp;
        emit NewOBOAddressEvent(_oboAddress, true);
    }

    /**
     * Removes an approvedOBO immediately.
     */
    function removeApprovedOBO(address _oboAddress) external onlyOBOAdmin {
        delete approvedOBOs[_oboAddress];
        emit NewOBOAddressEvent(_oboAddress, false);
    }

    /*
     * Add OBOAddress for immediate use. This is an internal only Fn that is called
     * only when the contract is deployed.
     */
    function addApprovedOBOImmediately(address _oboAddress) internal onlyOwner {
        require(_oboAddress != address(0), "addr(0)");
        // set the date to one in past so that address is active immediately.
        approvedOBOs[_oboAddress] = block.timestamp - newAddressWaitPeriod - 1;
        emit NewOBOAddressEvent(_oboAddress, true);
    }

    function addApprovedOBOAfterDeploy(address _oboAddress) external onlyOBOAdmin {
        require(canAddOBOImmediately == true, "disabled");
        addApprovedOBOImmediately(_oboAddress);
    }

    function blockImmediateOBO() external onlyOBOAdmin {
        canAddOBOImmediately = false;
    }

    /*
     * Helper function to verify is a given address is a valid approvedOBO address.
     */
    function isValidApprovedOBO(address _oboAddress) public view returns (bool) {
        uint256 createdAt = approvedOBOs[_oboAddress];
        if (createdAt == 0) {
            return false;
        }
        return block.timestamp - createdAt > newAddressWaitPeriod;
    }

    /**
    * @dev Modifier to make the obo calls only callable by approved addressess
    */
    modifier isApprovedOBO() {
        require(isValidApprovedOBO(msg.sender), "unauthorized OBO user");
        _;
    }
}
// File: @openzeppelin/contracts/security/Pausable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        _requireNotPaused();
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        _requirePaused();
        _;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

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


// OpenZeppelin Contracts (last updated v4.7.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
                /// @solidity memory-safe-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 (last updated v4.6.0) (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 `IERC721Receiver.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 (last updated v4.7.0) (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`.
     *
     * 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;

    /**
     * @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 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 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 the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @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);
}

// 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/token/ERC721/ERC721.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;








/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

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

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

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @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 virtual override returns (uint256) {
        require(owner != address(0), "ERC721: address zero is not a valid owner");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: invalid token ID");
        return owner;
    }

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        _requireMinted(tokenId);

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not token owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_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 {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");

        _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 {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");
        _safeTransfer(from, to, tokenId, data);
    }

    /**
     * @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.
     *
     * `data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);

        _afterTokenTransfer(address(0), 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 {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);

        _afterTokenTransfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * 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 virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

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

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits an {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

    /**
     * @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.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

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


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

pragma solidity ^0.8.0;



/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

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

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

// File: CollectionCore.sol



pragma solidity 0.8.9;








contract CollectionCore is ERC721Enumerable, OBOControl, Pausable {
    using ECDSA for bytes32;
    uint8 constant public VERSION = 1;
    uint16 public immutable royaltyPercentage;
    address public immutable creator;
    address public signerAddress;
    bool public enableExternalMinting;
    // by default bool's are false, save gas by not initializing
    bool public isImmutable;
    uint256 public immutable totalMediaSupply;
    string public baseURI;
    ApprovedCreatorRegistryInterface public creatorRegistryStore;

    struct ExternalCreateRequest {
        address owner;
        bytes signature;
        uint256 tokenId;
    }

    struct OBOCreateRequest {
        address owner;
        uint256 tokenId;
    }

    struct ChainSignatureRequest {
        uint256 onchainId;
        address owner;
        address thisContract;
    }

    event NewSignerEvent(
        address signer);

    constructor(string memory _tokenName, string memory _tokenSymbol,
            address _crsAddress, uint256 _totalSupply,
            address _creator, uint16 _royaltyPercentage, string memory _initialBaseURI) ERC721(_tokenName, _tokenSymbol) {
        require(_royaltyPercentage > 0 && _royaltyPercentage <= 10000, "invalid royalty");
        require(_creator != address(0), "creator = 0x0");
        setCreatorRegistryStore(_crsAddress);
        require(_totalSupply > 0, "supply > 0");
        totalMediaSupply = _totalSupply;
        creator = _creator;
        royaltyPercentage = _royaltyPercentage;
        baseURI = _initialBaseURI;
    }

    /*
     * Set signer address on the token contract. Setting signer means we are opening
     * the token contract for external accounts to create tokens. Call this to change
     * the signer immediately.
     */
    function setSignerAddress(address _signerAddress, bool _enableExternalMinting) external
            whenNotPaused isApprovedOBO {
        require(_signerAddress != address(0), "cant be zero");
        signerAddress = _signerAddress;
        enableExternalMinting = _enableExternalMinting;
        emit NewSignerEvent(signerAddress);
    }

    // Set the creator registry address upon construction. Immutable.
    function setCreatorRegistryStore(address _crsAddress) internal {
        require(_crsAddress != address(0), "registry = 0x0");
        ApprovedCreatorRegistryInterface candidateCreatorRegistryStore = ApprovedCreatorRegistryInterface(_crsAddress);
        // require(candidateCreatorRegistryStore.getVersion() == 1, "registry store is not version 1");
        // Simple check to make sure we are adding the registry contract indeed
        // https://fravoll.github.io/solidity-patterns/string_equality_comparison.html
        bytes32 contractType = keccak256(abi.encodePacked(candidateCreatorRegistryStore.typeOfContract()));
        // keccak256(abi.encodePacked("approvedCreatorRegistryReadOnly")) = 0x9732b26dfb8751e6f1f71e8f21b28a237cfe383953dce7db3dfa1777abdb2791
        require(contractType == 0x9732b26dfb8751e6f1f71e8f21b28a237cfe383953dce7db3dfa1777abdb2791,
            "not crtrReadOnlyRegistry");
        creatorRegistryStore = candidateCreatorRegistryStore;
    }

    function _baseURI() internal view override returns (string memory) {
        return baseURI;
    }

    /*
     * Set BaseURI for the entire collectible project. Only owner can set it to hide / reveal
     * baseURI.
     */
    function setBaseURI(string memory _newBaseURI) external onlyOwner whenNotPaused {
        require(isImmutable == false, "cant change");
        baseURI = _newBaseURI;
    }

    function makeImmutable() external onlyOwner {
        isImmutable = true;
    }

    /* External users who have been given a signature can mint token using this function 
     * This Fn works only when unpaused.
     */
    function mintTokens(ExternalCreateRequest[] calldata requests) external whenNotPaused {
        require(enableExternalMinting == true, "minting disabled");
        for (uint32 i=0; i < requests.length; i++) {
            ExternalCreateRequest memory request = requests[i];
            // If a token is burnt _exists will return 0.
            require(_exists(request.tokenId) == false, "token exists");
            require(request.owner == msg.sender, "owner error");
            require(totalSupply() + 1 <= totalMediaSupply, "exceeded supply");
            ChainSignatureRequest memory signatureRequest = ChainSignatureRequest(request.tokenId, request.owner, address(this));
            bytes32 encodedRequest = keccak256(abi.encode(signatureRequest));
            address addressWhoSigned = encodedRequest.recover(request.signature);
            require(addressWhoSigned == signerAddress, "sig error");
            _safeMint(msg.sender, request.tokenId);
        }
    }

    function oboMintTokens(OBOCreateRequest[] calldata requests) external isApprovedOBO {
        for (uint32 i=0; i < requests.length; i++) {
            OBOCreateRequest memory request = requests[i];
            require(_exists(request.tokenId) == false, "token exists");
            require(totalSupply() + 1 <= totalMediaSupply, "exceeded supply");
            _safeMint(request.owner, request.tokenId);
        }
    }

    /**
     * Override the isApprovalForAll to check for a special oboApproval list.  Reason for this
     * is that we can can easily remove obo operators if they every become compromised.
     */
    function isApprovedForAll(address _owner, address _operator) public view override registryInitialized returns (bool) {
        if (creatorRegistryStore.isOperatorApprovedForCustodialAccount(_operator, _owner) == true) {
            return true;
        } else {
            return super.isApprovedForAll(_owner, _operator);
        }
    }

         /**
     * Validates that the Registered store is initialized.
     */
    modifier registryInitialized() {
        require(address(creatorRegistryStore) != address(0), "registry = 0x0");
        _;
    }

    function royaltyInfo(uint256, uint256 _salePrice) external view returns (
            address _creator, uint256 _payout) {
        return (creator, (_salePrice * royaltyPercentage / 10000));
    }

    function pause() external onlyOwner {
        _pause();
    }

    function unpause() external onlyOwner {
        _unpause();
    }

    // TODO: Other collectible project dont expose burn.
    // function burn(uint256 _tokenId) external {
    //     require(_isApprovedOrOwner(msg.sender, _tokenId), "ERC721: burn caller is not owner nor approved");
    //     _burn(_tokenId);
    // }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_tokenName","type":"string"},{"internalType":"string","name":"_tokenSymbol","type":"string"},{"internalType":"address","name":"_crsAddress","type":"address"},{"internalType":"uint256","name":"_totalSupply","type":"uint256"},{"internalType":"address","name":"_creator","type":"address"},{"internalType":"uint16","name":"_royaltyPercentage","type":"uint16"},{"internalType":"string","name":"_initialBaseURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"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":false,"internalType":"address","name":"OBOAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"action","type":"bool"}],"name":"NewOBOAddressEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oboAdminAddress","type":"address"}],"name":"NewOBOAdminAddressEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"NewSignerEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oboAddress","type":"address"}],"name":"addApprovedOBO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oboAddress","type":"address"}],"name":"addApprovedOBOAfterDeploy","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":"","type":"address"}],"name":"approvedOBOs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blockImmediateOBO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"canAddOBOImmediately","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creatorRegistryStore","outputs":[{"internalType":"contract ApprovedCreatorRegistryInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableExternalMinting","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":[{"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":[],"name":"isImmutable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oboAddress","type":"address"}],"name":"isValidApprovedOBO","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"makeImmutable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"internalType":"struct CollectionCore.ExternalCreateRequest[]","name":"requests","type":"tuple[]"}],"name":"mintTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newAddressWaitPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oboAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"internalType":"struct CollectionCore.OBOCreateRequest[]","name":"requests","type":"tuple[]"}],"name":"oboMintTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oboAddress","type":"address"}],"name":"removeApprovedOBO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"_creator","type":"address"},{"internalType":"uint256","name":"_payout","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyPercentage","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","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":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oboAdmin","type":"address"}],"name":"setOBOAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signerAddress","type":"address"},{"internalType":"bool","name":"_enableExternalMinting","type":"bool"}],"name":"setSignerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMediaSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60e0604052600b805460ff60a01b1916600160a01b1790553480156200002457600080fd5b506040516200371638038062003716833981016040819052620000479162000548565b86518790879062000060906000906020850190620003ab565b50805162000076906001906020840190620003ab565b505050620000936200008d620001ca60201b60201c565b620001ce565b600d805460ff1916905561ffff821615801590620000b757506127108261ffff1611155b620000fb5760405162461bcd60e51b815260206004820152600f60248201526e696e76616c696420726f79616c747960881b60448201526064015b60405180910390fd5b6001600160a01b038316620001435760405162461bcd60e51b815260206004820152600d60248201526c063726561746f72203d2030783609c1b6044820152606401620000f2565b6200014e8562000220565b600084116200018d5760405162461bcd60e51b815260206004820152600a6024820152690737570706c79203e20360b41b6044820152606401620000f2565b60c08490526001600160a01b03831660a05261ffff82166080528051620001bc90600e906020840190620003ab565b5050505050505050620006bf565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b038116620002695760405162461bcd60e51b815260206004820152600e60248201526d07265676973747279203d203078360941b6044820152606401620000f2565b60008190506000816001600160a01b031663c20a03826040518163ffffffff1660e01b815260040160006040518083038186803b158015620002aa57600080fd5b505afa158015620002bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620002e9919081019062000624565b604051602001620002fb919062000664565b604051602081830303815290604052805190602001209050807f9732b26dfb8751e6f1f71e8f21b28a237cfe383953dce7db3dfa1777abdb279160001b14620003875760405162461bcd60e51b815260206004820152601860248201527f6e6f742063727472526561644f6e6c79526567697374727900000000000000006044820152606401620000f2565b50600f80546001600160a01b0319166001600160a01b039290921691909117905550565b828054620003b99062000682565b90600052602060002090601f016020900481019282620003dd576000855562000428565b82601f10620003f857805160ff191683800117855562000428565b8280016001018555821562000428579182015b82811115620004285782518255916020019190600101906200040b565b50620004369291506200043a565b5090565b5b808211156200043657600081556001016200043b565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004845781810151838201526020016200046a565b8381111562000494576000848401525b50505050565b600082601f830112620004ac57600080fd5b81516001600160401b0380821115620004c957620004c962000451565b604051601f8301601f19908116603f01168101908282118183101715620004f457620004f462000451565b816040528381528660208588010111156200050e57600080fd5b6200052184602083016020890162000467565b9695505050505050565b80516001600160a01b03811681146200054357600080fd5b919050565b600080600080600080600060e0888a0312156200056457600080fd5b87516001600160401b03808211156200057c57600080fd5b6200058a8b838c016200049a565b985060208a0151915080821115620005a157600080fd5b620005af8b838c016200049a565b9750620005bf60408b016200052b565b965060608a01519550620005d660808b016200052b565b945060a08a0151915061ffff82168214620005f057600080fd5b60c08a0151919350808211156200060657600080fd5b50620006158a828b016200049a565b91505092959891949750929550565b6000602082840312156200063757600080fd5b81516001600160401b038111156200064e57600080fd5b6200065c848285016200049a565b949350505050565b600082516200067881846020870162000467565b9190910192915050565b600181811c908216806200069757607f821691505b60208210811415620006b957634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05161300b6200070b60003960008181610415015281816109b601526114e90152600081816102c70152610b560152600081816104f90152610b80015261300b6000f3fe608060405234801561001057600080fd5b50600436106102955760003560e01c806370a0823111610167578063b39ba60a116100ce578063d5edf45b11610087578063d5edf45b146105fb578063d7dd397d1461060f578063e985e9c514610622578063f2fde38b14610635578063fb12a87614610648578063ffa1ad741461065b57600080fd5b8063b39ba60a14610588578063b88d4fde1461059b578063bb0aa8ef146105ae578063c87b56dd146105c2578063c95ab462146105d5578063cd161d2e146105e857600080fd5b80638ce87646116101205780638ce876461461052e5780638da5cb5b1461054157806395d89b4114610552578063a22cb4651461055a578063a47a2e771461056d578063a790c0e21461058057600080fd5b806370a08231146104b6578063715018a6146104c95780637ff9f614146104d15780638456cb59146104e4578063875d364e146104ec5780638a71bb2d146104f457600080fd5b80632a55205a1161020b5780634f6ccce7116101c45780634f6ccce71461045257806355f804b3146104655780635b7633d0146104785780635c975abb146104905780636352211e1461049b5780636c0360eb146104ae57600080fd5b80632a55205a146103b85780632f745c59146103ea5780633ad0288e146103fd5780633ef110f1146104105780633f4ba83a1461043757806342842e0e1461043f57600080fd5b80630c9999291161025d5780630c9999291461033e57806313e2263e1461035657806318160ddd1461036a5780631ad32562146103725780631dd8354c1461039257806323b872dd146103a557600080fd5b806301ffc9a71461029a57806302d05d3f146102c257806306fdde0314610301578063081812fc14610316578063095ea7b314610329575b600080fd5b6102ad6102a836600461280a565b610675565b60405190151581526020015b60405180910390f35b6102e97f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016102b9565b6103096106a0565b6040516102b9919061287f565b6102e9610324366004612892565b610732565b61033c6103373660046128c7565b610759565b005b6103486201518081565b6040519081526020016102b9565b600d546102ad90600160a81b900460ff1681565b600854610348565b6103486103803660046128f1565b600c6020526000908152604090205481565b61033c6103a036600461290c565b610874565b61033c6103b3366004612981565b610b20565b6103cb6103c63660046129bd565b610b51565b604080516001600160a01b0390931683526020830191909152016102b9565b6103486103f83660046128c7565b610bbc565b61033c61040b3660046129ed565b610c52565b6103487f000000000000000000000000000000000000000000000000000000000000000081565b61033c610d5d565b61033c61044d366004612981565b610d6f565b610348610460366004612892565b610d8a565b61033c610473366004612ab0565b610e1d565b600d546102e99061010090046001600160a01b031681565b600d5460ff166102ad565b6102e96104a9366004612892565b610e8c565b610309610eec565b6103486104c43660046128f1565b610f7a565b61033c611000565b61033c6104df3660046128f1565b611012565b61033c6110aa565b61033c6110ba565b61051b7f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff90911681526020016102b9565b61033c61053c3660046128f1565b6110d7565b600a546001600160a01b03166102e9565b61030961112d565b61033c6105683660046129ed565b61113c565b61033c61057b3660046128f1565b611147565b61033c6111db565b600f546102e9906001600160a01b031681565b61033c6105a9366004612b19565b611229565b600d546102ad90600160b01b900460ff1681565b6103096105d0366004612892565b611261565b600b546102e9906001600160a01b031681565b61033c6105f63660046128f1565b6112c8565b600b546102ad90600160a01b900460ff1681565b61033c61061d366004612b81565b6113f6565b6102ad610630366004612be4565b611581565b61033c6106433660046128f1565b611693565b6102ad6106563660046128f1565b611709565b610663600181565b60405160ff90911681526020016102b9565b60006001600160e01b0319821663780e9d6360e01b148061069a575061069a82611746565b92915050565b6060600080546106af90612c17565b80601f01602080910402602001604051908101604052809291908181526020018280546106db90612c17565b80156107285780601f106106fd57610100808354040283529160200191610728565b820191906000526020600020905b81548152906001019060200180831161070b57829003601f168201915b5050505050905090565b600061073d82611796565b506000908152600460205260409020546001600160a01b031690565b600061076482610e8c565b9050806001600160a01b0316836001600160a01b031614156107d75760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806107f357506107f38133611581565b6108655760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c000060648201526084016107ce565b61086f83836117f5565b505050565b61087c611863565b600d54600160a81b900460ff1615156001146108cd5760405162461bcd60e51b815260206004820152601060248201526f1b5a5b9d1a5b99c8191a5cd8589b195960821b60448201526064016107ce565b60005b63ffffffff811682111561086f57600083838363ffffffff168181106108f8576108f8612c52565b905060200281019061090a9190612c68565b61091390612c88565b6040808201516000908152600260205220549091506001600160a01b03161561096d5760405162461bcd60e51b815260206004820152600c60248201526b746f6b656e2065786973747360a01b60448201526064016107ce565b80516001600160a01b031633146109b45760405162461bcd60e51b815260206004820152600b60248201526a37bbb732b91032b93937b960a91b60448201526064016107ce565b7f00000000000000000000000000000000000000000000000000000000000000006109de60085490565b6109e9906001612d1b565b1115610a295760405162461bcd60e51b815260206004820152600f60248201526e657863656564656420737570706c7960881b60448201526064016107ce565b60408051606080820183528383015180835284516001600160a01b03908116602080860191825230868801908152875191820194909452905182169581019590955290511690830152906000906080016040516020818303038152906040528051906020012090506000610aaa8460200151836118a990919063ffffffff16565b600d549091506001600160a01b038083166101009092041614610afb5760405162461bcd60e51b815260206004820152600960248201526839b4b39032b93937b960b91b60448201526064016107ce565b610b093385604001516118cd565b505050508080610b1890612d33565b9150506108d0565b610b2a33826118e7565b610b465760405162461bcd60e51b81526004016107ce90612d57565b61086f838383611946565b6000807f0000000000000000000000000000000000000000000000000000000000000000612710610ba661ffff7f00000000000000000000000000000000000000000000000000000000000000001686612da5565b610bb09190612dda565b915091505b9250929050565b6000610bc783610f7a565b8210610c295760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b60648201526084016107ce565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610c5a611863565b610c6333611709565b610ca75760405162461bcd60e51b81526020600482015260156024820152743ab730baba3437b934bd32b21027a127903ab9b2b960591b60448201526064016107ce565b6001600160a01b038216610cec5760405162461bcd60e51b815260206004820152600c60248201526b63616e74206265207a65726f60a01b60448201526064016107ce565b600d8054610100600160b01b0319166101006001600160a01b03858116820260ff60a81b191692909217600160a81b85151502179283905560405192041681527f892cc3ddabcf4697be271eb3df1f098bec1713e58e7287c001532df08b5ebaab9060200160405180910390a15050565b610d65611aed565b610d6d611b47565b565b61086f83838360405180602001604052806000815250611229565b6000610d9560085490565b8210610df85760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b60648201526084016107ce565b60088281548110610e0b57610e0b612c52565b90600052602060002001549050919050565b610e25611aed565b610e2d611863565b600d54600160b01b900460ff1615610e755760405162461bcd60e51b815260206004820152600b60248201526a63616e74206368616e676560a81b60448201526064016107ce565b8051610e8890600e90602084019061275b565b5050565b6000818152600260205260408120546001600160a01b03168061069a5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016107ce565b600e8054610ef990612c17565b80601f0160208091040260200160405190810160405280929190818152602001828054610f2590612c17565b8015610f725780601f10610f4757610100808354040283529160200191610f72565b820191906000526020600020905b815481529060010190602001808311610f5557829003601f168201915b505050505081565b60006001600160a01b038216610fe45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016107ce565b506001600160a01b031660009081526003602052604090205490565b611008611aed565b610d6d6000611b99565b600a546001600160a01b03163314806110355750600b546001600160a01b031633145b6110515760405162461bcd60e51b81526004016107ce90612dee565b6001600160a01b0381166000818152600c602090815260408083208390558051938452908301919091527fe2e2dad866561a9926816384b10b4073c5e0e101b6c911e4936d22438bd63e9b91015b60405180910390a150565b6110b2611aed565b610d6d611beb565b6110c2611aed565b600d805460ff60b01b1916600160b01b179055565b6110df611aed565b600b80546001600160a01b0319166001600160a01b0383169081179091556040519081527ffbd1c2e6a1f767e08b9689ca3ce8ca1e7b60fbb71734bfc34f39f5bcb846cf309060200161109f565b6060600180546106af90612c17565b610e88338383611c28565b600a546001600160a01b031633148061116a5750600b546001600160a01b031633145b6111865760405162461bcd60e51b81526004016107ce90612dee565b600b54600160a01b900460ff1615156001146111cf5760405162461bcd60e51b8152602060048201526008602482015267191a5cd8589b195960c21b60448201526064016107ce565b6111d881611cf7565b50565b600a546001600160a01b03163314806111fe5750600b546001600160a01b031633145b61121a5760405162461bcd60e51b81526004016107ce90612dee565b600b805460ff60a01b19169055565b61123333836118e7565b61124f5760405162461bcd60e51b81526004016107ce90612d57565b61125b84848484611dae565b50505050565b606061126c82611796565b6000611276611de1565b9050600081511161129657604051806020016040528060008152506112c1565b806112a084611df0565b6040516020016112b1929190612e14565b6040516020818303038152906040525b9392505050565b600a546001600160a01b03163314806112eb5750600b546001600160a01b031633145b6113075760405162461bcd60e51b81526004016107ce90612dee565b6001600160a01b03811661134e5760405162461bcd60e51b815260206004820152600e60248201526d0c6c2dce840e6cae840e8de4060f60931b60448201526064016107ce565b6001600160a01b0381166000908152600c6020526040902054156113a45760405162461bcd60e51b815260206004820152600d60248201526c185b1c9958591e481859191959609a1b60448201526064016107ce565b6001600160a01b0381166000818152600c602090815260409182902042905581519283526001908301527fe2e2dad866561a9926816384b10b4073c5e0e101b6c911e4936d22438bd63e9b910161109f565b6113ff33611709565b6114435760405162461bcd60e51b81526020600482015260156024820152743ab730baba3437b934bd32b21027a127903ab9b2b960591b60448201526064016107ce565b60005b63ffffffff811682111561086f57600083838363ffffffff1681811061146e5761146e612c52565b9050604002018036038101906114849190612e43565b90506114ab81602001516000908152600260205260409020546001600160a01b0316151590565b156114e75760405162461bcd60e51b815260206004820152600c60248201526b746f6b656e2065786973747360a01b60448201526064016107ce565b7f000000000000000000000000000000000000000000000000000000000000000061151160085490565b61151c906001612d1b565b111561155c5760405162461bcd60e51b815260206004820152600f60248201526e657863656564656420737570706c7960881b60448201526064016107ce565b61156e816000015182602001516118cd565b508061157981612d33565b915050611446565b600f546000906001600160a01b03166115cd5760405162461bcd60e51b815260206004820152600e60248201526d07265676973747279203d203078360941b60448201526064016107ce565b600f546040516319f5a9f760e21b81526001600160a01b0384811660048301528581166024830152909116906367d6a7dc9060440160206040518083038186803b15801561161a57600080fd5b505afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190612e9a565b1515600114156116645750600161069a565b506001600160a01b0382811660009081526005602090815260408083209385168352929052205460ff1661069a565b61169b611aed565b6001600160a01b0381166117005760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107ce565b6111d881611b99565b6001600160a01b0381166000908152600c6020526040812054806117305750600092915050565b6201518061173e8242612eb7565b119392505050565b60006001600160e01b031982166380ac58cd60e01b148061177757506001600160e01b03198216635b5e139f60e01b145b8061069a57506301ffc9a760e01b6001600160e01b031983161461069a565b6000818152600260205260409020546001600160a01b03166111d85760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016107ce565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061182a82610e8c565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600d5460ff1615610d6d5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016107ce565b60008060006118b88585611eee565b915091506118c581611f5b565b509392505050565b610e88828260405180602001604052806000815250612116565b6000806118f383610e8c565b9050806001600160a01b0316846001600160a01b0316148061191a575061191a8185611581565b8061193e5750836001600160a01b031661193384610732565b6001600160a01b0316145b949350505050565b826001600160a01b031661195982610e8c565b6001600160a01b0316146119bd5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016107ce565b6001600160a01b038216611a1f5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016107ce565b611a2a838383612149565b611a356000826117f5565b6001600160a01b0383166000908152600360205260408120805460019290611a5e908490612eb7565b90915550506001600160a01b0382166000908152600360205260408120805460019290611a8c908490612d1b565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a546001600160a01b03163314610d6d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107ce565b611b4f612201565b600d805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611bf3611863565b600d805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611b7c3390565b816001600160a01b0316836001600160a01b03161415611c8a5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016107ce565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611cff611aed565b6001600160a01b038116611d3f5760405162461bcd60e51b81526020600482015260076024820152666164647228302960c81b60448201526064016107ce565b6001611d4e6201518042612eb7565b611d589190612eb7565b6001600160a01b0382166000818152600c60209081526040918290209390935580519182526001928201929092527fe2e2dad866561a9926816384b10b4073c5e0e101b6c911e4936d22438bd63e9b910161109f565b611db9848484611946565b611dc58484848461224a565b61125b5760405162461bcd60e51b81526004016107ce90612ece565b6060600e80546106af90612c17565b606081611e145750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611e3e5780611e2881612f20565b9150611e379050600a83612dda565b9150611e18565b60008167ffffffffffffffff811115611e5957611e59612a24565b6040519080825280601f01601f191660200182016040528015611e83576020820181803683370190505b5090505b841561193e57611e98600183612eb7565b9150611ea5600a86612f3b565b611eb0906030612d1b565b60f81b818381518110611ec557611ec5612c52565b60200101906001600160f81b031916908160001a905350611ee7600a86612dda565b9450611e87565b600080825160411415611f255760208301516040840151606085015160001a611f1987828585612357565b94509450505050610bb5565b825160401415611f4f5760208301516040840151611f44868383612444565b935093505050610bb5565b50600090506002610bb5565b6000816004811115611f6f57611f6f612f4f565b1415611f785750565b6001816004811115611f8c57611f8c612f4f565b1415611fda5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016107ce565b6002816004811115611fee57611fee612f4f565b141561203c5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016107ce565b600381600481111561205057612050612f4f565b14156120a95760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016107ce565b60048160048111156120bd576120bd612f4f565b14156111d85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016107ce565b612120838361247d565b61212d600084848461224a565b61086f5760405162461bcd60e51b81526004016107ce90612ece565b6001600160a01b0383166121a45761219f81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6121c7565b816001600160a01b0316836001600160a01b0316146121c7576121c783826125cb565b6001600160a01b0382166121de5761086f81612668565b826001600160a01b0316826001600160a01b03161461086f5761086f8282612717565b600d5460ff16610d6d5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016107ce565b60006001600160a01b0384163b1561234c57604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061228e903390899088908890600401612f65565b602060405180830381600087803b1580156122a857600080fd5b505af19250505080156122d8575060408051601f3d908101601f191682019092526122d591810190612fa2565b60015b612332573d808015612306576040519150601f19603f3d011682016040523d82523d6000602084013e61230b565b606091505b50805161232a5760405162461bcd60e51b81526004016107ce90612ece565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061193e565b506001949350505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561238e575060009050600361243b565b8460ff16601b141580156123a657508460ff16601c14155b156123b7575060009050600461243b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561240b573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166124345760006001925092505061243b565b9150600090505b94509492505050565b6000806001600160ff1b0383168161246160ff86901c601b612d1b565b905061246f87828885612357565b935093505050935093915050565b6001600160a01b0382166124d35760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016107ce565b6000818152600260205260409020546001600160a01b0316156125385760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016107ce565b61254460008383612149565b6001600160a01b038216600090815260036020526040812080546001929061256d908490612d1b565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600060016125d884610f7a565b6125e29190612eb7565b600083815260076020526040902054909150808214612635576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061267a90600190612eb7565b600083815260096020526040812054600880549394509092849081106126a2576126a2612c52565b9060005260206000200154905080600883815481106126c3576126c3612c52565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806126fb576126fb612fbf565b6001900381819060005260206000200160009055905550505050565b600061272283610f7a565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b82805461276790612c17565b90600052602060002090601f01602090048101928261278957600085556127cf565b82601f106127a257805160ff19168380011785556127cf565b828001600101855582156127cf579182015b828111156127cf5782518255916020019190600101906127b4565b506127db9291506127df565b5090565b5b808211156127db57600081556001016127e0565b6001600160e01b0319811681146111d857600080fd5b60006020828403121561281c57600080fd5b81356112c1816127f4565b60005b8381101561284257818101518382015260200161282a565b8381111561125b5750506000910152565b6000815180845261286b816020860160208601612827565b601f01601f19169290920160200192915050565b6020815260006112c16020830184612853565b6000602082840312156128a457600080fd5b5035919050565b80356001600160a01b03811681146128c257600080fd5b919050565b600080604083850312156128da57600080fd5b6128e3836128ab565b946020939093013593505050565b60006020828403121561290357600080fd5b6112c1826128ab565b6000806020838503121561291f57600080fd5b823567ffffffffffffffff8082111561293757600080fd5b818501915085601f83011261294b57600080fd5b81358181111561295a57600080fd5b8660208260051b850101111561296f57600080fd5b60209290920196919550909350505050565b60008060006060848603121561299657600080fd5b61299f846128ab565b92506129ad602085016128ab565b9150604084013590509250925092565b600080604083850312156129d057600080fd5b50508035926020909101359150565b80151581146111d857600080fd5b60008060408385031215612a0057600080fd5b612a09836128ab565b91506020830135612a19816129df565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612a5557612a55612a24565b604051601f8501601f19908116603f01168101908282118183101715612a7d57612a7d612a24565b81604052809350858152868686011115612a9657600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215612ac257600080fd5b813567ffffffffffffffff811115612ad957600080fd5b8201601f81018413612aea57600080fd5b61193e84823560208401612a3a565b600082601f830112612b0a57600080fd5b6112c183833560208501612a3a565b60008060008060808587031215612b2f57600080fd5b612b38856128ab565b9350612b46602086016128ab565b925060408501359150606085013567ffffffffffffffff811115612b6957600080fd5b612b7587828801612af9565b91505092959194509250565b60008060208385031215612b9457600080fd5b823567ffffffffffffffff80821115612bac57600080fd5b818501915085601f830112612bc057600080fd5b813581811115612bcf57600080fd5b8660208260061b850101111561296f57600080fd5b60008060408385031215612bf757600080fd5b612c00836128ab565b9150612c0e602084016128ab565b90509250929050565b600181811c90821680612c2b57607f821691505b60208210811415612c4c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b60008235605e19833603018112612c7e57600080fd5b9190910192915050565b600060608236031215612c9a57600080fd5b6040516060810167ffffffffffffffff8282108183111715612cbe57612cbe612a24565b81604052612ccb856128ab565b83526020850135915080821115612ce157600080fd5b50612cee36828601612af9565b602083015250604092830135928101929092525090565b634e487b7160e01b600052601160045260246000fd5b60008219821115612d2e57612d2e612d05565b500190565b600063ffffffff80831681811415612d4d57612d4d612d05565b6001019392505050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6000816000190483118215151615612dbf57612dbf612d05565b500290565b634e487b7160e01b600052601260045260246000fd5b600082612de957612de9612dc4565b500490565b6020808252600c908201526b3737ba1037b137a0b236b4b760a11b604082015260600190565b60008351612e26818460208801612827565b835190830190612e3a818360208801612827565b01949350505050565b600060408284031215612e5557600080fd5b6040516040810181811067ffffffffffffffff82111715612e7857612e78612a24565b604052612e84836128ab565b8152602083013560208201528091505092915050565b600060208284031215612eac57600080fd5b81516112c1816129df565b600082821015612ec957612ec9612d05565b500390565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000600019821415612f3457612f34612d05565b5060010190565b600082612f4a57612f4a612dc4565b500690565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612f9890830184612853565b9695505050505050565b600060208284031215612fb457600080fd5b81516112c1816127f4565b634e487b7160e01b600052603160045260246000fdfea26469706673582212208748a262441041dfab5f326e0b1e6d554572def581541933bd4561c362eea50664736f6c6343000809003300000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000085508ce7885b65a57ee070460055f3e4b412051e00000000000000000000000000000000000000000000000000000000000015b30000000000000000000000000d52eb2d936602abf5a45a32f8223417903f90e200000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000010506978656c61746564204865726f6573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002504800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046970667300000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102955760003560e01c806370a0823111610167578063b39ba60a116100ce578063d5edf45b11610087578063d5edf45b146105fb578063d7dd397d1461060f578063e985e9c514610622578063f2fde38b14610635578063fb12a87614610648578063ffa1ad741461065b57600080fd5b8063b39ba60a14610588578063b88d4fde1461059b578063bb0aa8ef146105ae578063c87b56dd146105c2578063c95ab462146105d5578063cd161d2e146105e857600080fd5b80638ce87646116101205780638ce876461461052e5780638da5cb5b1461054157806395d89b4114610552578063a22cb4651461055a578063a47a2e771461056d578063a790c0e21461058057600080fd5b806370a08231146104b6578063715018a6146104c95780637ff9f614146104d15780638456cb59146104e4578063875d364e146104ec5780638a71bb2d146104f457600080fd5b80632a55205a1161020b5780634f6ccce7116101c45780634f6ccce71461045257806355f804b3146104655780635b7633d0146104785780635c975abb146104905780636352211e1461049b5780636c0360eb146104ae57600080fd5b80632a55205a146103b85780632f745c59146103ea5780633ad0288e146103fd5780633ef110f1146104105780633f4ba83a1461043757806342842e0e1461043f57600080fd5b80630c9999291161025d5780630c9999291461033e57806313e2263e1461035657806318160ddd1461036a5780631ad32562146103725780631dd8354c1461039257806323b872dd146103a557600080fd5b806301ffc9a71461029a57806302d05d3f146102c257806306fdde0314610301578063081812fc14610316578063095ea7b314610329575b600080fd5b6102ad6102a836600461280a565b610675565b60405190151581526020015b60405180910390f35b6102e97f0000000000000000000000000d52eb2d936602abf5a45a32f8223417903f90e281565b6040516001600160a01b0390911681526020016102b9565b6103096106a0565b6040516102b9919061287f565b6102e9610324366004612892565b610732565b61033c6103373660046128c7565b610759565b005b6103486201518081565b6040519081526020016102b9565b600d546102ad90600160a81b900460ff1681565b600854610348565b6103486103803660046128f1565b600c6020526000908152604090205481565b61033c6103a036600461290c565b610874565b61033c6103b3366004612981565b610b20565b6103cb6103c63660046129bd565b610b51565b604080516001600160a01b0390931683526020830191909152016102b9565b6103486103f83660046128c7565b610bbc565b61033c61040b3660046129ed565b610c52565b6103487f00000000000000000000000000000000000000000000000000000000000015b381565b61033c610d5d565b61033c61044d366004612981565b610d6f565b610348610460366004612892565b610d8a565b61033c610473366004612ab0565b610e1d565b600d546102e99061010090046001600160a01b031681565b600d5460ff166102ad565b6102e96104a9366004612892565b610e8c565b610309610eec565b6103486104c43660046128f1565b610f7a565b61033c611000565b61033c6104df3660046128f1565b611012565b61033c6110aa565b61033c6110ba565b61051b7f00000000000000000000000000000000000000000000000000000000000001f481565b60405161ffff90911681526020016102b9565b61033c61053c3660046128f1565b6110d7565b600a546001600160a01b03166102e9565b61030961112d565b61033c6105683660046129ed565b61113c565b61033c61057b3660046128f1565b611147565b61033c6111db565b600f546102e9906001600160a01b031681565b61033c6105a9366004612b19565b611229565b600d546102ad90600160b01b900460ff1681565b6103096105d0366004612892565b611261565b600b546102e9906001600160a01b031681565b61033c6105f63660046128f1565b6112c8565b600b546102ad90600160a01b900460ff1681565b61033c61061d366004612b81565b6113f6565b6102ad610630366004612be4565b611581565b61033c6106433660046128f1565b611693565b6102ad6106563660046128f1565b611709565b610663600181565b60405160ff90911681526020016102b9565b60006001600160e01b0319821663780e9d6360e01b148061069a575061069a82611746565b92915050565b6060600080546106af90612c17565b80601f01602080910402602001604051908101604052809291908181526020018280546106db90612c17565b80156107285780601f106106fd57610100808354040283529160200191610728565b820191906000526020600020905b81548152906001019060200180831161070b57829003601f168201915b5050505050905090565b600061073d82611796565b506000908152600460205260409020546001600160a01b031690565b600061076482610e8c565b9050806001600160a01b0316836001600160a01b031614156107d75760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806107f357506107f38133611581565b6108655760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c000060648201526084016107ce565b61086f83836117f5565b505050565b61087c611863565b600d54600160a81b900460ff1615156001146108cd5760405162461bcd60e51b815260206004820152601060248201526f1b5a5b9d1a5b99c8191a5cd8589b195960821b60448201526064016107ce565b60005b63ffffffff811682111561086f57600083838363ffffffff168181106108f8576108f8612c52565b905060200281019061090a9190612c68565b61091390612c88565b6040808201516000908152600260205220549091506001600160a01b03161561096d5760405162461bcd60e51b815260206004820152600c60248201526b746f6b656e2065786973747360a01b60448201526064016107ce565b80516001600160a01b031633146109b45760405162461bcd60e51b815260206004820152600b60248201526a37bbb732b91032b93937b960a91b60448201526064016107ce565b7f00000000000000000000000000000000000000000000000000000000000015b36109de60085490565b6109e9906001612d1b565b1115610a295760405162461bcd60e51b815260206004820152600f60248201526e657863656564656420737570706c7960881b60448201526064016107ce565b60408051606080820183528383015180835284516001600160a01b03908116602080860191825230868801908152875191820194909452905182169581019590955290511690830152906000906080016040516020818303038152906040528051906020012090506000610aaa8460200151836118a990919063ffffffff16565b600d549091506001600160a01b038083166101009092041614610afb5760405162461bcd60e51b815260206004820152600960248201526839b4b39032b93937b960b91b60448201526064016107ce565b610b093385604001516118cd565b505050508080610b1890612d33565b9150506108d0565b610b2a33826118e7565b610b465760405162461bcd60e51b81526004016107ce90612d57565b61086f838383611946565b6000807f0000000000000000000000000d52eb2d936602abf5a45a32f8223417903f90e2612710610ba661ffff7f00000000000000000000000000000000000000000000000000000000000001f41686612da5565b610bb09190612dda565b915091505b9250929050565b6000610bc783610f7a565b8210610c295760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b60648201526084016107ce565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610c5a611863565b610c6333611709565b610ca75760405162461bcd60e51b81526020600482015260156024820152743ab730baba3437b934bd32b21027a127903ab9b2b960591b60448201526064016107ce565b6001600160a01b038216610cec5760405162461bcd60e51b815260206004820152600c60248201526b63616e74206265207a65726f60a01b60448201526064016107ce565b600d8054610100600160b01b0319166101006001600160a01b03858116820260ff60a81b191692909217600160a81b85151502179283905560405192041681527f892cc3ddabcf4697be271eb3df1f098bec1713e58e7287c001532df08b5ebaab9060200160405180910390a15050565b610d65611aed565b610d6d611b47565b565b61086f83838360405180602001604052806000815250611229565b6000610d9560085490565b8210610df85760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b60648201526084016107ce565b60088281548110610e0b57610e0b612c52565b90600052602060002001549050919050565b610e25611aed565b610e2d611863565b600d54600160b01b900460ff1615610e755760405162461bcd60e51b815260206004820152600b60248201526a63616e74206368616e676560a81b60448201526064016107ce565b8051610e8890600e90602084019061275b565b5050565b6000818152600260205260408120546001600160a01b03168061069a5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016107ce565b600e8054610ef990612c17565b80601f0160208091040260200160405190810160405280929190818152602001828054610f2590612c17565b8015610f725780601f10610f4757610100808354040283529160200191610f72565b820191906000526020600020905b815481529060010190602001808311610f5557829003601f168201915b505050505081565b60006001600160a01b038216610fe45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016107ce565b506001600160a01b031660009081526003602052604090205490565b611008611aed565b610d6d6000611b99565b600a546001600160a01b03163314806110355750600b546001600160a01b031633145b6110515760405162461bcd60e51b81526004016107ce90612dee565b6001600160a01b0381166000818152600c602090815260408083208390558051938452908301919091527fe2e2dad866561a9926816384b10b4073c5e0e101b6c911e4936d22438bd63e9b91015b60405180910390a150565b6110b2611aed565b610d6d611beb565b6110c2611aed565b600d805460ff60b01b1916600160b01b179055565b6110df611aed565b600b80546001600160a01b0319166001600160a01b0383169081179091556040519081527ffbd1c2e6a1f767e08b9689ca3ce8ca1e7b60fbb71734bfc34f39f5bcb846cf309060200161109f565b6060600180546106af90612c17565b610e88338383611c28565b600a546001600160a01b031633148061116a5750600b546001600160a01b031633145b6111865760405162461bcd60e51b81526004016107ce90612dee565b600b54600160a01b900460ff1615156001146111cf5760405162461bcd60e51b8152602060048201526008602482015267191a5cd8589b195960c21b60448201526064016107ce565b6111d881611cf7565b50565b600a546001600160a01b03163314806111fe5750600b546001600160a01b031633145b61121a5760405162461bcd60e51b81526004016107ce90612dee565b600b805460ff60a01b19169055565b61123333836118e7565b61124f5760405162461bcd60e51b81526004016107ce90612d57565b61125b84848484611dae565b50505050565b606061126c82611796565b6000611276611de1565b9050600081511161129657604051806020016040528060008152506112c1565b806112a084611df0565b6040516020016112b1929190612e14565b6040516020818303038152906040525b9392505050565b600a546001600160a01b03163314806112eb5750600b546001600160a01b031633145b6113075760405162461bcd60e51b81526004016107ce90612dee565b6001600160a01b03811661134e5760405162461bcd60e51b815260206004820152600e60248201526d0c6c2dce840e6cae840e8de4060f60931b60448201526064016107ce565b6001600160a01b0381166000908152600c6020526040902054156113a45760405162461bcd60e51b815260206004820152600d60248201526c185b1c9958591e481859191959609a1b60448201526064016107ce565b6001600160a01b0381166000818152600c602090815260409182902042905581519283526001908301527fe2e2dad866561a9926816384b10b4073c5e0e101b6c911e4936d22438bd63e9b910161109f565b6113ff33611709565b6114435760405162461bcd60e51b81526020600482015260156024820152743ab730baba3437b934bd32b21027a127903ab9b2b960591b60448201526064016107ce565b60005b63ffffffff811682111561086f57600083838363ffffffff1681811061146e5761146e612c52565b9050604002018036038101906114849190612e43565b90506114ab81602001516000908152600260205260409020546001600160a01b0316151590565b156114e75760405162461bcd60e51b815260206004820152600c60248201526b746f6b656e2065786973747360a01b60448201526064016107ce565b7f00000000000000000000000000000000000000000000000000000000000015b361151160085490565b61151c906001612d1b565b111561155c5760405162461bcd60e51b815260206004820152600f60248201526e657863656564656420737570706c7960881b60448201526064016107ce565b61156e816000015182602001516118cd565b508061157981612d33565b915050611446565b600f546000906001600160a01b03166115cd5760405162461bcd60e51b815260206004820152600e60248201526d07265676973747279203d203078360941b60448201526064016107ce565b600f546040516319f5a9f760e21b81526001600160a01b0384811660048301528581166024830152909116906367d6a7dc9060440160206040518083038186803b15801561161a57600080fd5b505afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190612e9a565b1515600114156116645750600161069a565b506001600160a01b0382811660009081526005602090815260408083209385168352929052205460ff1661069a565b61169b611aed565b6001600160a01b0381166117005760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107ce565b6111d881611b99565b6001600160a01b0381166000908152600c6020526040812054806117305750600092915050565b6201518061173e8242612eb7565b119392505050565b60006001600160e01b031982166380ac58cd60e01b148061177757506001600160e01b03198216635b5e139f60e01b145b8061069a57506301ffc9a760e01b6001600160e01b031983161461069a565b6000818152600260205260409020546001600160a01b03166111d85760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016107ce565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061182a82610e8c565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600d5460ff1615610d6d5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016107ce565b60008060006118b88585611eee565b915091506118c581611f5b565b509392505050565b610e88828260405180602001604052806000815250612116565b6000806118f383610e8c565b9050806001600160a01b0316846001600160a01b0316148061191a575061191a8185611581565b8061193e5750836001600160a01b031661193384610732565b6001600160a01b0316145b949350505050565b826001600160a01b031661195982610e8c565b6001600160a01b0316146119bd5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016107ce565b6001600160a01b038216611a1f5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016107ce565b611a2a838383612149565b611a356000826117f5565b6001600160a01b0383166000908152600360205260408120805460019290611a5e908490612eb7565b90915550506001600160a01b0382166000908152600360205260408120805460019290611a8c908490612d1b565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a546001600160a01b03163314610d6d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107ce565b611b4f612201565b600d805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611bf3611863565b600d805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611b7c3390565b816001600160a01b0316836001600160a01b03161415611c8a5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016107ce565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611cff611aed565b6001600160a01b038116611d3f5760405162461bcd60e51b81526020600482015260076024820152666164647228302960c81b60448201526064016107ce565b6001611d4e6201518042612eb7565b611d589190612eb7565b6001600160a01b0382166000818152600c60209081526040918290209390935580519182526001928201929092527fe2e2dad866561a9926816384b10b4073c5e0e101b6c911e4936d22438bd63e9b910161109f565b611db9848484611946565b611dc58484848461224a565b61125b5760405162461bcd60e51b81526004016107ce90612ece565b6060600e80546106af90612c17565b606081611e145750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611e3e5780611e2881612f20565b9150611e379050600a83612dda565b9150611e18565b60008167ffffffffffffffff811115611e5957611e59612a24565b6040519080825280601f01601f191660200182016040528015611e83576020820181803683370190505b5090505b841561193e57611e98600183612eb7565b9150611ea5600a86612f3b565b611eb0906030612d1b565b60f81b818381518110611ec557611ec5612c52565b60200101906001600160f81b031916908160001a905350611ee7600a86612dda565b9450611e87565b600080825160411415611f255760208301516040840151606085015160001a611f1987828585612357565b94509450505050610bb5565b825160401415611f4f5760208301516040840151611f44868383612444565b935093505050610bb5565b50600090506002610bb5565b6000816004811115611f6f57611f6f612f4f565b1415611f785750565b6001816004811115611f8c57611f8c612f4f565b1415611fda5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016107ce565b6002816004811115611fee57611fee612f4f565b141561203c5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016107ce565b600381600481111561205057612050612f4f565b14156120a95760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016107ce565b60048160048111156120bd576120bd612f4f565b14156111d85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016107ce565b612120838361247d565b61212d600084848461224a565b61086f5760405162461bcd60e51b81526004016107ce90612ece565b6001600160a01b0383166121a45761219f81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6121c7565b816001600160a01b0316836001600160a01b0316146121c7576121c783826125cb565b6001600160a01b0382166121de5761086f81612668565b826001600160a01b0316826001600160a01b03161461086f5761086f8282612717565b600d5460ff16610d6d5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016107ce565b60006001600160a01b0384163b1561234c57604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061228e903390899088908890600401612f65565b602060405180830381600087803b1580156122a857600080fd5b505af19250505080156122d8575060408051601f3d908101601f191682019092526122d591810190612fa2565b60015b612332573d808015612306576040519150601f19603f3d011682016040523d82523d6000602084013e61230b565b606091505b50805161232a5760405162461bcd60e51b81526004016107ce90612ece565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061193e565b506001949350505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561238e575060009050600361243b565b8460ff16601b141580156123a657508460ff16601c14155b156123b7575060009050600461243b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561240b573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166124345760006001925092505061243b565b9150600090505b94509492505050565b6000806001600160ff1b0383168161246160ff86901c601b612d1b565b905061246f87828885612357565b935093505050935093915050565b6001600160a01b0382166124d35760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016107ce565b6000818152600260205260409020546001600160a01b0316156125385760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016107ce565b61254460008383612149565b6001600160a01b038216600090815260036020526040812080546001929061256d908490612d1b565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600060016125d884610f7a565b6125e29190612eb7565b600083815260076020526040902054909150808214612635576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061267a90600190612eb7565b600083815260096020526040812054600880549394509092849081106126a2576126a2612c52565b9060005260206000200154905080600883815481106126c3576126c3612c52565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806126fb576126fb612fbf565b6001900381819060005260206000200160009055905550505050565b600061272283610f7a565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b82805461276790612c17565b90600052602060002090601f01602090048101928261278957600085556127cf565b82601f106127a257805160ff19168380011785556127cf565b828001600101855582156127cf579182015b828111156127cf5782518255916020019190600101906127b4565b506127db9291506127df565b5090565b5b808211156127db57600081556001016127e0565b6001600160e01b0319811681146111d857600080fd5b60006020828403121561281c57600080fd5b81356112c1816127f4565b60005b8381101561284257818101518382015260200161282a565b8381111561125b5750506000910152565b6000815180845261286b816020860160208601612827565b601f01601f19169290920160200192915050565b6020815260006112c16020830184612853565b6000602082840312156128a457600080fd5b5035919050565b80356001600160a01b03811681146128c257600080fd5b919050565b600080604083850312156128da57600080fd5b6128e3836128ab565b946020939093013593505050565b60006020828403121561290357600080fd5b6112c1826128ab565b6000806020838503121561291f57600080fd5b823567ffffffffffffffff8082111561293757600080fd5b818501915085601f83011261294b57600080fd5b81358181111561295a57600080fd5b8660208260051b850101111561296f57600080fd5b60209290920196919550909350505050565b60008060006060848603121561299657600080fd5b61299f846128ab565b92506129ad602085016128ab565b9150604084013590509250925092565b600080604083850312156129d057600080fd5b50508035926020909101359150565b80151581146111d857600080fd5b60008060408385031215612a0057600080fd5b612a09836128ab565b91506020830135612a19816129df565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612a5557612a55612a24565b604051601f8501601f19908116603f01168101908282118183101715612a7d57612a7d612a24565b81604052809350858152868686011115612a9657600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215612ac257600080fd5b813567ffffffffffffffff811115612ad957600080fd5b8201601f81018413612aea57600080fd5b61193e84823560208401612a3a565b600082601f830112612b0a57600080fd5b6112c183833560208501612a3a565b60008060008060808587031215612b2f57600080fd5b612b38856128ab565b9350612b46602086016128ab565b925060408501359150606085013567ffffffffffffffff811115612b6957600080fd5b612b7587828801612af9565b91505092959194509250565b60008060208385031215612b9457600080fd5b823567ffffffffffffffff80821115612bac57600080fd5b818501915085601f830112612bc057600080fd5b813581811115612bcf57600080fd5b8660208260061b850101111561296f57600080fd5b60008060408385031215612bf757600080fd5b612c00836128ab565b9150612c0e602084016128ab565b90509250929050565b600181811c90821680612c2b57607f821691505b60208210811415612c4c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b60008235605e19833603018112612c7e57600080fd5b9190910192915050565b600060608236031215612c9a57600080fd5b6040516060810167ffffffffffffffff8282108183111715612cbe57612cbe612a24565b81604052612ccb856128ab565b83526020850135915080821115612ce157600080fd5b50612cee36828601612af9565b602083015250604092830135928101929092525090565b634e487b7160e01b600052601160045260246000fd5b60008219821115612d2e57612d2e612d05565b500190565b600063ffffffff80831681811415612d4d57612d4d612d05565b6001019392505050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6000816000190483118215151615612dbf57612dbf612d05565b500290565b634e487b7160e01b600052601260045260246000fd5b600082612de957612de9612dc4565b500490565b6020808252600c908201526b3737ba1037b137a0b236b4b760a11b604082015260600190565b60008351612e26818460208801612827565b835190830190612e3a818360208801612827565b01949350505050565b600060408284031215612e5557600080fd5b6040516040810181811067ffffffffffffffff82111715612e7857612e78612a24565b604052612e84836128ab565b8152602083013560208201528091505092915050565b600060208284031215612eac57600080fd5b81516112c1816129df565b600082821015612ec957612ec9612d05565b500390565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000600019821415612f3457612f34612d05565b5060010190565b600082612f4a57612f4a612dc4565b500690565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612f9890830184612853565b9695505050505050565b600060208284031215612fb457600080fd5b81516112c1816127f4565b634e487b7160e01b600052603160045260246000fdfea26469706673582212208748a262441041dfab5f326e0b1e6d554572def581541933bd4561c362eea50664736f6c63430008090033

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

00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000085508ce7885b65a57ee070460055f3e4b412051e00000000000000000000000000000000000000000000000000000000000015b30000000000000000000000000d52eb2d936602abf5a45a32f8223417903f90e200000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000010506978656c61746564204865726f6573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002504800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046970667300000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _tokenName (string): Pixelated Heroes
Arg [1] : _tokenSymbol (string): PH
Arg [2] : _crsAddress (address): 0x85508Ce7885B65a57Ee070460055f3e4b412051e
Arg [3] : _totalSupply (uint256): 5555
Arg [4] : _creator (address): 0x0d52EB2d936602aBf5a45a32f8223417903F90e2
Arg [5] : _royaltyPercentage (uint16): 500
Arg [6] : _initialBaseURI (string): ipfs

-----Encoded View---------------
13 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [2] : 00000000000000000000000085508ce7885b65a57ee070460055f3e4b412051e
Arg [3] : 00000000000000000000000000000000000000000000000000000000000015b3
Arg [4] : 0000000000000000000000000d52eb2d936602abf5a45a32f8223417903f90e2
Arg [5] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000010
Arg [8] : 506978656c61746564204865726f657300000000000000000000000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [10] : 5048000000000000000000000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [12] : 6970667300000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

63142:6714:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56919:224;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;56919:224:0;;;;;;;;63333:32;;;;;;;;-1:-1:-1;;;;;756:32:1;;;738:51;;726:2;711:18;63333:32:0;592:203:1;43653:100:0;;;:::i;:::-;;;;;;;:::i;45166:171::-;;;;;;:::i;:::-;;:::i;44683:417::-;;;;;;:::i;:::-;;:::i;:::-;;17592:53;;17639:6;17592:53;;;;;2319:25:1;;;2307:2;2292:18;17592:53:0;2173:177:1;63407:33:0;;;;;-1:-1:-1;;;63407:33:0;;;;;;57559:113;57647:10;:17;57559:113;;17745:48;;;;;;:::i;:::-;;;;;;;;;;;;;;67038:987;;;;;;:::i;:::-;;:::i;45866:336::-;;;;;;:::i;:::-;;:::i;69246:199::-;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;3985:32:1;;;3967:51;;4049:2;4034:18;;4027:34;;;;3940:18;69246:199:0;3793:274:1;57227:256:0;;;;;;:::i;:::-;;:::i;64968:344::-;;;;;;:::i;:::-;;:::i;63543:41::-;;;;;69524:67;;;:::i;46273:185::-;;;;;;:::i;:::-;;:::i;57749:233::-;;;;;;:::i;:::-;;:::i;66624:175::-;;;;;;:::i;:::-;;:::i;63372:28::-;;;;;;;;-1:-1:-1;;;;;63372:28:0;;;22017:86;22088:7;;;;22017:86;;43364:222;;;;;;:::i;:::-;;:::i;63591:21::-;;;:::i;43095:207::-;;;;;;:::i;:::-;;:::i;16646:103::-;;;:::i;18737:175::-;;;;;;:::i;:::-;;:::i;69453:63::-;;;:::i;66807:81::-;;;:::i;63285:41::-;;;;;;;;5914:6:1;5902:19;;;5884:38;;5872:2;5857:18;63285:41:0;5740:188:1;18099:148:0;;;;;;:::i;:::-;;:::i;15998:87::-;16071:6;;-1:-1:-1;;;;;16071:6:0;15998:87;;43822:104;;;:::i;45409:155::-;;;;;;:::i;:::-;;:::i;19426:195::-;;;;;;:::i;:::-;;:::i;19629:98::-;;;:::i;63619:60::-;;;;;-1:-1:-1;;;;;63619:60:0;;;46529:323;;;;;;:::i;:::-;;:::i;63513:23::-;;;;;-1:-1:-1;;;63513:23:0;;;;;;43997:281;;;;;;:::i;:::-;;:::i;17562:23::-;;;;;-1:-1:-1;;;;;17562:23:0;;;18355:312;;;;;;:::i;:::-;;:::i;17652:39::-;;;;;-1:-1:-1;;;17652:39:0;;;;;;68033:426;;;;;;:::i;:::-;;:::i;68670:345::-;;;;;;:::i;:::-;;:::i;16904:201::-;;;;;;:::i;:::-;;:::i;19837:277::-;;;;;;:::i;:::-;;:::i;63245:33::-;;63277:1;63245:33;;;;;8041:4:1;8029:17;;;8011:36;;7999:2;7984:18;63245:33:0;7869:184:1;56919:224:0;57021:4;-1:-1:-1;;;;;;57045:50:0;;-1:-1:-1;;;57045:50:0;;:90;;;57099:36;57123:11;57099:23;:36::i;:::-;57038:97;56919:224;-1:-1:-1;;56919:224:0:o;43653:100::-;43707:13;43740:5;43733:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43653:100;:::o;45166:171::-;45242:7;45262:23;45277:7;45262:14;:23::i;:::-;-1:-1:-1;45305:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;45305:24:0;;45166:171::o;44683:417::-;44764:13;44780:23;44795:7;44780:14;:23::i;:::-;44764:39;;44828:5;-1:-1:-1;;;;;44822:11:0;:2;-1:-1:-1;;;;;44822:11:0;;;44814:57;;;;-1:-1:-1;;;44814:57:0;;8645:2:1;44814:57:0;;;8627:21:1;8684:2;8664:18;;;8657:30;8723:34;8703:18;;;8696:62;-1:-1:-1;;;8774:18:1;;;8767:31;8815:19;;44814:57:0;;;;;;;;;14629:10;-1:-1:-1;;;;;44906:21:0;;;;:62;;-1:-1:-1;44931:37:0;44948:5;14629:10;68670:345;:::i;44931:37::-;44884:174;;;;-1:-1:-1;;;44884:174:0;;9047:2:1;44884:174:0;;;9029:21:1;9086:2;9066:18;;;9059:30;9125:34;9105:18;;;9098:62;9196:32;9176:18;;;9169:60;9246:19;;44884:174:0;8845:426:1;44884:174:0;45071:21;45080:2;45084:7;45071:8;:21::i;:::-;44753:347;44683:417;;:::o;67038:987::-;21622:19;:17;:19::i;:::-;67143:21:::1;::::0;-1:-1:-1;;;67143:21:0;::::1;;;:29;;67168:4;67143:29;67135:58;;;::::0;-1:-1:-1;;;67135:58:0;;9478:2:1;67135:58:0::1;::::0;::::1;9460:21:1::0;9517:2;9497:18;;;9490:30;-1:-1:-1;;;9536:18:1;;;9529:46;9592:18;;67135:58:0::1;9276:340:1::0;67135:58:0::1;67209:8;67204:814;67221:19;::::0;::::1;::::0;-1:-1:-1;67204:814:0::1;;;67262:36;67301:8;;67310:1;67301:11;;;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;67262:50;;;:::i;:::-;67402:15;::::0;;::::1;::::0;48424:4;48448:16;;;:7;:16;;;;67262:50;;-1:-1:-1;;;;;;48448:16:0;:30;67386:58:::1;;;::::0;-1:-1:-1;;;67386:58:0;;11065:2:1;67386:58:0::1;::::0;::::1;11047:21:1::0;11104:2;11084:18;;;11077:30;-1:-1:-1;;;11123:18:1;;;11116:42;11175:18;;67386:58:0::1;10863:336:1::0;67386:58:0::1;67467:13:::0;;-1:-1:-1;;;;;67467:27:0::1;67484:10;67467:27;67459:51;;;::::0;-1:-1:-1;;;67459:51:0;;11406:2:1;67459:51:0::1;::::0;::::1;11388:21:1::0;11445:2;11425:18;;;11418:30;-1:-1:-1;;;11464:18:1;;;11457:41;11515:18;;67459:51:0::1;11204:335:1::0;67459:51:0::1;67554:16;67533:13;57647:10:::0;:17;;57559:113;67533:13:::1;:17;::::0;67549:1:::1;67533:17;:::i;:::-;:37;;67525:65;;;::::0;-1:-1:-1;;;67525:65:0;;12011:2:1;67525:65:0::1;::::0;::::1;11993:21:1::0;12050:2;12030:18;;;12023:30;-1:-1:-1;;;12069:18:1;;;12062:45;12124:18;;67525:65:0::1;11809:339:1::0;67525:65:0::1;67653:68;::::0;;::::1;::::0;;::::1;::::0;;67675:15;;::::1;::::0;67653:68;;;67692:13;;-1:-1:-1;;;;;67653:68:0;;::::1;;::::0;;::::1;::::0;;;67715:4:::1;67653:68:::0;;;;;;67771:28;;;;::::1;12377:32:1::0;;;;12438:24;;12538:21;;12516:20;;;12509:51;;;;12602:24;;12598:33;12576:20;;;12569:63;67653:68:0;-1:-1:-1;;12350:18:1;;67771:28:0::1;;;;;;;;;;;;67761:39;;;;;;67736:64;;67815:24;67842:41;67865:7;:17;;;67842:14;:22;;:41;;;;:::i;:::-;67926:13;::::0;67815:68;;-1:-1:-1;;;;;;67906:33:0;;::::1;67926:13;::::0;;::::1;;67906:33;67898:55;;;::::0;-1:-1:-1;;;67898:55:0;;12845:2:1;67898:55:0::1;::::0;::::1;12827:21:1::0;12884:1;12864:18;;;12857:29;-1:-1:-1;;;12902:18:1;;;12895:39;12951:18;;67898:55:0::1;12643:332:1::0;67898:55:0::1;67968:38;67978:10;67990:7;:15;;;67968:9;:38::i;:::-;67247:771;;;;67242:3;;;;;:::i;:::-;;;;67204:814;;45866:336:::0;46061:41;14629:10;46094:7;46061:18;:41::i;:::-;46053:100;;;;-1:-1:-1;;;46053:100:0;;;;;;;:::i;:::-;46166:28;46176:4;46182:2;46186:7;46166:9;:28::i;69246:199::-;69333:16;;69387:7;69430:5;69397:30;;69410:17;69397:30;:10;:30;:::i;:::-;:38;;;;:::i;:::-;69379:58;;;;69246:199;;;;;;:::o;57227:256::-;57324:7;57360:23;57377:5;57360:16;:23::i;:::-;57352:5;:31;57344:87;;;;-1:-1:-1;;;57344:87:0;;14233:2:1;57344:87:0;;;14215:21:1;14272:2;14252:18;;;14245:30;14311:34;14291:18;;;14284:62;-1:-1:-1;;;14362:18:1;;;14355:41;14413:19;;57344:87:0;14031:407:1;57344:87:0;-1:-1:-1;;;;;;57449:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;57227:256::o;64968:344::-;21622:19;:17;:19::i;:::-;20263:30:::1;20282:10;20263:18;:30::i;:::-;20255:64;;;::::0;-1:-1:-1;;;20255:64:0;;14645:2:1;20255:64:0::1;::::0;::::1;14627:21:1::0;14684:2;14664:18;;;14657:30;-1:-1:-1;;;14703:18:1;;;14696:51;14764:18;;20255:64:0::1;14443:345:1::0;20255:64:0::1;-1:-1:-1::0;;;;;65116:28:0;::::2;65108:53;;;::::0;-1:-1:-1;;;65108:53:0;;14995:2:1;65108:53:0::2;::::0;::::2;14977:21:1::0;15034:2;15014:18;;;15007:30;-1:-1:-1;;;15053:18:1;;;15046:42;15105:18;;65108:53:0::2;14793:336:1::0;65108:53:0::2;65172:13;:30:::0;;-1:-1:-1;;;;;;65213:46:0;65172:30:::2;-1:-1:-1::0;;;;;65172:30:0;;::::2;::::0;::::2;-1:-1:-1::0;;;;65213:46:0;;;;;-1:-1:-1;;;65213:46:0;::::2;;;;::::0;;;;65275:29:::2;::::0;65290:13;::::2;;738:51:1::0;;65275:29:0::2;::::0;726:2:1;711:18;65275:29:0::2;;;;;;;64968:344:::0;;:::o;69524:67::-;15884:13;:11;:13::i;:::-;69573:10:::1;:8;:10::i;:::-;69524:67::o:0;46273:185::-;46411:39;46428:4;46434:2;46438:7;46411:39;;;;;;;;;;;;:16;:39::i;57749:233::-;57824:7;57860:30;57647:10;:17;;57559:113;57860:30;57852:5;:38;57844:95;;;;-1:-1:-1;;;57844:95:0;;15336:2:1;57844:95:0;;;15318:21:1;15375:2;15355:18;;;15348:30;15414:34;15394:18;;;15387:62;-1:-1:-1;;;15465:18:1;;;15458:42;15517:19;;57844:95:0;15134:408:1;57844:95:0;57957:10;57968:5;57957:17;;;;;;;;:::i;:::-;;;;;;;;;57950:24;;57749:233;;;:::o;66624:175::-;15884:13;:11;:13::i;:::-;21622:19:::1;:17;:19::i;:::-;66723:11:::2;::::0;-1:-1:-1;;;66723:11:0;::::2;;;:20;66715:44;;;::::0;-1:-1:-1;;;66715:44:0;;15749:2:1;66715:44:0::2;::::0;::::2;15731:21:1::0;15788:2;15768:18;;;15761:30;-1:-1:-1;;;15807:18:1;;;15800:41;15858:18;;66715:44:0::2;15547:335:1::0;66715:44:0::2;66770:21:::0;;::::2;::::0;:7:::2;::::0;:21:::2;::::0;::::2;::::0;::::2;:::i;:::-;;66624:175:::0;:::o;43364:222::-;43436:7;43472:16;;;:7;:16;;;;;;-1:-1:-1;;;;;43472:16:0;43507:19;43499:56;;;;-1:-1:-1;;;43499:56:0;;16089:2:1;43499:56:0;;;16071:21:1;16128:2;16108:18;;;16101:30;-1:-1:-1;;;16147:18:1;;;16140:54;16211:18;;43499:56:0;15887:348:1;63591:21:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;43095:207::-;43167:7;-1:-1:-1;;;;;43195:19:0;;43187:73;;;;-1:-1:-1;;;43187:73:0;;16442:2:1;43187:73:0;;;16424:21:1;16481:2;16461:18;;;16454:30;16520:34;16500:18;;;16493:62;-1:-1:-1;;;16571:18:1;;;16564:39;16620:19;;43187:73:0;16240:405:1;43187:73:0;-1:-1:-1;;;;;;43278:16:0;;;;;:9;:16;;;;;;;43095:207::o;16646:103::-;15884:13;:11;:13::i;:::-;16711:30:::1;16738:1;16711:18;:30::i;18737:175::-:0;16071:6;;-1:-1:-1;;;;;16071:6:0;14629:10;18003:23;;:51;;-1:-1:-1;18030:8:0;;-1:-1:-1;;;;;18030:8:0;14629:10;18030:24;18003:51;17995:76;;;;-1:-1:-1;;;17995:76:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;18825:25:0;::::1;;::::0;;;:12:::1;:25;::::0;;;;;;;18818:32;;;18866:38;;17159:51:1;;;17226:18;;;17219:50;;;;18866:38:0::1;::::0;17132:18:1;18866:38:0::1;;;;;;;;18737:175:::0;:::o;69453:63::-;15884:13;:11;:13::i;:::-;69500:8:::1;:6;:8::i;66807:81::-:0;15884:13;:11;:13::i;:::-;66862:11:::1;:18:::0;;-1:-1:-1;;;;66862:18:0::1;-1:-1:-1::0;;;66862:18:0::1;::::0;;66807:81::o;18099:148::-;15884:13;:11;:13::i;:::-;18169:8:::1;:20:::0;;-1:-1:-1;;;;;;18169:20:0::1;-1:-1:-1::0;;;;;18169:20:0;::::1;::::0;;::::1;::::0;;;18205:34:::1;::::0;738:51:1;;;18205:34:0::1;::::0;726:2:1;711:18;18205:34:0::1;592:203:1::0;43822:104:0;43878:13;43911:7;43904:14;;;;;:::i;45409:155::-;45504:52;14629:10;45537:8;45547;45504:18;:52::i;19426:195::-;16071:6;;-1:-1:-1;;;;;16071:6:0;14629:10;18003:23;;:51;;-1:-1:-1;18030:8:0;;-1:-1:-1;;;;;18030:8:0;14629:10;18030:24;18003:51;17995:76;;;;-1:-1:-1;;;17995:76:0;;;;;;;:::i;:::-;19523:20:::1;::::0;-1:-1:-1;;;19523:20:0;::::1;;;:28;;19547:4;19523:28;19515:49;;;::::0;-1:-1:-1;;;19515:49:0;;17482:2:1;19515:49:0::1;::::0;::::1;17464:21:1::0;17521:1;17501:18;;;17494:29;-1:-1:-1;;;17539:18:1;;;17532:38;17587:18;;19515:49:0::1;17280:331:1::0;19515:49:0::1;19575:38;19601:11;19575:25;:38::i;:::-;19426:195:::0;:::o;19629:98::-;16071:6;;-1:-1:-1;;;;;16071:6:0;14629:10;18003:23;;:51;;-1:-1:-1;18030:8:0;;-1:-1:-1;;;;;18030:8:0;14629:10;18030:24;18003:51;17995:76;;;;-1:-1:-1;;;17995:76:0;;;;;;;:::i;:::-;19691:20:::1;:28:::0;;-1:-1:-1;;;;19691:28:0::1;::::0;;19629:98::o;46529:323::-;46703:41;14629:10;46736:7;46703:18;:41::i;:::-;46695:100;;;;-1:-1:-1;;;46695:100:0;;;;;;;:::i;:::-;46806:38;46820:4;46826:2;46830:7;46839:4;46806:13;:38::i;:::-;46529:323;;;;:::o;43997:281::-;44070:13;44096:23;44111:7;44096:14;:23::i;:::-;44132:21;44156:10;:8;:10::i;:::-;44132:34;;44208:1;44190:7;44184:21;:25;:86;;;;;;;;;;;;;;;;;44236:7;44245:18;:7;:16;:18::i;:::-;44219:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;44184:86;44177:93;43997:281;-1:-1:-1;;;43997:281:0:o;18355:312::-;16071:6;;-1:-1:-1;;;;;16071:6:0;14629:10;18003:23;;:51;;-1:-1:-1;18030:8:0;;-1:-1:-1;;;;;18030:8:0;14629:10;18030:24;18003:51;17995:76;;;;-1:-1:-1;;;17995:76:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;18441:25:0;::::1;18433:52;;;::::0;-1:-1:-1;;;18433:52:0;;18293:2:1;18433:52:0::1;::::0;::::1;18275:21:1::0;18332:2;18312:18;;;18305:30;-1:-1:-1;;;18351:18:1;;;18344:44;18405:18;;18433:52:0::1;18091:338:1::0;18433:52:0::1;-1:-1:-1::0;;;;;18504:25:0;::::1;;::::0;;;:12:::1;:25;::::0;;;;;:30;18496:56:::1;;;::::0;-1:-1:-1;;;18496:56:0;;18636:2:1;18496:56:0::1;::::0;::::1;18618:21:1::0;18675:2;18655:18;;;18648:30;-1:-1:-1;;;18694:18:1;;;18687:43;18747:18;;18496:56:0::1;18434:337:1::0;18496:56:0::1;-1:-1:-1::0;;;;;18563:25:0;::::1;;::::0;;;:12:::1;:25;::::0;;;;;;;;18591:15:::1;18563:43:::0;;18622:37;;17159:51:1;;;18654:4:0::1;17226:18:1::0;;;17219:50;18622:37:0::1;::::0;17132:18:1;18622:37:0::1;16991:284:1::0;68033:426:0;20263:30;20282:10;20263:18;:30::i;:::-;20255:64;;;;-1:-1:-1;;;20255:64:0;;14645:2:1;20255:64:0;;;14627:21:1;14684:2;14664:18;;;14657:30;-1:-1:-1;;;14703:18:1;;;14696:51;14764:18;;20255:64:0;14443:345:1;20255:64:0;68133:8:::1;68128:324;68145:19;::::0;::::1;::::0;-1:-1:-1;68128:324:0::1;;;68186:31;68220:8;;68229:1;68220:11;;;;;;;;;:::i;:::-;;;;;;68186:45;;;;;;;;;;:::i;:::-;;;68254:24;68262:7;:15;;;48424:4:::0;48448:16;;;:7;:16;;;;;;-1:-1:-1;;;;;48448:16:0;:30;;;48359:127;68254:24:::1;:33;68246:58;;;::::0;-1:-1:-1;;;68246:58:0;;11065:2:1;68246:58:0::1;::::0;::::1;11047:21:1::0;11104:2;11084:18;;;11077:30;-1:-1:-1;;;11123:18:1;;;11116:42;11175:18;;68246:58:0::1;10863:336:1::0;68246:58:0::1;68348:16;68327:13;57647:10:::0;:17;;57559:113;68327:13:::1;:17;::::0;68343:1:::1;68327:17;:::i;:::-;:37;;68319:65;;;::::0;-1:-1:-1;;;68319:65:0;;12011:2:1;68319:65:0::1;::::0;::::1;11993:21:1::0;12050:2;12030:18;;;12023:30;-1:-1:-1;;;12069:18:1;;;12062:45;12124:18;;68319:65:0::1;11809:339:1::0;68319:65:0::1;68399:41;68409:7;:13;;;68424:7;:15;;;68399:9;:41::i;:::-;-1:-1:-1::0;68166:3:0;::::1;::::0;::::1;:::i;:::-;;;;68128:324;;68670:345:::0;69164:20;;68781:4;;-1:-1:-1;;;;;69164:20:0;69148:70;;;;-1:-1:-1;;;69148:70:0;;19502:2:1;69148:70:0;;;19484:21:1;19541:2;19521:18;;;19514:30;-1:-1:-1;;;19560:18:1;;;19553:44;19614:18;;69148:70:0;19300:338:1;69148:70:0;68802:20:::1;::::0;:77:::1;::::0;-1:-1:-1;;;68802:77:0;;-1:-1:-1;;;;;19873:15:1;;;68802:77:0::1;::::0;::::1;19855:34:1::0;19925:15;;;19905:18;;;19898:43;68802:20:0;;::::1;::::0;:58:::1;::::0;19790:18:1;;68802:77:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:85;;68883:4;68802:85;68798:210;;;-1:-1:-1::0;68911:4:0::1;68904:11;;68798:210;-1:-1:-1::0;;;;;;45756:25:0;;;45732:4;45756:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;68948:48:::1;;16904:201:::0;15884:13;:11;:13::i;:::-;-1:-1:-1;;;;;16993:22:0;::::1;16985:73;;;::::0;-1:-1:-1;;;16985:73:0;;20404:2:1;16985:73:0::1;::::0;::::1;20386:21:1::0;20443:2;20423:18;;;20416:30;20482:34;20462:18;;;20455:62;-1:-1:-1;;;20533:18:1;;;20526:36;20579:19;;16985:73:0::1;20202:402:1::0;16985:73:0::1;17069:28;17088:8;17069:18;:28::i;19837:277::-:0;-1:-1:-1;;;;;19944:25:0;;19907:4;19944:25;;;:12;:25;;;;;;19984:14;19980:59;;-1:-1:-1;20022:5:0;;19837:277;-1:-1:-1;;19837:277:0:o;19980:59::-;17639:6;20056:27;20074:9;20056:15;:27;:::i;:::-;:50;;19837:277;-1:-1:-1;;;19837:277:0:o;42726:305::-;42828:4;-1:-1:-1;;;;;;42865:40:0;;-1:-1:-1;;;42865:40:0;;:105;;-1:-1:-1;;;;;;;42922:48:0;;-1:-1:-1;;;42922:48:0;42865:105;:158;;;-1:-1:-1;;;;;;;;;;34497:40:0;;;42987:36;34388:157;53141:135;48424:4;48448:16;;;:7;:16;;;;;;-1:-1:-1;;;;;48448:16:0;53215:53;;;;-1:-1:-1;;;53215:53:0;;16089:2:1;53215:53:0;;;16071:21:1;16128:2;16108:18;;;16101:30;-1:-1:-1;;;16147:18:1;;;16140:54;16211:18;;53215:53:0;15887:348:1;52420:174:0;52495:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;52495:29:0;-1:-1:-1;;;;;52495:29:0;;;;;;;;:24;;52549:23;52495:24;52549:14;:23::i;:::-;-1:-1:-1;;;;;52540:46:0;;;;;;;;;;;52420:174;;:::o;22176:108::-;22088:7;;;;22246:9;22238:38;;;;-1:-1:-1;;;22238:38:0;;20941:2:1;22238:38:0;;;20923:21:1;20980:2;20960:18;;;20953:30;-1:-1:-1;;;20999:18:1;;;20992:46;21055:18;;22238:38:0;20739:340:1;8753:231:0;8831:7;8852:17;8871:18;8893:27;8904:4;8910:9;8893:10;:27::i;:::-;8851:69;;;;8931:18;8943:5;8931:11;:18::i;:::-;-1:-1:-1;8967:9:0;8753:231;-1:-1:-1;;;8753:231:0:o;49259:110::-;49335:26;49345:2;49349:7;49335:26;;;;;;;;;;;;:9;:26::i;48653:264::-;48746:4;48763:13;48779:23;48794:7;48779:14;:23::i;:::-;48763:39;;48832:5;-1:-1:-1;;;;;48821:16:0;:7;-1:-1:-1;;;;;48821:16:0;;:52;;;;48841:32;48858:5;48865:7;48841:16;:32::i;:::-;48821:87;;;;48901:7;-1:-1:-1;;;;;48877:31:0;:20;48889:7;48877:11;:20::i;:::-;-1:-1:-1;;;;;48877:31:0;;48821:87;48813:96;48653:264;-1:-1:-1;;;;48653:264:0:o;51676:625::-;51835:4;-1:-1:-1;;;;;51808:31:0;:23;51823:7;51808:14;:23::i;:::-;-1:-1:-1;;;;;51808:31:0;;51800:81;;;;-1:-1:-1;;;51800:81:0;;21286:2:1;51800:81:0;;;21268:21:1;21325:2;21305:18;;;21298:30;21364:34;21344:18;;;21337:62;-1:-1:-1;;;21415:18:1;;;21408:35;21460:19;;51800:81:0;21084:401:1;51800:81:0;-1:-1:-1;;;;;51900:16:0;;51892:65;;;;-1:-1:-1;;;51892:65:0;;21692:2:1;51892:65:0;;;21674:21:1;21731:2;21711:18;;;21704:30;21770:34;21750:18;;;21743:62;-1:-1:-1;;;21821:18:1;;;21814:34;21865:19;;51892:65:0;21490:400:1;51892:65:0;51970:39;51991:4;51997:2;52001:7;51970:20;:39::i;:::-;52074:29;52091:1;52095:7;52074:8;:29::i;:::-;-1:-1:-1;;;;;52116:15:0;;;;;;:9;:15;;;;;:20;;52135:1;;52116:15;:20;;52135:1;;52116:20;:::i;:::-;;;;-1:-1:-1;;;;;;;52147:13:0;;;;;;:9;:13;;;;;:18;;52164:1;;52147:13;:18;;52164:1;;52147:18;:::i;:::-;;;;-1:-1:-1;;52176:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;52176:21:0;-1:-1:-1;;;;;52176:21:0;;;;;;;;;52215:27;;52176:16;;52215:27;;;;;;;44753:347;44683:417;;:::o;16163:132::-;16071:6;;-1:-1:-1;;;;;16071:6:0;14629:10;16227:23;16219:68;;;;-1:-1:-1;;;16219:68:0;;22097:2:1;16219:68:0;;;22079:21:1;;;22116:18;;;22109:30;22175:34;22155:18;;;22148:62;22227:18;;16219:68:0;21895:356:1;22872:120:0;21881:16;:14;:16::i;:::-;22931:7:::1;:15:::0;;-1:-1:-1;;22931:15:0::1;::::0;;22962:22:::1;14629:10:::0;22971:12:::1;22962:22;::::0;-1:-1:-1;;;;;756:32:1;;;738:51;;726:2;711:18;22962:22:0::1;;;;;;;22872:120::o:0;17265:191::-;17358:6;;;-1:-1:-1;;;;;17375:17:0;;;-1:-1:-1;;;;;;17375:17:0;;;;;;;17408:40;;17358:6;;;17375:17;17358:6;;17408:40;;17339:16;;17408:40;17328:128;17265:191;:::o;22613:118::-;21622:19;:17;:19::i;:::-;22673:7:::1;:14:::0;;-1:-1:-1;;22673:14:0::1;22683:4;22673:14;::::0;;22703:20:::1;22710:12;14629:10:::0;;14549:98;52737:315;52892:8;-1:-1:-1;;;;;52883:17:0;:5;-1:-1:-1;;;;;52883:17:0;;;52875:55;;;;-1:-1:-1;;;52875:55:0;;22458:2:1;52875:55:0;;;22440:21:1;22497:2;22477:18;;;22470:30;22536:27;22516:18;;;22509:55;22581:18;;52875:55:0;22256:349:1;52875:55:0;-1:-1:-1;;;;;52941:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;52941:46:0;;;;;;;;;;53003:41;;540::1;;;53003::0;;513:18:1;53003:41:0;;;;;;;52737:315;;;:::o;19066:352::-;15884:13;:11;:13::i;:::-;-1:-1:-1;;;;;19160:25:0;::::1;19152:45;;;::::0;-1:-1:-1;;;19152:45:0;;22812:2:1;19152:45:0::1;::::0;::::1;22794:21:1::0;22851:1;22831:18;;;22824:29;-1:-1:-1;;;22869:18:1;;;22862:37;22916:18;;19152:45:0::1;22610:330:1::0;19152:45:0::1;19356:1;19315:38;17639:6;19315:15;:38;:::i;:::-;:42;;;;:::i;:::-;-1:-1:-1::0;;;;;19287:25:0;::::1;;::::0;;;:12:::1;:25;::::0;;;;;;;;:70;;;;19373:37;;17159:51:1;;;19405:4:0::1;17226:18:1::0;;;17219:50;;;;19373:37:0::1;::::0;17132:18:1;19373:37:0::1;16991:284:1::0;47733:313:0;47889:28;47899:4;47905:2;47909:7;47889:9;:28::i;:::-;47936:47;47959:4;47965:2;47969:7;47978:4;47936:22;:47::i;:::-;47928:110;;;;-1:-1:-1;;;47928:110:0;;;;;;;:::i;66387:100::-;66439:13;66472:7;66465:14;;;;;:::i;2173:723::-;2229:13;2450:10;2446:53;;-1:-1:-1;;2477:10:0;;;;;;;;;;;;-1:-1:-1;;;2477:10:0;;;;;2173:723::o;2446:53::-;2524:5;2509:12;2565:78;2572:9;;2565:78;;2598:8;;;;:::i;:::-;;-1:-1:-1;2621:10:0;;-1:-1:-1;2629:2:0;2621:10;;:::i;:::-;;;2565:78;;;2653:19;2685:6;2675:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2675:17:0;;2653:39;;2703:154;2710:10;;2703:154;;2737:11;2747:1;2737:11;;:::i;:::-;;-1:-1:-1;2806:10:0;2814:2;2806:5;:10;:::i;:::-;2793:24;;:2;:24;:::i;:::-;2780:39;;2763:6;2770;2763:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;2763:56:0;;;;;;;;-1:-1:-1;2834:11:0;2843:2;2834:11;;:::i;:::-;;;2703:154;;6547:1404;6628:7;6637:12;6862:9;:16;6882:2;6862:22;6858:1086;;;7206:4;7191:20;;7185:27;7256:4;7241:20;;7235:27;7314:4;7299:20;;7293:27;6901:9;7285:36;7357:25;7368:4;7285:36;7185:27;7235;7357:10;:25::i;:::-;7350:32;;;;;;;;;6858:1086;7404:9;:16;7424:2;7404:22;7400:544;;;7727:4;7712:20;;7706:27;7778:4;7763:20;;7757:27;7820:23;7831:4;7706:27;7757;7820:10;:23::i;:::-;7813:30;;;;;;;;7400:544;-1:-1:-1;7892:1:0;;-1:-1:-1;7896:35:0;7876:56;;4818:643;4896:20;4887:5;:29;;;;;;;;:::i;:::-;;4883:571;;;4818:643;:::o;4883:571::-;4994:29;4985:5;:38;;;;;;;;:::i;:::-;;4981:473;;;5040:34;;-1:-1:-1;;;5040:34:0;;23955:2:1;5040:34:0;;;23937:21:1;23994:2;23974:18;;;23967:30;24033:26;24013:18;;;24006:54;24077:18;;5040:34:0;23753:348:1;4981:473:0;5105:35;5096:5;:44;;;;;;;;:::i;:::-;;5092:362;;;5157:41;;-1:-1:-1;;;5157:41:0;;24308:2:1;5157:41:0;;;24290:21:1;24347:2;24327:18;;;24320:30;24386:33;24366:18;;;24359:61;24437:18;;5157:41:0;24106:355:1;5092:362:0;5229:30;5220:5;:39;;;;;;;;:::i;:::-;;5216:238;;;5276:44;;-1:-1:-1;;;5276:44:0;;24668:2:1;5276:44:0;;;24650:21:1;24707:2;24687:18;;;24680:30;24746:34;24726:18;;;24719:62;-1:-1:-1;;;24797:18:1;;;24790:32;24839:19;;5276:44:0;24466:398:1;5216:238:0;5351:30;5342:5;:39;;;;;;;;:::i;:::-;;5338:116;;;5398:44;;-1:-1:-1;;;5398:44:0;;25071:2:1;5398:44:0;;;25053:21:1;25110:2;25090:18;;;25083:30;25149:34;25129:18;;;25122:62;-1:-1:-1;;;25200:18:1;;;25193:32;25242:19;;5398:44:0;24869:398:1;49596:319:0;49725:18;49731:2;49735:7;49725:5;:18::i;:::-;49776:53;49807:1;49811:2;49815:7;49824:4;49776:22;:53::i;:::-;49754:153;;;;-1:-1:-1;;;49754:153:0;;;;;;;:::i;58595:589::-;-1:-1:-1;;;;;58801:18:0;;58797:187;;58836:40;58868:7;60011:10;:17;;59984:24;;;;:15;:24;;;;;:44;;;60039:24;;;;;;;;;;;;59907:164;58836:40;58797:187;;;58906:2;-1:-1:-1;;;;;58898:10:0;:4;-1:-1:-1;;;;;58898:10:0;;58894:90;;58925:47;58958:4;58964:7;58925:32;:47::i;:::-;-1:-1:-1;;;;;58998:16:0;;58994:183;;59031:45;59068:7;59031:36;:45::i;58994:183::-;59104:4;-1:-1:-1;;;;;59098:10:0;:2;-1:-1:-1;;;;;59098:10:0;;59094:83;;59125:40;59153:2;59157:7;59125:27;:40::i;22361:108::-;22088:7;;;;22420:41;;;;-1:-1:-1;;;22420:41:0;;25474:2:1;22420:41:0;;;25456:21:1;25513:2;25493:18;;;25486:30;-1:-1:-1;;;25532:18:1;;;25525:50;25592:18;;22420:41:0;25272:344:1;53840:853:0;53994:4;-1:-1:-1;;;;;54015:13:0;;24527:19;:23;54011:675;;54051:71;;-1:-1:-1;;;54051:71:0;;-1:-1:-1;;;;;54051:36:0;;;;;:71;;14629:10;;54102:4;;54108:7;;54117:4;;54051:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54051:71:0;;;;;;;;-1:-1:-1;;54051:71:0;;;;;;;;;;;;:::i;:::-;;;54047:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54292:13:0;;54288:328;;54335:60;;-1:-1:-1;;;54335:60:0;;;;;;;:::i;54288:328::-;54566:6;54560:13;54551:6;54547:2;54543:15;54536:38;54047:584;-1:-1:-1;;;;;;54173:51:0;-1:-1:-1;;;54173:51:0;;-1:-1:-1;54166:58:0;;54011:675;-1:-1:-1;54670:4:0;53840:853;;;;;;:::o;10205:1632::-;10336:7;;11270:66;11257:79;;11253:163;;;-1:-1:-1;11369:1:0;;-1:-1:-1;11373:30:0;11353:51;;11253:163;11430:1;:7;;11435:2;11430:7;;:18;;;;;11441:1;:7;;11446:2;11441:7;;11430:18;11426:102;;;-1:-1:-1;11481:1:0;;-1:-1:-1;11485:30:0;11465:51;;11426:102;11642:24;;;11625:14;11642:24;;;;;;;;;26596:25:1;;;26669:4;26657:17;;26637:18;;;26630:45;;;;26691:18;;;26684:34;;;26734:18;;;26727:34;;;11642:24:0;;26568:19:1;;11642:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;11642:24:0;;-1:-1:-1;;11642:24:0;;;-1:-1:-1;;;;;;;11681:20:0;;11677:103;;11734:1;11738:29;11718:50;;;;;;;11677:103;11800:6;-1:-1:-1;11808:20:0;;-1:-1:-1;10205:1632:0;;;;;;;;:::o;9247:344::-;9361:7;;-1:-1:-1;;;;;9407:80:0;;9361:7;9514:25;9530:3;9515:18;;;9537:2;9514:25;:::i;:::-;9498:42;;9558:25;9569:4;9575:1;9578;9581;9558:10;:25::i;:::-;9551:32;;;;;;9247:344;;;;;;:::o;50251:439::-;-1:-1:-1;;;;;50331:16:0;;50323:61;;;;-1:-1:-1;;;50323:61:0;;26974:2:1;50323:61:0;;;26956:21:1;;;26993:18;;;26986:30;27052:34;27032:18;;;27025:62;27104:18;;50323:61:0;26772:356:1;50323:61:0;48424:4;48448:16;;;:7;:16;;;;;;-1:-1:-1;;;;;48448:16:0;:30;50395:58;;;;-1:-1:-1;;;50395:58:0;;27335:2:1;50395:58:0;;;27317:21:1;27374:2;27354:18;;;27347:30;27413;27393:18;;;27386:58;27461:18;;50395:58:0;27133:352:1;50395:58:0;50466:45;50495:1;50499:2;50503:7;50466:20;:45::i;:::-;-1:-1:-1;;;;;50524:13:0;;;;;;:9;:13;;;;;:18;;50541:1;;50524:13;:18;;50541:1;;50524:18;:::i;:::-;;;;-1:-1:-1;;50553:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;50553:21:0;-1:-1:-1;;;;;50553:21:0;;;;;;;;50592:33;;50553:16;;;50592:33;;50553:16;;50592:33;66770:21:::2;66624:175:::0;:::o;60698:988::-;60964:22;61014:1;60989:22;61006:4;60989:16;:22::i;:::-;:26;;;;:::i;:::-;61026:18;61047:26;;;:17;:26;;;;;;60964:51;;-1:-1:-1;61180:28:0;;;61176:328;;-1:-1:-1;;;;;61247:18:0;;61225:19;61247:18;;;:12;:18;;;;;;;;:34;;;;;;;;;61298:30;;;;;;:44;;;61415:30;;:17;:30;;;;;:43;;;61176:328;-1:-1:-1;61600:26:0;;;;:17;:26;;;;;;;;61593:33;;;-1:-1:-1;;;;;61644:18:0;;;;;:12;:18;;;;;:34;;;;;;;61637:41;60698:988::o;61981:1079::-;62259:10;:17;62234:22;;62259:21;;62279:1;;62259:21;:::i;:::-;62291:18;62312:24;;;:15;:24;;;;;;62685:10;:26;;62234:46;;-1:-1:-1;62312:24:0;;62234:46;;62685:26;;;;;;:::i;:::-;;;;;;;;;62663:48;;62749:11;62724:10;62735;62724:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;62829:28;;;:15;:28;;;;;;;:41;;;63001:24;;;;;62994:31;63036:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;62052:1008;;;61981:1079;:::o;59485:221::-;59570:14;59587:20;59604:2;59587:16;:20::i;:::-;-1:-1:-1;;;;;59618:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;59663:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;59485:221:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;800:258::-;872:1;882:113;896:6;893:1;890:13;882:113;;;972:11;;;966:18;953:11;;;946:39;918:2;911:10;882:113;;;1013:6;1010:1;1007:13;1004:48;;;-1:-1:-1;;1048:1:1;1030:16;;1023:27;800:258::o;1063:::-;1105:3;1143:5;1137:12;1170:6;1165:3;1158:19;1186:63;1242:6;1235:4;1230:3;1226:14;1219:4;1212:5;1208:16;1186:63;:::i;:::-;1303:2;1282:15;-1:-1:-1;;1278:29:1;1269:39;;;;1310:4;1265:50;;1063:258;-1:-1:-1;;1063:258:1:o;1326:220::-;1475:2;1464:9;1457:21;1438:4;1495:45;1536:2;1525:9;1521:18;1513:6;1495:45;:::i;1551:180::-;1610:6;1663:2;1651:9;1642:7;1638:23;1634:32;1631:52;;;1679:1;1676;1669:12;1631:52;-1:-1:-1;1702:23:1;;1551:180;-1:-1:-1;1551:180:1:o;1736:173::-;1804:20;;-1:-1:-1;;;;;1853:31:1;;1843:42;;1833:70;;1899:1;1896;1889:12;1833:70;1736:173;;;:::o;1914:254::-;1982:6;1990;2043:2;2031:9;2022:7;2018:23;2014:32;2011:52;;;2059:1;2056;2049:12;2011:52;2082:29;2101:9;2082:29;:::i;:::-;2072:39;2158:2;2143:18;;;;2130:32;;-1:-1:-1;;;1914:254:1:o;2355:186::-;2414:6;2467:2;2455:9;2446:7;2442:23;2438:32;2435:52;;;2483:1;2480;2473:12;2435:52;2506:29;2525:9;2506:29;:::i;2546:656::-;2673:6;2681;2734:2;2722:9;2713:7;2709:23;2705:32;2702:52;;;2750:1;2747;2740:12;2702:52;2790:9;2777:23;2819:18;2860:2;2852:6;2849:14;2846:34;;;2876:1;2873;2866:12;2846:34;2914:6;2903:9;2899:22;2889:32;;2959:7;2952:4;2948:2;2944:13;2940:27;2930:55;;2981:1;2978;2971:12;2930:55;3021:2;3008:16;3047:2;3039:6;3036:14;3033:34;;;3063:1;3060;3053:12;3033:34;3116:7;3111:2;3101:6;3098:1;3094:14;3090:2;3086:23;3082:32;3079:45;3076:65;;;3137:1;3134;3127:12;3076:65;3168:2;3160:11;;;;;3190:6;;-1:-1:-1;2546:656:1;;-1:-1:-1;;;;2546:656:1:o;3207:328::-;3284:6;3292;3300;3353:2;3341:9;3332:7;3328:23;3324:32;3321:52;;;3369:1;3366;3359:12;3321:52;3392:29;3411:9;3392:29;:::i;:::-;3382:39;;3440:38;3474:2;3463:9;3459:18;3440:38;:::i;:::-;3430:48;;3525:2;3514:9;3510:18;3497:32;3487:42;;3207:328;;;;;:::o;3540:248::-;3608:6;3616;3669:2;3657:9;3648:7;3644:23;3640:32;3637:52;;;3685:1;3682;3675:12;3637:52;-1:-1:-1;;3708:23:1;;;3778:2;3763:18;;;3750:32;;-1:-1:-1;3540:248:1:o;4072:118::-;4158:5;4151:13;4144:21;4137:5;4134:32;4124:60;;4180:1;4177;4170:12;4195:315;4260:6;4268;4321:2;4309:9;4300:7;4296:23;4292:32;4289:52;;;4337:1;4334;4327:12;4289:52;4360:29;4379:9;4360:29;:::i;:::-;4350:39;;4439:2;4428:9;4424:18;4411:32;4452:28;4474:5;4452:28;:::i;:::-;4499:5;4489:15;;;4195:315;;;;;:::o;4515:127::-;4576:10;4571:3;4567:20;4564:1;4557:31;4607:4;4604:1;4597:15;4631:4;4628:1;4621:15;4647:632;4712:5;4742:18;4783:2;4775:6;4772:14;4769:40;;;4789:18;;:::i;:::-;4864:2;4858:9;4832:2;4918:15;;-1:-1:-1;;4914:24:1;;;4940:2;4910:33;4906:42;4894:55;;;4964:18;;;4984:22;;;4961:46;4958:72;;;5010:18;;:::i;:::-;5050:10;5046:2;5039:22;5079:6;5070:15;;5109:6;5101;5094:22;5149:3;5140:6;5135:3;5131:16;5128:25;5125:45;;;5166:1;5163;5156:12;5125:45;5216:6;5211:3;5204:4;5196:6;5192:17;5179:44;5271:1;5264:4;5255:6;5247;5243:19;5239:30;5232:41;;;;4647:632;;;;;:::o;5284:451::-;5353:6;5406:2;5394:9;5385:7;5381:23;5377:32;5374:52;;;5422:1;5419;5412:12;5374:52;5462:9;5449:23;5495:18;5487:6;5484:30;5481:50;;;5527:1;5524;5517:12;5481:50;5550:22;;5603:4;5595:13;;5591:27;-1:-1:-1;5581:55:1;;5632:1;5629;5622:12;5581:55;5655:74;5721:7;5716:2;5703:16;5698:2;5694;5690:11;5655:74;:::i;6180:221::-;6222:5;6275:3;6268:4;6260:6;6256:17;6252:27;6242:55;;6293:1;6290;6283:12;6242:55;6315:80;6391:3;6382:6;6369:20;6362:4;6354:6;6350:17;6315:80;:::i;6406:537::-;6501:6;6509;6517;6525;6578:3;6566:9;6557:7;6553:23;6549:33;6546:53;;;6595:1;6592;6585:12;6546:53;6618:29;6637:9;6618:29;:::i;:::-;6608:39;;6666:38;6700:2;6689:9;6685:18;6666:38;:::i;:::-;6656:48;;6751:2;6740:9;6736:18;6723:32;6713:42;;6806:2;6795:9;6791:18;6778:32;6833:18;6825:6;6822:30;6819:50;;;6865:1;6862;6855:12;6819:50;6888:49;6929:7;6920:6;6909:9;6905:22;6888:49;:::i;:::-;6878:59;;;6406:537;;;;;;;:::o;6948:651::-;7070:6;7078;7131:2;7119:9;7110:7;7106:23;7102:32;7099:52;;;7147:1;7144;7137:12;7099:52;7187:9;7174:23;7216:18;7257:2;7249:6;7246:14;7243:34;;;7273:1;7270;7263:12;7243:34;7311:6;7300:9;7296:22;7286:32;;7356:7;7349:4;7345:2;7341:13;7337:27;7327:55;;7378:1;7375;7368:12;7327:55;7418:2;7405:16;7444:2;7436:6;7433:14;7430:34;;;7460:1;7457;7450:12;7430:34;7513:7;7508:2;7498:6;7495:1;7491:14;7487:2;7483:23;7479:32;7476:45;7473:65;;;7534:1;7531;7524:12;7604:260;7672:6;7680;7733:2;7721:9;7712:7;7708:23;7704:32;7701:52;;;7749:1;7746;7739:12;7701:52;7772:29;7791:9;7772:29;:::i;:::-;7762:39;;7820:38;7854:2;7843:9;7839:18;7820:38;:::i;:::-;7810:48;;7604:260;;;;;:::o;8058:380::-;8137:1;8133:12;;;;8180;;;8201:61;;8255:4;8247:6;8243:17;8233:27;;8201:61;8308:2;8300:6;8297:14;8277:18;8274:38;8271:161;;;8354:10;8349:3;8345:20;8342:1;8335:31;8389:4;8386:1;8379:15;8417:4;8414:1;8407:15;8271:161;;8058:380;;;:::o;9621:127::-;9682:10;9677:3;9673:20;9670:1;9663:31;9713:4;9710:1;9703:15;9737:4;9734:1;9727:15;9753:338;9860:4;9918:11;9905:25;10012:2;10008:7;9997:8;9981:14;9977:29;9973:43;9953:18;9949:68;9939:96;;10031:1;10028;10021:12;9939:96;10052:33;;;;;9753:338;-1:-1:-1;;9753:338:1:o;10096:762::-;10226:9;10285:4;10277:5;10261:14;10257:26;10253:37;10250:57;;;10303:1;10300;10293:12;10250:57;10336:2;10330:9;10378:4;10370:6;10366:17;10402:18;10470:6;10458:10;10455:22;10450:2;10438:10;10435:18;10432:46;10429:72;;;10481:18;;:::i;:::-;10521:10;10517:2;10510:22;10556:25;10575:5;10556:25;:::i;:::-;10548:6;10541:41;10629:2;10622:5;10618:14;10605:28;10591:42;;10656:2;10648:6;10645:14;10642:34;;;10672:1;10669;10662:12;10642:34;;10709:52;10746:14;10737:6;10730:5;10726:18;10709:52;:::i;:::-;10704:2;10692:15;;10685:77;-1:-1:-1;10819:2:1;10808:14;;;10795:28;10778:15;;;10771:53;;;;-1:-1:-1;10696:6:1;10096:762::o;11544:127::-;11605:10;11600:3;11596:20;11593:1;11586:31;11636:4;11633:1;11626:15;11660:4;11657:1;11650:15;11676:128;11716:3;11747:1;11743:6;11740:1;11737:13;11734:39;;;11753:18;;:::i;:::-;-1:-1:-1;11789:9:1;;11676:128::o;12980:201::-;13018:3;13046:10;13091:2;13084:5;13080:14;13118:2;13109:7;13106:15;13103:41;;;13124:18;;:::i;:::-;13173:1;13160:15;;12980:201;-1:-1:-1;;;12980:201:1:o;13186:410::-;13388:2;13370:21;;;13427:2;13407:18;;;13400:30;13466:34;13461:2;13446:18;;13439:62;-1:-1:-1;;;13532:2:1;13517:18;;13510:44;13586:3;13571:19;;13186:410::o;13601:168::-;13641:7;13707:1;13703;13699:6;13695:14;13692:1;13689:21;13684:1;13677:9;13670:17;13666:45;13663:71;;;13714:18;;:::i;:::-;-1:-1:-1;13754:9:1;;13601:168::o;13774:127::-;13835:10;13830:3;13826:20;13823:1;13816:31;13866:4;13863:1;13856:15;13890:4;13887:1;13880:15;13906:120;13946:1;13972;13962:35;;13977:18;;:::i;:::-;-1:-1:-1;14011:9:1;;13906:120::o;16650:336::-;16852:2;16834:21;;;16891:2;16871:18;;;16864:30;-1:-1:-1;;;16925:2:1;16910:18;;16903:42;16977:2;16962:18;;16650:336::o;17616:470::-;17795:3;17833:6;17827:13;17849:53;17895:6;17890:3;17883:4;17875:6;17871:17;17849:53;:::i;:::-;17965:13;;17924:16;;;;17987:57;17965:13;17924:16;18021:4;18009:17;;17987:57;:::i;:::-;18060:20;;17616:470;-1:-1:-1;;;;17616:470:1:o;18776:519::-;18869:6;18922:2;18910:9;18901:7;18897:23;18893:32;18890:52;;;18938:1;18935;18928:12;18890:52;18971:2;18965:9;19013:2;19005:6;19001:15;19082:6;19070:10;19067:22;19046:18;19034:10;19031:34;19028:62;19025:88;;;19093:18;;:::i;:::-;19129:2;19122:22;19168:29;19187:9;19168:29;:::i;:::-;19160:6;19153:45;19259:2;19248:9;19244:18;19231:32;19226:2;19218:6;19214:15;19207:57;19283:6;19273:16;;;18776:519;;;;:::o;19952:245::-;20019:6;20072:2;20060:9;20051:7;20047:23;20043:32;20040:52;;;20088:1;20085;20078:12;20040:52;20120:9;20114:16;20139:28;20161:5;20139:28;:::i;20609:125::-;20649:4;20677:1;20674;20671:8;20668:34;;;20682:18;;:::i;:::-;-1:-1:-1;20719:9:1;;20609:125::o;22945:414::-;23147:2;23129:21;;;23186:2;23166:18;;;23159:30;23225:34;23220:2;23205:18;;23198:62;-1:-1:-1;;;23291:2:1;23276:18;;23269:48;23349:3;23334:19;;22945:414::o;23364:135::-;23403:3;-1:-1:-1;;23424:17:1;;23421:43;;;23444:18;;:::i;:::-;-1:-1:-1;23491:1:1;23480:13;;23364:135::o;23504:112::-;23536:1;23562;23552:35;;23567:18;;:::i;:::-;-1:-1:-1;23601:9:1;;23504:112::o;23621:127::-;23682:10;23677:3;23673:20;23670:1;23663:31;23713:4;23710:1;23703:15;23737:4;23734:1;23727:15;25621:489;-1:-1:-1;;;;;25890:15:1;;;25872:34;;25942:15;;25937:2;25922:18;;25915:43;25989:2;25974:18;;25967:34;;;26037:3;26032:2;26017:18;;26010:31;;;25815:4;;26058:46;;26084:19;;26076:6;26058:46;:::i;:::-;26050:54;25621:489;-1:-1:-1;;;;;;25621:489:1:o;26115:249::-;26184:6;26237:2;26225:9;26216:7;26212:23;26208:32;26205:52;;;26253:1;26250;26243:12;26205:52;26285:9;26279:16;26304:30;26328:5;26304:30;:::i;27490:127::-;27551:10;27546:3;27542:20;27539:1;27532:31;27582:4;27579:1;27572:15;27606:4;27603:1;27596:15

Swarm Source

ipfs://8748a262441041dfab5f326e0b1e6d554572def581541933bd4561c362eea506
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.