ETH Price: $3,482.15 (-1.50%)
Gas: 2 Gwei

Token

Bit Bird Club (BBC)
 

Overview

Max Total Supply

590 BBC

Holders

87

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
asymmetriccapital.eth
Balance
1 BBC
0xf60fd90fc72e1eb4d2054a24f5dcf7658f166eda
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:
BitBirdClubNFT

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-08-17
*/

// File: contracts/includes/WithLimitedSupply.sol


pragma solidity ^0.8.4;

/// @author Modified version of original code by 1001.digital
/// @title A token tracker that limits the token supply and increments token IDs on each new mint.
abstract contract WithLimitedSupply {
    // Keeps track of how many we have minted
    uint256 private _tokenCount;

    /// @dev The maximum count of tokens this token tracker will issue.
    uint256 private immutable _maxAvailableSupply;

    /// Instanciate the contract
    /// @param maxSupply_ how many tokens this collection should hold
    constructor(uint256 maxSupply_, uint256 reserved_) {
        _maxAvailableSupply = maxSupply_ - reserved_;
    }

    function maxAvailableSupply() public view returns (uint256) {
        return _maxAvailableSupply;
    }

    /// @dev Get the current token count
    /// @return the created token count
    /// TODO: if this is not required externally, does making it `public view` use unneccary gas?
    function tokenCount() public view returns (uint256) {
        return _tokenCount;
    }

    /// @dev Check whether tokens are still available
    /// @return the available token count
    function availableTokenCount() public view returns (uint256) {
        return maxAvailableSupply() - tokenCount();
    }

    /// @dev Increment the token count and fetch the latest count
    /// @return the next token id
    function nextToken() internal virtual ensureAvailability returns (uint256) {
        return _tokenCount++;
    }

    /// @dev Check whether another token is still available
    modifier ensureAvailability() {
        require(availableTokenCount() > 0, "No more tokens available");
        _;
    }

    /// @param amount Check whether number of tokens are still available
    /// @dev Check whether tokens are still available
    modifier ensureAvailabilityFor(uint256 amount) {
        require(
            availableTokenCount() >= amount,
            "Requested number of tokens not available"
        );
        _;
    }
}

// File: contracts/includes/RandomlyAssigned.sol


pragma solidity ^0.8.4;


/// @author Modified version of original code by 1001.digital
/// @title Randomly assign tokenIDs from a given set of tokens.
abstract contract RandomlyAssigned is WithLimitedSupply {
    // Used for random index assignment
    mapping(uint256 => uint256) private tokenMatrix;

    // The initial token ID
    uint256 private immutable startFrom;

    /// Instanciate the contract
    /// @param maxSupply_ how many tokens this collection should hold
    /// @param numReserved_ the number of tokens reserved whose IDs dont come from the randomizer
    constructor(
        uint256 maxSupply_,
        uint256 numReserved_
    ) WithLimitedSupply(maxSupply_, numReserved_) {
        startFrom = numReserved_ + 1;
    }

    /// Get the next token ID
    /// @dev Randomly gets a new token ID and keeps track of the ones that are still available.
    /// @return the next token ID
    function nextToken() internal override returns (uint256) {
        uint256 maxIndex = maxAvailableSupply() - tokenCount();
        uint256 random = uint256(
            keccak256(
                abi.encodePacked(
                    msg.sender,
                    block.coinbase,
                    block.prevrandao,
                    block.gaslimit,
                    block.timestamp
                )
            )
        ) % maxIndex;

        uint256 value = 0;
        if (tokenMatrix[random] == 0) {
            // If this matrix position is empty, set the value to the generated random number.
            value = random;
        } else {
            // Otherwise, use the previously stored number from the matrix.
            value = tokenMatrix[random];
        }

        // If the last available tokenID is still unused...
        if (tokenMatrix[maxIndex - 1] == 0) {
            // ...store that ID in the current matrix position.
            tokenMatrix[random] = maxIndex - 1;
        } else {
            // ...otherwise copy over the stored number to the current matrix position.
            tokenMatrix[random] = tokenMatrix[maxIndex - 1];
        }

        // Increment counts (ie. qty minted)
        super.nextToken();

        return value + startFrom;
    }
}

// File: @openzeppelin/contracts/utils/math/SignedMath.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two signed numbers.
     */
    function min(int256 a, int256 b) internal pure returns (int256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

// File: @openzeppelin/contracts/utils/math/Math.sol


// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

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


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

pragma solidity ^0.8.0;



/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _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) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

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

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

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


// OpenZeppelin Contracts (last updated v4.9.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
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, "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");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or 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 {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // 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.9.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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * 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/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

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


// OpenZeppelin Contracts (last updated v4.9.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 = _ownerOf(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 or 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 or 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 or 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 the owner of the `tokenId`. Does NOT revert if token doesn't exist
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

    /**
     * @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 _ownerOf(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, 1);

        // Check that tokenId was not minted by `_beforeTokenTransfer` hook
        require(!_exists(tokenId), "ERC721: token already minted");

        unchecked {
            // Will not overflow unless all 2**256 token ids are minted to the same owner.
            // Given that tokens are minted one by one, it is impossible in practice that
            // this ever happens. Might change if we allow batch minting.
            // The ERC fails to describe this case.
            _balances[to] += 1;
        }

        _owners[tokenId] = to;

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

        _afterTokenTransfer(address(0), to, tokenId, 1);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     * This is an internal function that does not check if the sender is authorized to operate on the token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

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

        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
        owner = ERC721.ownerOf(tokenId);

        // Clear approvals
        delete _tokenApprovals[tokenId];

        unchecked {
            // Cannot overflow, as that would require more tokens to be burned/transferred
            // out than the owner initially received through minting and transferring in.
            _balances[owner] -= 1;
        }
        delete _owners[tokenId];

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

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

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

        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");

        // Clear approvals from the previous owner
        delete _tokenApprovals[tokenId];

        unchecked {
            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
            // `from`'s balance is the number of token held, which is at least one before the current
            // transfer.
            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
            // all 2**256 token ids to be minted, which in practice is impossible.
            _balances[from] -= 1;
            _balances[to] += 1;
        }
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId, 1);
    }

    /**
     * @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. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
     * - When `from` is zero, the tokens will be minted for `to`.
     * - When `to` is zero, ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}

    /**
     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
     * - When `from` is zero, the tokens were minted for `to`.
     * - When `to` is zero, ``from``'s tokens were burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}

    /**
     * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
     *
     * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant
     * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such
     * that `ownerOf(tokenId)` is `a`.
     */
    // solhint-disable-next-line func-name-mixedcase
    function __unsafe_increaseBalance(address account, uint256 amount) internal {
        _balances[account] += amount;
    }
}

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


// OpenZeppelin Contracts (last updated v4.8.0) (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 See {ERC721-_beforeTokenTransfer}.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, firstTokenId, batchSize);

        if (batchSize > 1) {
            // Will only trigger during construction. Batch transferring (minting) is not available afterwards.
            revert("ERC721Enumerable: consecutive transfers not supported");
        }

        uint256 tokenId = firstTokenId;

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


// OpenZeppelin Contracts (last updated v4.9.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. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling 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: contracts/BitBirdClubNFT.sol

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;






contract BitBirdClubNFT is ERC721Enumerable, RandomlyAssigned, Ownable {
    uint256 constant MAX_MINT = 5555;
    uint256 constant MAX_MINT_PER_TRANSACTION = 50;

    mapping(address => bool) public whitelist;
    mapping(address => uint256) public totalUserMints;

    uint256 public normalMintCost;
    uint256 public whitelistMintCost;

    uint256 public whitelistMintStartTimestamp;
    uint256 public mintStartTimestamp;

    uint256 public payableERC20TokenMintCost;
    address public payableERC20Token;

    // Drop Operator Fee Setup
    address private constant OPERATOR_ADDRESS =
        0x16d934B9646d9DA51Db92627BF0070Be0Ab72389;
    uint256 private constant OPERATOR_FEE = 0;
    uint256 private constant OPERATOR_FEE_DENOMINATOR = 1000;

    string baseURI;
    string revealURI;
    bool public mintEnabled;
    bool public whitelistOnly;
    bool public canMintWithERC20;
    bool public isRevealed;
    uint256 public maxMintPerAddress;

    modifier onlyMintEnabled() {
        require(
            mintEnabled ||
                (block.timestamp >= mintStartTimestamp) ||
                (whitelist[msg.sender] == true &&
                    block.timestamp >= whitelistMintStartTimestamp),
            "Mint Disabled"
        );
        _;
    }

    modifier onlyWhitelisted() {
        if (whitelistOnly) {
            require(isWhitelisted(msg.sender), "Not Whitelisted");
        }
        _;
    }

    modifier ERC20MintingAllowed() {
        require(canMintWithERC20 == true, "ERC20 Token Minting is disabled");
        _;
    }

    constructor(
        string memory _nftBaseURI,
        string memory _nftRevealURI,
        uint256 _initialTeamReserve,
        uint256 _mintStartTimestamp,
        uint256 _whitelistMintStartTimestamp,
        uint256 _maxMintPerAddress
    ) ERC721("Bit Bird Club", "BBC") RandomlyAssigned(MAX_MINT, 0) {
        baseURI = _nftBaseURI;
        revealURI = _nftRevealURI;
        maxMintPerAddress = _maxMintPerAddress;

        payableERC20Token = address(0);

        normalMintCost = 36000000000000000;
        whitelistMintCost = 27000000000000000;
        payableERC20TokenMintCost = 1 ether;

        whitelistMintStartTimestamp = _whitelistMintStartTimestamp;
        mintStartTimestamp = _mintStartTimestamp;

        // Mint initial team reserve
        if (_initialTeamReserve > 0) {
            for (uint256 i = 0; i < _initialTeamReserve; i++) {
                uint256 index = nextToken();
                _safeMint(msg.sender, index);
            }
        }

        isRevealed = true;
    }

    function canUserStartMinting(address _address) public view returns (bool) {
        return
            mintEnabled ||
            (block.timestamp >= mintStartTimestamp) ||
            (whitelist[_address] == true &&
                block.timestamp >= whitelistMintStartTimestamp);
    }

    function setRevealed() external onlyOwner {
        isRevealed = true;
    }

    function setMaxMintPerAddress(
        uint256 _maxMintPerAddress
    ) external onlyOwner {
        maxMintPerAddress = _maxMintPerAddress;
    }

    function updateBaseURI(string memory _newURI) external onlyOwner {
        baseURI = _newURI;
    }

    function updateRevealURI(string memory _newURI) external onlyOwner {
        revealURI = _newURI;
    }

    function setMintEnabled(bool _mintEnabled) external onlyOwner {
        mintEnabled = _mintEnabled;
    }

    function setWhitelistOnly(bool _whitelistOnly) external onlyOwner {
        whitelistOnly = _whitelistOnly;
    }

    function setCanMintWithERC20(bool _canMintWithERC20) external onlyOwner {
        canMintWithERC20 = _canMintWithERC20;
    }

    function setPayableERC20Token(
        address _payableERC20Token
    ) external onlyOwner {
        payableERC20Token = _payableERC20Token;
    }

    function setMintCosts(
        uint256 _normalMintCost,
        uint256 _whitelistMintCost,
        uint256 _payableERC20TokenMintCost
    ) external onlyOwner {
        normalMintCost = _normalMintCost;
        whitelistMintCost = _whitelistMintCost;
        payableERC20TokenMintCost = _payableERC20TokenMintCost;
    }

    function setMintStartTimestamps(
        uint256 _mintStartTimestamp,
        uint256 _whitelistMintStartTimestamp
    ) external onlyOwner {
        mintStartTimestamp = _mintStartTimestamp;
        whitelistMintStartTimestamp = _whitelistMintStartTimestamp;
    }

    function mint(
        uint256 _amount
    ) external payable onlyMintEnabled onlyWhitelisted {
        _mintNFT(_amount);
    }

    function mintWithERC20Token(
        uint256 _amount
    ) external onlyMintEnabled onlyWhitelisted ERC20MintingAllowed {
        require(_amount <= MAX_MINT_PER_TRANSACTION, "Invalid mint amount");
        require(_amount > 0, "Invalid mint amount");
        require(
            totalSupply() + _amount <= MAX_MINT,
            "Exceeding Max Mint Count"
        );
        require(
            maxMintPerAddress == 0 ||
                totalUserMints[msg.sender] + _amount <= maxMintPerAddress ||
                msg.sender == owner(),
            "Exceeding Max Mint Per Address"
        );

        uint256 requiredAmount = payableERC20TokenMintCost * _amount;

        // send tokens to owner
        IERC20(payableERC20Token).transferFrom(
            msg.sender,
            address(this),
            requiredAmount
        );

        for (uint256 i = 0; i < _amount; i++) {
            uint256 index = totalSupply() + 1;
            _safeMint(msg.sender, index);
        }

        totalUserMints[msg.sender] += _amount;
    }

    function _mintNFT(uint256 _amount) internal {
        require(_amount <= MAX_MINT_PER_TRANSACTION, "Invalid mint amount");
        require(_amount > 0, "Invalid mint amount");
        require(
            totalSupply() + _amount <= MAX_MINT,
            "Exceeding Max Mint Count"
        );
        require(
            maxMintPerAddress == 0 ||
                totalUserMints[msg.sender] + _amount <= maxMintPerAddress ||
                msg.sender == owner(),
            "Exceeding Max Mint Per Address"
        );

        uint256 requiredAmount = mintCost(msg.sender) * _amount;
        uint256 operatorFee = OPERATOR_FEE > 0
            ? (requiredAmount * OPERATOR_FEE) / OPERATOR_FEE_DENOMINATOR
            : 0;

        // Ensure the caller has sent enough ETH to cover the cost of minting
        require(
            msg.value == requiredAmount || msg.sender == owner(),
            "Insufficient Payment"
        );

        // Send operator fee to designated address
        if (operatorFee > 0) {
            (bool sent, ) = OPERATOR_ADDRESS.call{value: operatorFee}("");
            require(sent, "Failed to send operator fee");
        }

        for (uint256 i = 0; i < _amount; i++) {
            uint256 index = nextToken();
            _safeMint(msg.sender, index);
        }

        totalUserMints[msg.sender] += _amount;
    }

    function addWhitelist(address[] calldata _addresses) external onlyOwner {
        for (uint256 index = 0; index < _addresses.length; index++) {
            whitelist[_addresses[index]] = true;
        }
    }

    function removeWhitelist(address[] calldata _addresses) external onlyOwner {
        for (uint256 index = 0; index < _addresses.length; index++) {
            whitelist[_addresses[index]] = false;
        }
    }

    function mintCost(address _minter) public view returns (uint256) {
        uint256 _mintCost = normalMintCost;

        if (whitelist[_minter] == true) {
            _mintCost = whitelistMintCost;
        }

        if (_minter == owner()) {
            _mintCost = 0;
        }

        return _mintCost;
    }

    function maxMintPerTransaction() public pure returns (uint256) {
        return MAX_MINT_PER_TRANSACTION;
    }

    function canMint(address _minter) external view returns (uint256) {
        if (mintEnabled == false) {
            return 0;
        }

        if (whitelistOnly == true && isWhitelisted(_minter) == false) {
            return 0;
        }

        if (totalSupply() >= MAX_MINT) {
            return 0;
        }

        return MAX_MINT_PER_TRANSACTION;
    }

    function adminWithdrawETH() external onlyOwner {
        require(address(this).balance > 0, "No ETH to withdraw.");

        (bool success, ) = address(msg.sender).call{
            value: address(this).balance
        }("");

        require(success, "Failed to withdraw ETH.");
    }

    function adminWithdrawToken(address _tokenAddress) external onlyOwner {
        require(
            IERC20(_tokenAddress).balanceOf(address(this)) > 0,
            "No tokens to recover."
        );
        IERC20(_tokenAddress).transfer(
            msg.sender,
            IERC20(_tokenAddress).balanceOf(address(this))
        );
    }

    function maxSupply() external pure returns (uint256) {
        return MAX_MINT;
    }

    function isWhitelisted(address _address) public view returns (bool) {
        return whitelist[_address];
    }

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

    function getBaseURI() external view returns (string memory) {
        return _baseURI();
    }

    function supportsInterface(
        bytes4 interfaceId
    ) public view override(ERC721Enumerable) returns (bool) {
        return super.supportsInterface(interfaceId);
    }

    function tokenURI(
        uint256 tokenID
    ) public view virtual override returns (string memory) {
        if (isRevealed != true) {
            return string(abi.encodePacked(revealURI));
        }

        return string(abi.encodePacked(super.tokenURI(tokenID)));
    }

    function ownedNFTIdList(
        address _ownerAddress
    ) public view returns (uint256[] memory) {
        uint256 balance = balanceOf(_ownerAddress);

        uint256[] memory allIndexes = new uint256[](balance);
        for (uint256 i = 0; i < balance; i++) {
            uint256 tokenIndex = tokenOfOwnerByIndex(_ownerAddress, i);
            allIndexes[i] = tokenIndex;
        }

        return allIndexes;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_nftBaseURI","type":"string"},{"internalType":"string","name":"_nftRevealURI","type":"string"},{"internalType":"uint256","name":"_initialTeamReserve","type":"uint256"},{"internalType":"uint256","name":"_mintStartTimestamp","type":"uint256"},{"internalType":"uint256","name":"_whitelistMintStartTimestamp","type":"uint256"},{"internalType":"uint256","name":"_maxMintPerAddress","type":"uint256"}],"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":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"addWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"adminWithdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"}],"name":"adminWithdrawToken","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":[],"name":"availableTokenCount","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":[{"internalType":"address","name":"_minter","type":"address"}],"name":"canMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canMintWithERC20","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"canUserStartMinting","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBaseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"isRevealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAvailableSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintPerAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintPerTransaction","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"mintCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintStartTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintWithERC20Token","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"normalMintCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_ownerAddress","type":"address"}],"name":"ownedNFTIdList","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","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":"payableERC20Token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"payableERC20TokenMintCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"removeWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_canMintWithERC20","type":"bool"}],"name":"setCanMintWithERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxMintPerAddress","type":"uint256"}],"name":"setMaxMintPerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_normalMintCost","type":"uint256"},{"internalType":"uint256","name":"_whitelistMintCost","type":"uint256"},{"internalType":"uint256","name":"_payableERC20TokenMintCost","type":"uint256"}],"name":"setMintCosts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_mintEnabled","type":"bool"}],"name":"setMintEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintStartTimestamp","type":"uint256"},{"internalType":"uint256","name":"_whitelistMintStartTimestamp","type":"uint256"}],"name":"setMintStartTimestamps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_payableERC20Token","type":"address"}],"name":"setPayableERC20Token","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setRevealed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_whitelistOnly","type":"bool"}],"name":"setWhitelistOnly","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenCount","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":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalUserMints","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":[{"internalType":"string","name":"_newURI","type":"string"}],"name":"updateBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newURI","type":"string"}],"name":"updateRevealURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistMintCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistMintStartTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistOnly","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60c06040523480156200001157600080fd5b50604051620044a7380380620044a7833981016040819052620000349162000c00565b6115b3600081816040518060400160405280600d81526020016c2134ba102134b9321021b63ab160991b8152506040518060400160405280600381526020016242424360e81b81525081600090816200008e919062000d1d565b5060016200009d828262000d1d565b5050508082620000ae919062000dff565b60805250620000c1905081600162000e1b565b60a05250620000d290503362000196565b6015620000e0878262000d1d565b506016620000ef868262000d1d565b506018819055601480546001600160a01b0319169055667fe5cf2bea0000600f55665fec5b60ef8000601055670de0b6b3a7640000601355601182905560128390558315620001765760005b848110156200017457600062000150620001e8565b90506200015e338262000344565b50806200016b8162000e31565b9150506200013b565b505b50506017805463ff000000191663010000001790555062000f2592505050565b600c80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600080620001f5600a5490565b60805162000204919062000dff565b6040516001600160601b031933606090811b8216602084015241901b166034820152446048820152456068820152426088820152909150600090829060a8016040516020818303038152906040528051906020012060001c62000268919062000e4d565b6000818152600b60205260408120549192509081036200028a5750806200029b565b506000818152600b60205260409020545b600b6000620002ac60018662000dff565b815260200190815260200160002054600003620002e557620002d060018462000dff565b6000838152600b602052604090205562000317565b600b6000620002f660018662000dff565b81526020808201929092526040908101600090812054858252600b90935220555b6200032c6200036a60201b62001b371760201c565b5060a0516200033c908262000e1b565b935050505090565b62000366828260405180602001604052806000815250620003e560201b60201c565b5050565b600080620003776200045d565b11620003ca5760405162461bcd60e51b815260206004820152601860248201527f4e6f206d6f726520746f6b656e7320617661696c61626c65000000000000000060448201526064015b60405180910390fd5b600a8054906000620003dc8362000e31565b91905055905090565b620003f183836200047d565b6200040060008484846200061e565b620004585760405162461bcd60e51b815260206004820152603260248201526000805160206200448783398151915260448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608401620003c1565b505050565b600062000469600a5490565b60805162000478919062000dff565b905090565b6001600160a01b038216620004d55760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401620003c1565b6000818152600260205260409020546001600160a01b0316156200053c5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401620003c1565b6200054c6000838360016200077a565b6000818152600260205260409020546001600160a01b031615620005b35760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401620003c1565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006200063f846001600160a01b0316620008e460201b62001ba81760201c565b156200076e57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906200067990339089908890889060040162000e70565b6020604051808303816000875af1925050508015620006b7575060408051601f3d908101601f19168201909252620006b49181019062000ec6565b60015b62000753573d808015620006e8576040519150601f19603f3d011682016040523d82523d6000602084013e620006ed565b606091505b5080516000036200074b5760405162461bcd60e51b815260206004820152603260248201526000805160206200448783398151915260448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608401620003c1565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905062000772565b5060015b949350505050565b6200079384848484620008de60201b6200130a1760201c565b60018111156200080c5760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e736563757469766520747260448201527f616e7366657273206e6f7420737570706f7274656400000000000000000000006064820152608401620003c1565b816001600160a01b0385166200086b576200086581600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b62000891565b836001600160a01b0316856001600160a01b0316146200089157620008918582620008f3565b6001600160a01b038416620008b157620008ab81620009a0565b620008d7565b846001600160a01b0316846001600160a01b031614620008d757620008d7848262000a5a565b5050505050565b50505050565b6001600160a01b03163b151590565b600060016200090d8462000aab60201b6200102f1760201c565b62000919919062000dff565b6000838152600760205260409020549091508082146200096d576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090620009b49060019062000dff565b60008381526009602052604081205460088054939450909284908110620009df57620009df62000ef9565b90600052602060002001549050806008838154811062000a035762000a0362000ef9565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548062000a3e5762000a3e62000f0f565b6001900381819060005260206000200160009055905550505050565b600062000a728362000aab60201b6200102f1760201c565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b60006001600160a01b03821662000b175760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401620003c1565b506001600160a01b031660009081526003602052604090205490565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000b6657818101518382015260200162000b4c565b50506000910152565b600082601f83011262000b8157600080fd5b81516001600160401b038082111562000b9e5762000b9e62000b33565b604051601f8301601f19908116603f0116810190828211818310171562000bc95762000bc962000b33565b8160405283815286602085880101111562000be357600080fd5b62000bf684602083016020890162000b49565b9695505050505050565b60008060008060008060c0878903121562000c1a57600080fd5b86516001600160401b038082111562000c3257600080fd5b62000c408a838b0162000b6f565b9750602089015191508082111562000c5757600080fd5b5062000c6689828a0162000b6f565b95505060408701519350606087015192506080870151915060a087015190509295509295509295565b600181811c9082168062000ca457607f821691505b60208210810362000cc557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200045857600081815260208120601f850160051c8101602086101562000cf45750805b601f850160051c820191505b8181101562000d155782815560010162000d00565b505050505050565b81516001600160401b0381111562000d395762000d3962000b33565b62000d518162000d4a845462000c8f565b8462000ccb565b602080601f83116001811462000d89576000841562000d705750858301515b600019600386901b1c1916600185901b17855562000d15565b600085815260208120601f198616915b8281101562000dba5788860151825594840194600190910190840162000d99565b508582101562000dd95787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000e155762000e1562000de9565b92915050565b8082018082111562000e155762000e1562000de9565b60006001820162000e465762000e4662000de9565b5060010190565b60008262000e6b57634e487b7160e01b600052601260045260246000fd5b500690565b600060018060a01b03808716835280861660208401525083604083015260806060830152825180608084015262000eaf8160a085016020870162000b49565b601f01601f19169190910160a00195945050505050565b60006020828403121562000ed957600080fd5b81516001600160e01b03198116811462000ef257600080fd5b9392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05161352e62000f59600039600061265e0152600081816104b20152818161140b0152612520015261352e6000f3fe60806040526004361061038c5760003560e01c8063714c5398116101dc578063b88d4fde11610102578063e985e9c5116100a0578063f2fde38b1161006f578063f2fde38b14610a6b578063f46a04eb14610a8b578063fa0cf53814610aab578063fee9d13b14610acb57600080fd5b8063e985e9c5146109cd578063ea05a8c614610a16578063ed84fc9114610a36578063edac985b14610a4b57600080fd5b8063d1239730116100dc578063d123973014610969578063d48997df14610983578063d5abeb01146109a3578063e14ca353146109b857600080fd5b8063b88d4fde14610909578063c2ba474414610929578063c87b56dd1461094957600080fd5b80639a8c00351161017a578063a0e389de11610149578063a0e389de1461089d578063a22cb465146108b3578063b0d356e5146108d3578063b12dab6e146108f357600080fd5b80639a8c0035146108255780639b19251a146108455780639f181b5e14610875578063a0712d681461088a57600080fd5b80638da5cb5b116101b65780638da5cb5b146107b2578063931688cb146107d057806395d89b41146107f057806399f7e45f1461080557600080fd5b8063714c53981461075b578063715018a614610770578063839ad1d31461078557600080fd5b80632f745c59116102c157806342842e0e1161025f578063572849c41161022e578063572849c4146106ef5780636352211e146107055780636a7957321461072557806370a082311461073b57600080fd5b806342842e0e1461066f5780634b4687b51461068f5780634f6ccce7146106ae57806354214f69146106ce57600080fd5b80633af32abf1161029b5780633af32abf146105eb5780633b71275d146106245780633bd6496814610644578063413fa8e31461065957600080fd5b80632f745c591461058b5780633096b9e8146105ab57806333a5f120146105cb57600080fd5b806315f91c181161032e5780631e14d44b116103085780631e14d44b1461050b578063232452161461052b57806323b872dd1461054b5780632acc659e1461056b57600080fd5b806315f91c18146104a357806318160ddd146104d65780631e0d6eea146104eb57600080fd5b806306fdde031161036a57806306fdde03146103fa578063081812fc1461041c578063095ea7b31461045457806310d8bc091461047657600080fd5b806301f569971461039157806301ffc9a7146103b457806302ddfd21146103e4575b600080fd5b34801561039d57600080fd5b5060325b6040519081526020015b60405180910390f35b3480156103c057600080fd5b506103d46103cf366004612c69565b610aeb565b60405190151581526020016103ab565b3480156103f057600080fd5b506103a160115481565b34801561040657600080fd5b5061040f610afc565b6040516103ab9190612cd6565b34801561042857600080fd5b5061043c610437366004612ce9565b610b8e565b6040516001600160a01b0390911681526020016103ab565b34801561046057600080fd5b5061047461046f366004612d1e565b610bb5565b005b34801561048257600080fd5b506103a1610491366004612d48565b600e6020526000908152604090205481565b3480156104af57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103a1565b3480156104e257600080fd5b506008546103a1565b3480156104f757600080fd5b50610474610506366004612d63565b610ccf565b34801561051757600080fd5b50610474610526366004612ce9565b610ce5565b34801561053757600080fd5b50610474610546366004612d8f565b610cf2565b34801561055757600080fd5b50610474610566366004612e04565b610d6c565b34801561057757600080fd5b506103a1610586366004612d48565b610d9d565b34801561059757600080fd5b506103a16105a6366004612d1e565b610dfa565b3480156105b757600080fd5b506104746105c6366004612e4e565b610e90565b3480156105d757600080fd5b506103d46105e6366004612d48565b610eb4565b3480156105f757600080fd5b506103d4610606366004612d48565b6001600160a01b03166000908152600d602052604090205460ff1690565b34801561063057600080fd5b506017546103d49062010000900460ff1681565b34801561065057600080fd5b50610474610f04565b34801561066557600080fd5b506103a160135481565b34801561067b57600080fd5b5061047461068a366004612e04565b610f21565b34801561069b57600080fd5b506017546103d490610100900460ff1681565b3480156106ba57600080fd5b506103a16106c9366004612ce9565b610f3c565b3480156106da57600080fd5b506017546103d4906301000000900460ff1681565b3480156106fb57600080fd5b506103a160185481565b34801561071157600080fd5b5061043c610720366004612ce9565b610fcf565b34801561073157600080fd5b506103a1600f5481565b34801561074757600080fd5b506103a1610756366004612d48565b61102f565b34801561076757600080fd5b5061040f6110b5565b34801561077c57600080fd5b506104746110c4565b34801561079157600080fd5b506107a56107a0366004612d48565b6110d8565b6040516103ab9190612e6b565b3480156107be57600080fd5b50600c546001600160a01b031661043c565b3480156107dc57600080fd5b506104746107eb366004612f3b565b611180565b3480156107fc57600080fd5b5061040f611198565b34801561081157600080fd5b50610474610820366004612d48565b6111a7565b34801561083157600080fd5b50610474610840366004612f3b565b6111d1565b34801561085157600080fd5b506103d4610860366004612d48565b600d6020526000908152604090205460ff1681565b34801561088157600080fd5b50600a546103a1565b610474610898366004612ce9565b6111e5565b3480156108a957600080fd5b506103a160125481565b3480156108bf57600080fd5b506104746108ce366004612f84565b6112cd565b3480156108df57600080fd5b5060145461043c906001600160a01b031681565b3480156108ff57600080fd5b506103a160105481565b34801561091557600080fd5b50610474610924366004612fbb565b6112d8565b34801561093557600080fd5b506103a1610944366004612d48565b611310565b34801561095557600080fd5b5061040f610964366004612ce9565b61138d565b34801561097557600080fd5b506017546103d49060ff1681565b34801561098f57600080fd5b5061047461099e366004613037565b6113e7565b3480156109af57600080fd5b506115b36103a1565b3480156109c457600080fd5b506103a16113fa565b3480156109d957600080fd5b506103d46109e8366004613059565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610a2257600080fd5b50610474610a31366004612e4e565b61142f565b348015610a4257600080fd5b50610474611451565b348015610a5757600080fd5b50610474610a66366004612d8f565b611537565b348015610a7757600080fd5b50610474610a86366004612d48565b6115b1565b348015610a9757600080fd5b50610474610aa6366004612e4e565b611627565b348015610ab757600080fd5b50610474610ac6366004612ce9565b611642565b348015610ad757600080fd5b50610474610ae6366004612d48565b61199e565b6000610af682611bb7565b92915050565b606060008054610b0b9061308c565b80601f0160208091040260200160405190810160405280929190818152602001828054610b379061308c565b8015610b845780601f10610b5957610100808354040283529160200191610b84565b820191906000526020600020905b815481529060010190602001808311610b6757829003601f168201915b5050505050905090565b6000610b9982611bdc565b506000908152600460205260409020546001600160a01b031690565b6000610bc082610fcf565b9050806001600160a01b0316836001600160a01b031603610c325760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b0382161480610c4e5750610c4e81336109e8565b610cc05760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610c29565b610cca8383611c3b565b505050565b610cd7611ca9565b600f92909255601055601355565b610ced611ca9565b601855565b610cfa611ca9565b60005b81811015610cca576000600d6000858585818110610d1d57610d1d6130c6565b9050602002016020810190610d329190612d48565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905580610d64816130f2565b915050610cfd565b610d763382611d03565b610d925760405162461bcd60e51b8152600401610c299061310b565b610cca838383611d82565b600f546001600160a01b0382166000908152600d602052604081205490919060ff161515600103610dcd57506010545b600c546001600160a01b03166001600160a01b0316836001600160a01b031603610af65750600092915050565b6000610e058361102f565b8210610e675760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610c29565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610e98611ca9565b60178054911515620100000262ff000019909216919091179055565b60175460009060ff1680610eca57506012544210155b80610af657506001600160a01b0382166000908152600d602052604090205460ff1615156001148015610af6575060115442101592915050565b610f0c611ca9565b6017805463ff00000019166301000000179055565b610cca838383604051806020016040528060008152506112d8565b6000610f4760085490565b8210610faa5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610c29565b60088281548110610fbd57610fbd6130c6565b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b031680610af65760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c29565b60006001600160a01b0382166110995760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610c29565b506001600160a01b031660009081526003602052604090205490565b60606110bf611ef3565b905090565b6110cc611ca9565b6110d66000611f02565b565b606060006110e58361102f565b905060008167ffffffffffffffff81111561110257611102612eaf565b60405190808252806020026020018201604052801561112b578160200160208202803683370190505b50905060005b828110156111785760006111458683610dfa565b90508083838151811061115a5761115a6130c6565b60209081029190910101525080611170816130f2565b915050611131565b509392505050565b611188611ca9565b601561119482826131a6565b5050565b606060018054610b0b9061308c565b6111af611ca9565b601480546001600160a01b0319166001600160a01b0392909216919091179055565b6111d9611ca9565b601661119482826131a6565b60175460ff16806111f857506012544210155b806112245750336000908152600d602052604090205460ff161515600114801561122457506011544210155b6112605760405162461bcd60e51b815260206004820152600d60248201526c135a5b9d08111a5cd8589b1959609a1b6044820152606401610c29565b601754610100900460ff16156112c157336000908152600d602052604090205460ff166112c15760405162461bcd60e51b815260206004820152600f60248201526e139bdd0815da1a5d195b1a5cdd1959608a1b6044820152606401610c29565b6112ca81611f54565b50565b611194338383612208565b6112e23383611d03565b6112fe5760405162461bcd60e51b8152600401610c299061310b565b61130a848484846122d6565b50505050565b60175460009060ff161515810361132957506000919050565b60175460ff610100909104161515600114801561135f57506001600160a01b0382166000908152600d602052604090205460ff16155b1561136c57506000919050565b6115b361137860085490565b1061138557506000919050565b506032919050565b6017546060906301000000900460ff1615156001146113ce5760166040516020016113b89190613266565b6040516020818303038152906040529050919050565b6113d782612309565b6040516020016113b891906132dc565b6113ef611ca9565b601291909155601155565b6000611405600a5490565b6110bf907f00000000000000000000000000000000000000000000000000000000000000006132f8565b611437611ca9565b601780549115156101000261ff0019909216919091179055565b611459611ca9565b6000471161149f5760405162461bcd60e51b815260206004820152601360248201527227379022aa24103a37903bb4ba34323930bb9760691b6044820152606401610c29565b604051600090339047908381818185875af1925050503d80600081146114e1576040519150601f19603f3d011682016040523d82523d6000602084013e6114e6565b606091505b50509050806112ca5760405162461bcd60e51b815260206004820152601760248201527f4661696c656420746f207769746864726177204554482e0000000000000000006044820152606401610c29565b61153f611ca9565b60005b81811015610cca576001600d6000858585818110611562576115626130c6565b90506020020160208101906115779190612d48565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055806115a9816130f2565b915050611542565b6115b9611ca9565b6001600160a01b03811661161e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c29565b6112ca81611f02565b61162f611ca9565b6017805460ff1916911515919091179055565b60175460ff168061165557506012544210155b806116815750336000908152600d602052604090205460ff161515600114801561168157506011544210155b6116bd5760405162461bcd60e51b815260206004820152600d60248201526c135a5b9d08111a5cd8589b1959609a1b6044820152606401610c29565b601754610100900460ff161561171e57336000908152600d602052604090205460ff1661171e5760405162461bcd60e51b815260206004820152600f60248201526e139bdd0815da1a5d195b1a5cdd1959608a1b6044820152606401610c29565b60175462010000900460ff16151560011461177b5760405162461bcd60e51b815260206004820152601f60248201527f455243323020546f6b656e204d696e74696e672069732064697361626c6564006044820152606401610c29565b603281111561179c5760405162461bcd60e51b8152600401610c299061330b565b600081116117bc5760405162461bcd60e51b8152600401610c299061330b565b6115b3816117c960085490565b6117d39190613338565b111561181c5760405162461bcd60e51b8152602060048201526018602482015277115e18d959591a5b99c813585e08135a5b9d0810dbdd5b9d60421b6044820152606401610c29565b60185415806118475750601854336000908152600e6020526040902054611844908390613338565b11155b8061185c5750600c546001600160a01b031633145b6118a85760405162461bcd60e51b815260206004820152601e60248201527f457863656564696e67204d6178204d696e7420506572204164647265737300006044820152606401610c29565b6000816013546118b8919061334b565b6014546040516323b872dd60e01b8152336004820152306024820152604481018390529192506001600160a01b0316906323b872dd906064016020604051808303816000875af1158015611910573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119349190613362565b5060005b8281101561197557600061194b60085490565b611956906001613338565b90506119623382612370565b508061196d816130f2565b915050611938565b50336000908152600e602052604081208054849290611995908490613338565b90915550505050565b6119a6611ca9565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156119ed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a11919061337f565b11611a565760405162461bcd60e51b81526020600482015260156024820152742737903a37b5b2b739903a37903932b1b7bb32b91760591b6044820152606401610c29565b6040516370a0823160e01b81523060048201526001600160a01b0382169063a9059cbb90339083906370a0823190602401602060405180830381865afa158015611aa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac8919061337f565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015611b13573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111949190613362565b600080611b426113fa565b11611b8f5760405162461bcd60e51b815260206004820152601860248201527f4e6f206d6f726520746f6b656e7320617661696c61626c6500000000000000006044820152606401610c29565b600a8054906000611b9f836130f2565b91905055905090565b6001600160a01b03163b151590565b60006001600160e01b0319821663780e9d6360e01b1480610af65750610af68261238a565b6000818152600260205260409020546001600160a01b03166112ca5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c29565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611c7082610fcf565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600c546001600160a01b031633146110d65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c29565b600080611d0f83610fcf565b9050806001600160a01b0316846001600160a01b03161480611d5657506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80611d7a5750836001600160a01b0316611d6f84610b8e565b6001600160a01b0316145b949350505050565b826001600160a01b0316611d9582610fcf565b6001600160a01b031614611dbb5760405162461bcd60e51b8152600401610c2990613398565b6001600160a01b038216611e1d5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610c29565b611e2a83838360016123da565b826001600160a01b0316611e3d82610fcf565b6001600160a01b031614611e635760405162461bcd60e51b8152600401610c2990613398565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b606060158054610b0b9061308c565b600c80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6032811115611f755760405162461bcd60e51b8152600401610c299061330b565b60008111611f955760405162461bcd60e51b8152600401610c299061330b565b6115b381611fa260085490565b611fac9190613338565b1115611ff55760405162461bcd60e51b8152602060048201526018602482015277115e18d959591a5b99c813585e08135a5b9d0810dbdd5b9d60421b6044820152606401610c29565b60185415806120205750601854336000908152600e602052604090205461201d908390613338565b11155b806120355750600c546001600160a01b031633145b6120815760405162461bcd60e51b815260206004820152601e60248201527f457863656564696e67204d6178204d696e7420506572204164647265737300006044820152606401610c29565b60008161208d33610d9d565b612097919061334b565b90506000813414806120b35750600c546001600160a01b031633145b6120f65760405162461bcd60e51b8152602060048201526014602482015273125b9cdd59999a58da595b9d0814185e5b595b9d60621b6044820152606401610c29565b80156121aa576040516000907316d934b9646d9da51db92627bf0070be0ab723899083908381818185875af1925050503d8060008114612152576040519150601f19603f3d011682016040523d82523d6000602084013e612157565b606091505b50509050806121a85760405162461bcd60e51b815260206004820152601b60248201527f4661696c656420746f2073656e64206f70657261746f722066656500000000006044820152606401610c29565b505b60005b838110156121de5760006121bf61250e565b90506121cb3382612370565b50806121d6816130f2565b9150506121ad565b50336000908152600e6020526040812080548592906121fe908490613338565b9091555050505050565b816001600160a01b0316836001600160a01b0316036122695760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610c29565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6122e1848484611d82565b6122ed8484848461268b565b61130a5760405162461bcd60e51b8152600401610c29906133f3565b606061231482611bdc565b600061231e611ef3565b9050600081511161233e5760405180602001604052806000815250612369565b806123488461278c565b604051602001612359929190613445565b6040516020818303038152906040525b9392505050565b61119482826040518060200160405280600081525061281f565b60006001600160e01b031982166380ac58cd60e01b14806123bb57506001600160e01b03198216635b5e139f60e01b145b80610af657506301ffc9a760e01b6001600160e01b0319831614610af6565b60018111156124495760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610c29565b816001600160a01b0385166124a5576124a081600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6124c8565b836001600160a01b0316856001600160a01b0316146124c8576124c88582612852565b6001600160a01b0384166124e4576124df816128ef565b612507565b846001600160a01b0316846001600160a01b03161461250757612507848261299e565b5050505050565b60008061251a600a5490565b612544907f00000000000000000000000000000000000000000000000000000000000000006132f8565b6040516bffffffffffffffffffffffff1933606090811b8216602084015241901b166034820152446048820152456068820152426088820152909150600090829060a8016040516020818303038152906040528051906020012060001c6125ab9190613474565b6000818152600b60205260408120549192509081036125cb5750806125dc565b506000818152600b60205260409020545b600b60006125eb6001866132f8565b8152602001908152602001600020546000036126205761260c6001846132f8565b6000838152600b6020526040902055612650565b600b600061262f6001866132f8565b81526020808201929092526040908101600090812054858252600b90935220555b612658611b37565b506126837f000000000000000000000000000000000000000000000000000000000000000082613338565b935050505090565b60006001600160a01b0384163b1561278157604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906126cf903390899088908890600401613488565b6020604051808303816000875af192505050801561270a575060408051601f3d908101601f19168201909252612707918101906134c5565b60015b612767573d808015612738576040519150601f19603f3d011682016040523d82523d6000602084013e61273d565b606091505b50805160000361275f5760405162461bcd60e51b8152600401610c29906133f3565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611d7a565b506001949350505050565b60606000612799836129e2565b600101905060008167ffffffffffffffff8111156127b9576127b9612eaf565b6040519080825280601f01601f1916602001820160405280156127e3576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846127ed57509392505050565b6128298383612aba565b612836600084848461268b565b610cca5760405162461bcd60e51b8152600401610c29906133f3565b6000600161285f8461102f565b61286991906132f8565b6000838152600760205260409020549091508082146128bc576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612901906001906132f8565b60008381526009602052604081205460088054939450909284908110612929576129296130c6565b90600052602060002001549050806008838154811061294a5761294a6130c6565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612982576129826134e2565b6001900381819060005260206000200160009055905550505050565b60006129a98361102f565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310612a215772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612a4d576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310612a6b57662386f26fc10000830492506010015b6305f5e1008310612a83576305f5e100830492506008015b6127108310612a9757612710830492506004015b60648310612aa9576064830492506002015b600a8310610af65760010192915050565b6001600160a01b038216612b105760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610c29565b6000818152600260205260409020546001600160a01b031615612b755760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c29565b612b836000838360016123da565b6000818152600260205260409020546001600160a01b031615612be85760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c29565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160e01b0319811681146112ca57600080fd5b600060208284031215612c7b57600080fd5b813561236981612c53565b60005b83811015612ca1578181015183820152602001612c89565b50506000910152565b60008151808452612cc2816020860160208601612c86565b601f01601f19169290920160200192915050565b6020815260006123696020830184612caa565b600060208284031215612cfb57600080fd5b5035919050565b80356001600160a01b0381168114612d1957600080fd5b919050565b60008060408385031215612d3157600080fd5b612d3a83612d02565b946020939093013593505050565b600060208284031215612d5a57600080fd5b61236982612d02565b600080600060608486031215612d7857600080fd5b505081359360208301359350604090920135919050565b60008060208385031215612da257600080fd5b823567ffffffffffffffff80821115612dba57600080fd5b818501915085601f830112612dce57600080fd5b813581811115612ddd57600080fd5b8660208260051b8501011115612df257600080fd5b60209290920196919550909350505050565b600080600060608486031215612e1957600080fd5b612e2284612d02565b9250612e3060208501612d02565b9150604084013590509250925092565b80151581146112ca57600080fd5b600060208284031215612e6057600080fd5b813561236981612e40565b6020808252825182820181905260009190848201906040850190845b81811015612ea357835183529284019291840191600101612e87565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612ee057612ee0612eaf565b604051601f8501601f19908116603f01168101908282118183101715612f0857612f08612eaf565b81604052809350858152868686011115612f2157600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215612f4d57600080fd5b813567ffffffffffffffff811115612f6457600080fd5b8201601f81018413612f7557600080fd5b611d7a84823560208401612ec5565b60008060408385031215612f9757600080fd5b612fa083612d02565b91506020830135612fb081612e40565b809150509250929050565b60008060008060808587031215612fd157600080fd5b612fda85612d02565b9350612fe860208601612d02565b925060408501359150606085013567ffffffffffffffff81111561300b57600080fd5b8501601f8101871361301c57600080fd5b61302b87823560208401612ec5565b91505092959194509250565b6000806040838503121561304a57600080fd5b50508035926020909101359150565b6000806040838503121561306c57600080fd5b61307583612d02565b915061308360208401612d02565b90509250929050565b600181811c908216806130a057607f821691505b6020821081036130c057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201613104576131046130dc565b5060010190565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b601f821115610cca57600081815260208120601f850160051c8101602086101561317f5750805b601f850160051c820191505b8181101561319e5782815560010161318b565b505050505050565b815167ffffffffffffffff8111156131c0576131c0612eaf565b6131d4816131ce845461308c565b84613158565b602080601f83116001811461320957600084156131f15750858301515b600019600386901b1c1916600185901b17855561319e565b600085815260208120601f198616915b8281101561323857888601518255948401946001909101908401613219565b50858210156132565787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008083546132748161308c565b6001828116801561328c57600181146132a1576132d0565b60ff19841687528215158302870194506132d0565b8760005260208060002060005b858110156132c75781548a8201529084019082016132ae565b50505082870194505b50929695505050505050565b600082516132ee818460208701612c86565b9190910192915050565b81810381811115610af657610af66130dc565b602080825260139082015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b604082015260600190565b80820180821115610af657610af66130dc565b8082028115828204841417610af657610af66130dc565b60006020828403121561337457600080fd5b815161236981612e40565b60006020828403121561339157600080fd5b5051919050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60008351613457818460208801612c86565b83519083019061346b818360208801612c86565b01949350505050565b600082613483576134836133dd565b500690565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906134bb90830184612caa565b9695505050505050565b6000602082840312156134d757600080fd5b815161236981612c53565b634e487b7160e01b600052603160045260246000fdfea26469706673582212204b4b1618d256a256403870b0e2e5681c53809d68b3802be315781b0473fd5cdf64736f6c634300081200334552433732313a207472616e7366657220746f206e6f6e20455243373231526500000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064f25ee00000000000000000000000000000000000000000000000000000000064f25ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043697066733a2f2f62616679626569687a35706a6d737934626e753662363766716a696e6c326e3575727236346363366c6f6b3665756562786464366b326e676c7a752f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043697066733a2f2f62616679626569687a35706a6d737934626e753662363766716a696e6c326e3575727236346363366c6f6b3665756562786464366b326e676c7a752f0000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x60806040526004361061038c5760003560e01c8063714c5398116101dc578063b88d4fde11610102578063e985e9c5116100a0578063f2fde38b1161006f578063f2fde38b14610a6b578063f46a04eb14610a8b578063fa0cf53814610aab578063fee9d13b14610acb57600080fd5b8063e985e9c5146109cd578063ea05a8c614610a16578063ed84fc9114610a36578063edac985b14610a4b57600080fd5b8063d1239730116100dc578063d123973014610969578063d48997df14610983578063d5abeb01146109a3578063e14ca353146109b857600080fd5b8063b88d4fde14610909578063c2ba474414610929578063c87b56dd1461094957600080fd5b80639a8c00351161017a578063a0e389de11610149578063a0e389de1461089d578063a22cb465146108b3578063b0d356e5146108d3578063b12dab6e146108f357600080fd5b80639a8c0035146108255780639b19251a146108455780639f181b5e14610875578063a0712d681461088a57600080fd5b80638da5cb5b116101b65780638da5cb5b146107b2578063931688cb146107d057806395d89b41146107f057806399f7e45f1461080557600080fd5b8063714c53981461075b578063715018a614610770578063839ad1d31461078557600080fd5b80632f745c59116102c157806342842e0e1161025f578063572849c41161022e578063572849c4146106ef5780636352211e146107055780636a7957321461072557806370a082311461073b57600080fd5b806342842e0e1461066f5780634b4687b51461068f5780634f6ccce7146106ae57806354214f69146106ce57600080fd5b80633af32abf1161029b5780633af32abf146105eb5780633b71275d146106245780633bd6496814610644578063413fa8e31461065957600080fd5b80632f745c591461058b5780633096b9e8146105ab57806333a5f120146105cb57600080fd5b806315f91c181161032e5780631e14d44b116103085780631e14d44b1461050b578063232452161461052b57806323b872dd1461054b5780632acc659e1461056b57600080fd5b806315f91c18146104a357806318160ddd146104d65780631e0d6eea146104eb57600080fd5b806306fdde031161036a57806306fdde03146103fa578063081812fc1461041c578063095ea7b31461045457806310d8bc091461047657600080fd5b806301f569971461039157806301ffc9a7146103b457806302ddfd21146103e4575b600080fd5b34801561039d57600080fd5b5060325b6040519081526020015b60405180910390f35b3480156103c057600080fd5b506103d46103cf366004612c69565b610aeb565b60405190151581526020016103ab565b3480156103f057600080fd5b506103a160115481565b34801561040657600080fd5b5061040f610afc565b6040516103ab9190612cd6565b34801561042857600080fd5b5061043c610437366004612ce9565b610b8e565b6040516001600160a01b0390911681526020016103ab565b34801561046057600080fd5b5061047461046f366004612d1e565b610bb5565b005b34801561048257600080fd5b506103a1610491366004612d48565b600e6020526000908152604090205481565b3480156104af57600080fd5b507f00000000000000000000000000000000000000000000000000000000000015b36103a1565b3480156104e257600080fd5b506008546103a1565b3480156104f757600080fd5b50610474610506366004612d63565b610ccf565b34801561051757600080fd5b50610474610526366004612ce9565b610ce5565b34801561053757600080fd5b50610474610546366004612d8f565b610cf2565b34801561055757600080fd5b50610474610566366004612e04565b610d6c565b34801561057757600080fd5b506103a1610586366004612d48565b610d9d565b34801561059757600080fd5b506103a16105a6366004612d1e565b610dfa565b3480156105b757600080fd5b506104746105c6366004612e4e565b610e90565b3480156105d757600080fd5b506103d46105e6366004612d48565b610eb4565b3480156105f757600080fd5b506103d4610606366004612d48565b6001600160a01b03166000908152600d602052604090205460ff1690565b34801561063057600080fd5b506017546103d49062010000900460ff1681565b34801561065057600080fd5b50610474610f04565b34801561066557600080fd5b506103a160135481565b34801561067b57600080fd5b5061047461068a366004612e04565b610f21565b34801561069b57600080fd5b506017546103d490610100900460ff1681565b3480156106ba57600080fd5b506103a16106c9366004612ce9565b610f3c565b3480156106da57600080fd5b506017546103d4906301000000900460ff1681565b3480156106fb57600080fd5b506103a160185481565b34801561071157600080fd5b5061043c610720366004612ce9565b610fcf565b34801561073157600080fd5b506103a1600f5481565b34801561074757600080fd5b506103a1610756366004612d48565b61102f565b34801561076757600080fd5b5061040f6110b5565b34801561077c57600080fd5b506104746110c4565b34801561079157600080fd5b506107a56107a0366004612d48565b6110d8565b6040516103ab9190612e6b565b3480156107be57600080fd5b50600c546001600160a01b031661043c565b3480156107dc57600080fd5b506104746107eb366004612f3b565b611180565b3480156107fc57600080fd5b5061040f611198565b34801561081157600080fd5b50610474610820366004612d48565b6111a7565b34801561083157600080fd5b50610474610840366004612f3b565b6111d1565b34801561085157600080fd5b506103d4610860366004612d48565b600d6020526000908152604090205460ff1681565b34801561088157600080fd5b50600a546103a1565b610474610898366004612ce9565b6111e5565b3480156108a957600080fd5b506103a160125481565b3480156108bf57600080fd5b506104746108ce366004612f84565b6112cd565b3480156108df57600080fd5b5060145461043c906001600160a01b031681565b3480156108ff57600080fd5b506103a160105481565b34801561091557600080fd5b50610474610924366004612fbb565b6112d8565b34801561093557600080fd5b506103a1610944366004612d48565b611310565b34801561095557600080fd5b5061040f610964366004612ce9565b61138d565b34801561097557600080fd5b506017546103d49060ff1681565b34801561098f57600080fd5b5061047461099e366004613037565b6113e7565b3480156109af57600080fd5b506115b36103a1565b3480156109c457600080fd5b506103a16113fa565b3480156109d957600080fd5b506103d46109e8366004613059565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610a2257600080fd5b50610474610a31366004612e4e565b61142f565b348015610a4257600080fd5b50610474611451565b348015610a5757600080fd5b50610474610a66366004612d8f565b611537565b348015610a7757600080fd5b50610474610a86366004612d48565b6115b1565b348015610a9757600080fd5b50610474610aa6366004612e4e565b611627565b348015610ab757600080fd5b50610474610ac6366004612ce9565b611642565b348015610ad757600080fd5b50610474610ae6366004612d48565b61199e565b6000610af682611bb7565b92915050565b606060008054610b0b9061308c565b80601f0160208091040260200160405190810160405280929190818152602001828054610b379061308c565b8015610b845780601f10610b5957610100808354040283529160200191610b84565b820191906000526020600020905b815481529060010190602001808311610b6757829003601f168201915b5050505050905090565b6000610b9982611bdc565b506000908152600460205260409020546001600160a01b031690565b6000610bc082610fcf565b9050806001600160a01b0316836001600160a01b031603610c325760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b0382161480610c4e5750610c4e81336109e8565b610cc05760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610c29565b610cca8383611c3b565b505050565b610cd7611ca9565b600f92909255601055601355565b610ced611ca9565b601855565b610cfa611ca9565b60005b81811015610cca576000600d6000858585818110610d1d57610d1d6130c6565b9050602002016020810190610d329190612d48565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905580610d64816130f2565b915050610cfd565b610d763382611d03565b610d925760405162461bcd60e51b8152600401610c299061310b565b610cca838383611d82565b600f546001600160a01b0382166000908152600d602052604081205490919060ff161515600103610dcd57506010545b600c546001600160a01b03166001600160a01b0316836001600160a01b031603610af65750600092915050565b6000610e058361102f565b8210610e675760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610c29565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610e98611ca9565b60178054911515620100000262ff000019909216919091179055565b60175460009060ff1680610eca57506012544210155b80610af657506001600160a01b0382166000908152600d602052604090205460ff1615156001148015610af6575060115442101592915050565b610f0c611ca9565b6017805463ff00000019166301000000179055565b610cca838383604051806020016040528060008152506112d8565b6000610f4760085490565b8210610faa5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610c29565b60088281548110610fbd57610fbd6130c6565b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b031680610af65760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c29565b60006001600160a01b0382166110995760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610c29565b506001600160a01b031660009081526003602052604090205490565b60606110bf611ef3565b905090565b6110cc611ca9565b6110d66000611f02565b565b606060006110e58361102f565b905060008167ffffffffffffffff81111561110257611102612eaf565b60405190808252806020026020018201604052801561112b578160200160208202803683370190505b50905060005b828110156111785760006111458683610dfa565b90508083838151811061115a5761115a6130c6565b60209081029190910101525080611170816130f2565b915050611131565b509392505050565b611188611ca9565b601561119482826131a6565b5050565b606060018054610b0b9061308c565b6111af611ca9565b601480546001600160a01b0319166001600160a01b0392909216919091179055565b6111d9611ca9565b601661119482826131a6565b60175460ff16806111f857506012544210155b806112245750336000908152600d602052604090205460ff161515600114801561122457506011544210155b6112605760405162461bcd60e51b815260206004820152600d60248201526c135a5b9d08111a5cd8589b1959609a1b6044820152606401610c29565b601754610100900460ff16156112c157336000908152600d602052604090205460ff166112c15760405162461bcd60e51b815260206004820152600f60248201526e139bdd0815da1a5d195b1a5cdd1959608a1b6044820152606401610c29565b6112ca81611f54565b50565b611194338383612208565b6112e23383611d03565b6112fe5760405162461bcd60e51b8152600401610c299061310b565b61130a848484846122d6565b50505050565b60175460009060ff161515810361132957506000919050565b60175460ff610100909104161515600114801561135f57506001600160a01b0382166000908152600d602052604090205460ff16155b1561136c57506000919050565b6115b361137860085490565b1061138557506000919050565b506032919050565b6017546060906301000000900460ff1615156001146113ce5760166040516020016113b89190613266565b6040516020818303038152906040529050919050565b6113d782612309565b6040516020016113b891906132dc565b6113ef611ca9565b601291909155601155565b6000611405600a5490565b6110bf907f00000000000000000000000000000000000000000000000000000000000015b36132f8565b611437611ca9565b601780549115156101000261ff0019909216919091179055565b611459611ca9565b6000471161149f5760405162461bcd60e51b815260206004820152601360248201527227379022aa24103a37903bb4ba34323930bb9760691b6044820152606401610c29565b604051600090339047908381818185875af1925050503d80600081146114e1576040519150601f19603f3d011682016040523d82523d6000602084013e6114e6565b606091505b50509050806112ca5760405162461bcd60e51b815260206004820152601760248201527f4661696c656420746f207769746864726177204554482e0000000000000000006044820152606401610c29565b61153f611ca9565b60005b81811015610cca576001600d6000858585818110611562576115626130c6565b90506020020160208101906115779190612d48565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055806115a9816130f2565b915050611542565b6115b9611ca9565b6001600160a01b03811661161e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c29565b6112ca81611f02565b61162f611ca9565b6017805460ff1916911515919091179055565b60175460ff168061165557506012544210155b806116815750336000908152600d602052604090205460ff161515600114801561168157506011544210155b6116bd5760405162461bcd60e51b815260206004820152600d60248201526c135a5b9d08111a5cd8589b1959609a1b6044820152606401610c29565b601754610100900460ff161561171e57336000908152600d602052604090205460ff1661171e5760405162461bcd60e51b815260206004820152600f60248201526e139bdd0815da1a5d195b1a5cdd1959608a1b6044820152606401610c29565b60175462010000900460ff16151560011461177b5760405162461bcd60e51b815260206004820152601f60248201527f455243323020546f6b656e204d696e74696e672069732064697361626c6564006044820152606401610c29565b603281111561179c5760405162461bcd60e51b8152600401610c299061330b565b600081116117bc5760405162461bcd60e51b8152600401610c299061330b565b6115b3816117c960085490565b6117d39190613338565b111561181c5760405162461bcd60e51b8152602060048201526018602482015277115e18d959591a5b99c813585e08135a5b9d0810dbdd5b9d60421b6044820152606401610c29565b60185415806118475750601854336000908152600e6020526040902054611844908390613338565b11155b8061185c5750600c546001600160a01b031633145b6118a85760405162461bcd60e51b815260206004820152601e60248201527f457863656564696e67204d6178204d696e7420506572204164647265737300006044820152606401610c29565b6000816013546118b8919061334b565b6014546040516323b872dd60e01b8152336004820152306024820152604481018390529192506001600160a01b0316906323b872dd906064016020604051808303816000875af1158015611910573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119349190613362565b5060005b8281101561197557600061194b60085490565b611956906001613338565b90506119623382612370565b508061196d816130f2565b915050611938565b50336000908152600e602052604081208054849290611995908490613338565b90915550505050565b6119a6611ca9565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156119ed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a11919061337f565b11611a565760405162461bcd60e51b81526020600482015260156024820152742737903a37b5b2b739903a37903932b1b7bb32b91760591b6044820152606401610c29565b6040516370a0823160e01b81523060048201526001600160a01b0382169063a9059cbb90339083906370a0823190602401602060405180830381865afa158015611aa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac8919061337f565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015611b13573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111949190613362565b600080611b426113fa565b11611b8f5760405162461bcd60e51b815260206004820152601860248201527f4e6f206d6f726520746f6b656e7320617661696c61626c6500000000000000006044820152606401610c29565b600a8054906000611b9f836130f2565b91905055905090565b6001600160a01b03163b151590565b60006001600160e01b0319821663780e9d6360e01b1480610af65750610af68261238a565b6000818152600260205260409020546001600160a01b03166112ca5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c29565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611c7082610fcf565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600c546001600160a01b031633146110d65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c29565b600080611d0f83610fcf565b9050806001600160a01b0316846001600160a01b03161480611d5657506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80611d7a5750836001600160a01b0316611d6f84610b8e565b6001600160a01b0316145b949350505050565b826001600160a01b0316611d9582610fcf565b6001600160a01b031614611dbb5760405162461bcd60e51b8152600401610c2990613398565b6001600160a01b038216611e1d5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610c29565b611e2a83838360016123da565b826001600160a01b0316611e3d82610fcf565b6001600160a01b031614611e635760405162461bcd60e51b8152600401610c2990613398565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b606060158054610b0b9061308c565b600c80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6032811115611f755760405162461bcd60e51b8152600401610c299061330b565b60008111611f955760405162461bcd60e51b8152600401610c299061330b565b6115b381611fa260085490565b611fac9190613338565b1115611ff55760405162461bcd60e51b8152602060048201526018602482015277115e18d959591a5b99c813585e08135a5b9d0810dbdd5b9d60421b6044820152606401610c29565b60185415806120205750601854336000908152600e602052604090205461201d908390613338565b11155b806120355750600c546001600160a01b031633145b6120815760405162461bcd60e51b815260206004820152601e60248201527f457863656564696e67204d6178204d696e7420506572204164647265737300006044820152606401610c29565b60008161208d33610d9d565b612097919061334b565b90506000813414806120b35750600c546001600160a01b031633145b6120f65760405162461bcd60e51b8152602060048201526014602482015273125b9cdd59999a58da595b9d0814185e5b595b9d60621b6044820152606401610c29565b80156121aa576040516000907316d934b9646d9da51db92627bf0070be0ab723899083908381818185875af1925050503d8060008114612152576040519150601f19603f3d011682016040523d82523d6000602084013e612157565b606091505b50509050806121a85760405162461bcd60e51b815260206004820152601b60248201527f4661696c656420746f2073656e64206f70657261746f722066656500000000006044820152606401610c29565b505b60005b838110156121de5760006121bf61250e565b90506121cb3382612370565b50806121d6816130f2565b9150506121ad565b50336000908152600e6020526040812080548592906121fe908490613338565b9091555050505050565b816001600160a01b0316836001600160a01b0316036122695760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610c29565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6122e1848484611d82565b6122ed8484848461268b565b61130a5760405162461bcd60e51b8152600401610c29906133f3565b606061231482611bdc565b600061231e611ef3565b9050600081511161233e5760405180602001604052806000815250612369565b806123488461278c565b604051602001612359929190613445565b6040516020818303038152906040525b9392505050565b61119482826040518060200160405280600081525061281f565b60006001600160e01b031982166380ac58cd60e01b14806123bb57506001600160e01b03198216635b5e139f60e01b145b80610af657506301ffc9a760e01b6001600160e01b0319831614610af6565b60018111156124495760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610c29565b816001600160a01b0385166124a5576124a081600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6124c8565b836001600160a01b0316856001600160a01b0316146124c8576124c88582612852565b6001600160a01b0384166124e4576124df816128ef565b612507565b846001600160a01b0316846001600160a01b03161461250757612507848261299e565b5050505050565b60008061251a600a5490565b612544907f00000000000000000000000000000000000000000000000000000000000015b36132f8565b6040516bffffffffffffffffffffffff1933606090811b8216602084015241901b166034820152446048820152456068820152426088820152909150600090829060a8016040516020818303038152906040528051906020012060001c6125ab9190613474565b6000818152600b60205260408120549192509081036125cb5750806125dc565b506000818152600b60205260409020545b600b60006125eb6001866132f8565b8152602001908152602001600020546000036126205761260c6001846132f8565b6000838152600b6020526040902055612650565b600b600061262f6001866132f8565b81526020808201929092526040908101600090812054858252600b90935220555b612658611b37565b506126837f000000000000000000000000000000000000000000000000000000000000000182613338565b935050505090565b60006001600160a01b0384163b1561278157604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906126cf903390899088908890600401613488565b6020604051808303816000875af192505050801561270a575060408051601f3d908101601f19168201909252612707918101906134c5565b60015b612767573d808015612738576040519150601f19603f3d011682016040523d82523d6000602084013e61273d565b606091505b50805160000361275f5760405162461bcd60e51b8152600401610c29906133f3565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611d7a565b506001949350505050565b60606000612799836129e2565b600101905060008167ffffffffffffffff8111156127b9576127b9612eaf565b6040519080825280601f01601f1916602001820160405280156127e3576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846127ed57509392505050565b6128298383612aba565b612836600084848461268b565b610cca5760405162461bcd60e51b8152600401610c29906133f3565b6000600161285f8461102f565b61286991906132f8565b6000838152600760205260409020549091508082146128bc576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612901906001906132f8565b60008381526009602052604081205460088054939450909284908110612929576129296130c6565b90600052602060002001549050806008838154811061294a5761294a6130c6565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612982576129826134e2565b6001900381819060005260206000200160009055905550505050565b60006129a98361102f565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310612a215772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612a4d576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310612a6b57662386f26fc10000830492506010015b6305f5e1008310612a83576305f5e100830492506008015b6127108310612a9757612710830492506004015b60648310612aa9576064830492506002015b600a8310610af65760010192915050565b6001600160a01b038216612b105760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610c29565b6000818152600260205260409020546001600160a01b031615612b755760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c29565b612b836000838360016123da565b6000818152600260205260409020546001600160a01b031615612be85760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c29565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160e01b0319811681146112ca57600080fd5b600060208284031215612c7b57600080fd5b813561236981612c53565b60005b83811015612ca1578181015183820152602001612c89565b50506000910152565b60008151808452612cc2816020860160208601612c86565b601f01601f19169290920160200192915050565b6020815260006123696020830184612caa565b600060208284031215612cfb57600080fd5b5035919050565b80356001600160a01b0381168114612d1957600080fd5b919050565b60008060408385031215612d3157600080fd5b612d3a83612d02565b946020939093013593505050565b600060208284031215612d5a57600080fd5b61236982612d02565b600080600060608486031215612d7857600080fd5b505081359360208301359350604090920135919050565b60008060208385031215612da257600080fd5b823567ffffffffffffffff80821115612dba57600080fd5b818501915085601f830112612dce57600080fd5b813581811115612ddd57600080fd5b8660208260051b8501011115612df257600080fd5b60209290920196919550909350505050565b600080600060608486031215612e1957600080fd5b612e2284612d02565b9250612e3060208501612d02565b9150604084013590509250925092565b80151581146112ca57600080fd5b600060208284031215612e6057600080fd5b813561236981612e40565b6020808252825182820181905260009190848201906040850190845b81811015612ea357835183529284019291840191600101612e87565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612ee057612ee0612eaf565b604051601f8501601f19908116603f01168101908282118183101715612f0857612f08612eaf565b81604052809350858152868686011115612f2157600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215612f4d57600080fd5b813567ffffffffffffffff811115612f6457600080fd5b8201601f81018413612f7557600080fd5b611d7a84823560208401612ec5565b60008060408385031215612f9757600080fd5b612fa083612d02565b91506020830135612fb081612e40565b809150509250929050565b60008060008060808587031215612fd157600080fd5b612fda85612d02565b9350612fe860208601612d02565b925060408501359150606085013567ffffffffffffffff81111561300b57600080fd5b8501601f8101871361301c57600080fd5b61302b87823560208401612ec5565b91505092959194509250565b6000806040838503121561304a57600080fd5b50508035926020909101359150565b6000806040838503121561306c57600080fd5b61307583612d02565b915061308360208401612d02565b90509250929050565b600181811c908216806130a057607f821691505b6020821081036130c057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201613104576131046130dc565b5060010190565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b601f821115610cca57600081815260208120601f850160051c8101602086101561317f5750805b601f850160051c820191505b8181101561319e5782815560010161318b565b505050505050565b815167ffffffffffffffff8111156131c0576131c0612eaf565b6131d4816131ce845461308c565b84613158565b602080601f83116001811461320957600084156131f15750858301515b600019600386901b1c1916600185901b17855561319e565b600085815260208120601f198616915b8281101561323857888601518255948401946001909101908401613219565b50858210156132565787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008083546132748161308c565b6001828116801561328c57600181146132a1576132d0565b60ff19841687528215158302870194506132d0565b8760005260208060002060005b858110156132c75781548a8201529084019082016132ae565b50505082870194505b50929695505050505050565b600082516132ee818460208701612c86565b9190910192915050565b81810381811115610af657610af66130dc565b602080825260139082015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b604082015260600190565b80820180821115610af657610af66130dc565b8082028115828204841417610af657610af66130dc565b60006020828403121561337457600080fd5b815161236981612e40565b60006020828403121561339157600080fd5b5051919050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60008351613457818460208801612c86565b83519083019061346b818360208801612c86565b01949350505050565b600082613483576134836133dd565b500690565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906134bb90830184612caa565b9695505050505050565b6000602082840312156134d757600080fd5b815161236981612c53565b634e487b7160e01b600052603160045260246000fdfea26469706673582212204b4b1618d256a256403870b0e2e5681c53809d68b3802be315781b0473fd5cdf64736f6c63430008120033

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

00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064f25ee00000000000000000000000000000000000000000000000000000000064f25ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043697066733a2f2f62616679626569687a35706a6d737934626e753662363766716a696e6c326e3575727236346363366c6f6b3665756562786464366b326e676c7a752f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043697066733a2f2f62616679626569687a35706a6d737934626e753662363766716a696e6c326e3575727236346363366c6f6b3665756562786464366b326e676c7a752f0000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _nftBaseURI (string): ipfs://bafybeihz5pjmsy4bnu6b67fqjinl2n5urr64cc6lok6euebxdd6k2nglzu/
Arg [1] : _nftRevealURI (string): ipfs://bafybeihz5pjmsy4bnu6b67fqjinl2n5urr64cc6lok6euebxdd6k2nglzu/
Arg [2] : _initialTeamReserve (uint256): 0
Arg [3] : _mintStartTimestamp (uint256): 1693605600
Arg [4] : _whitelistMintStartTimestamp (uint256): 1693605600
Arg [5] : _maxMintPerAddress (uint256): 0

-----Encoded View---------------
14 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 0000000000000000000000000000000000000000000000000000000064f25ee0
Arg [4] : 0000000000000000000000000000000000000000000000000000000064f25ee0
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000043
Arg [7] : 697066733a2f2f62616679626569687a35706a6d737934626e75366236376671
Arg [8] : 6a696e6c326e3575727236346363366c6f6b3665756562786464366b326e676c
Arg [9] : 7a752f0000000000000000000000000000000000000000000000000000000000
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000043
Arg [11] : 697066733a2f2f62616679626569687a35706a6d737934626e75366236376671
Arg [12] : 6a696e6c326e3575727236346363366c6f6b3665756562786464366b326e676c
Arg [13] : 7a752f0000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

72019:10469:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79984:113;;;;;;;;;;-1:-1:-1;72180:2:0;79984:113;;;160:25:1;;;148:2;133:18;79984:113:0;;;;;;;;81574:179;;;;;;;;;;-1:-1:-1;81574:179:0;;;;;:::i;:::-;;:::i;:::-;;;747:14:1;;740:22;722:41;;710:2;695:18;81574:179:0;582:187:1;72374:42:0;;;;;;;;;;;;;;;;47330:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;48842:171::-;;;;;;;;;;-1:-1:-1;48842:171:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1879:32:1;;;1861:51;;1849:2;1834:18;48842:171:0;1715:203:1;48360:416:0;;;;;;;;;;-1:-1:-1;48360:416:0;;;;;:::i;:::-;;:::i;:::-;;72239:49;;;;;;;;;;-1:-1:-1;72239:49:0;;;;;:::i;:::-;;;;;;;;;;;;;;725:105;;;;;;;;;;-1:-1:-1;803:19:0;725:105;;63921:113;;;;;;;;;;-1:-1:-1;64009:10:0;:17;63921:113;;75981:329;;;;;;;;;;-1:-1:-1;75981:329:0;;;;;:::i;:::-;;:::i;75070:150::-;;;;;;;;;;-1:-1:-1;75070:150:0;;;;;:::i;:::-;;:::i;79429:216::-;;;;;;;;;;-1:-1:-1;79429:216:0;;;;;:::i;:::-;;:::i;49542:301::-;;;;;;;;;;-1:-1:-1;49542:301:0;;;;;:::i;:::-;;:::i;79653:323::-;;;;;;;;;;-1:-1:-1;79653:323:0;;;;;:::i;:::-;;:::i;63589:256::-;;;;;;;;;;-1:-1:-1;63589:256:0;;;;;:::i;:::-;;:::i;75688:127::-;;;;;;;;;;-1:-1:-1;75688:127:0;;;;;:::i;:::-;;:::i;74683:293::-;;;;;;;;;;-1:-1:-1;74683:293:0;;;;;:::i;:::-;;:::i;81241:113::-;;;;;;;;;;-1:-1:-1;81241:113:0;;;;;:::i;:::-;-1:-1:-1;;;;;81327:19:0;81303:4;81327:19;;;:9;:19;;;;;;;;;81241:113;72906:28;;;;;;;;;;-1:-1:-1;72906:28:0;;;;;;;;;;;74984:78;;;;;;;;;;;;;:::i;72465:40::-;;;;;;;;;;;;;;;;49914:151;;;;;;;;;;-1:-1:-1;49914:151:0;;;;;:::i;:::-;;:::i;72874:25::-;;;;;;;;;;-1:-1:-1;72874:25:0;;;;;;;;;;;64111:233;;;;;;;;;;-1:-1:-1;64111:233:0;;;;;:::i;:::-;;:::i;72941:22::-;;;;;;;;;;-1:-1:-1;72941:22:0;;;;;;;;;;;72970:32;;;;;;;;;;;;;;;;47040:223;;;;;;;;;;-1:-1:-1;47040:223:0;;;;;:::i;:::-;;:::i;72297:29::-;;;;;;;;;;;;;;;;46771:207;;;;;;;;;;-1:-1:-1;46771:207:0;;;;;:::i;:::-;;:::i;81470:96::-;;;;;;;;;;;;;:::i;71092:103::-;;;;;;;;;;;;;:::i;82053:432::-;;;;;;;;;;-1:-1:-1;82053:432:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;70451:87::-;;;;;;;;;;-1:-1:-1;70524:6:0;;-1:-1:-1;;;;;70524:6:0;70451:87;;75228:101;;;;;;;;;;-1:-1:-1;75228:101:0;;;;;:::i;:::-;;:::i;47499:104::-;;;;;;;;;;;;;:::i;75823:150::-;;;;;;;;;;-1:-1:-1;75823:150:0;;;;;:::i;:::-;;:::i;75337:105::-;;;;;;;;;;-1:-1:-1;75337:105:0;;;;;:::i;:::-;;:::i;72191:41::-;;;;;;;;;;-1:-1:-1;72191:41:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;1020:89;;;;;;;;;;-1:-1:-1;1090:11:0;;1020:89;;76597:132;;;;;;:::i;:::-;;:::i;72423:33::-;;;;;;;;;;;;;;;;49085:155;;;;;;;;;;-1:-1:-1;49085:155:0;;;;;:::i;:::-;;:::i;72512:32::-;;;;;;;;;;-1:-1:-1;72512:32:0;;;;-1:-1:-1;;;;;72512:32:0;;;72333;;;;;;;;;;;;;;;;50136:279;;;;;;;;;;-1:-1:-1;50136:279:0;;;;;:::i;:::-;;:::i;80105:376::-;;;;;;;;;;-1:-1:-1;80105:376:0;;;;;:::i;:::-;;:::i;81761:284::-;;;;;;;;;;-1:-1:-1;81761:284:0;;;;;:::i;:::-;;:::i;72844:23::-;;;;;;;;;;-1:-1:-1;72844:23:0;;;;;;;;76318:271;;;;;;;;;;-1:-1:-1;76318:271:0;;;;;:::i;:::-;;:::i;81146:87::-;;;;;;;;;;-1:-1:-1;72125:4:0;81146:87;;1215:122;;;;;;;;;;;;;:::i;49311:164::-;;;;;;;;;;-1:-1:-1;49311:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;49432:25:0;;;49408:4;49432:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;49311:164;75565:115;;;;;;;;;;-1:-1:-1;75565:115:0;;;;;:::i;:::-;;:::i;80489:293::-;;;;;;;;;;;;;:::i;79209:212::-;;;;;;;;;;-1:-1:-1;79209:212:0;;;;;:::i;:::-;;:::i;71350:201::-;;;;;;;;;;-1:-1:-1;71350:201:0;;;;;:::i;:::-;;:::i;75450:107::-;;;;;;;;;;-1:-1:-1;75450:107:0;;;;;:::i;:::-;;:::i;76737:1068::-;;;;;;;;;;-1:-1:-1;76737:1068:0;;;;;:::i;:::-;;:::i;80790:348::-;;;;;;;;;;-1:-1:-1;80790:348:0;;;;;:::i;:::-;;:::i;81574:179::-;81685:4;81709:36;81733:11;81709:23;:36::i;:::-;81702:43;81574:179;-1:-1:-1;;81574:179:0:o;47330:100::-;47384:13;47417:5;47410:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47330:100;:::o;48842:171::-;48918:7;48938:23;48953:7;48938:14;:23::i;:::-;-1:-1:-1;48981:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;48981:24:0;;48842:171::o;48360:416::-;48441:13;48457:23;48472:7;48457:14;:23::i;:::-;48441:39;;48505:5;-1:-1:-1;;;;;48499:11:0;:2;-1:-1:-1;;;;;48499:11:0;;48491:57;;;;-1:-1:-1;;;48491:57:0;;8153:2:1;48491:57:0;;;8135:21:1;8192:2;8172:18;;;8165:30;8231:34;8211:18;;;8204:62;-1:-1:-1;;;8282:18:1;;;8275:31;8323:19;;48491:57:0;;;;;;;;;44861:10;-1:-1:-1;;;;;48583:21:0;;;;:62;;-1:-1:-1;48608:37:0;48625:5;44861:10;49311:164;:::i;48608:37::-;48561:173;;;;-1:-1:-1;;;48561:173:0;;8555:2:1;48561:173:0;;;8537:21:1;8594:2;8574:18;;;8567:30;8633:34;8613:18;;;8606:62;8704:31;8684:18;;;8677:59;8753:19;;48561:173:0;8353:425:1;48561:173:0;48747:21;48756:2;48760:7;48747:8;:21::i;:::-;48430:346;48360:416;;:::o;75981:329::-;70337:13;:11;:13::i;:::-;76156:14:::1;:32:::0;;;;76199:17:::1;:38:::0;76248:25:::1;:54:::0;75981:329::o;75070:150::-;70337:13;:11;:13::i;:::-;75174:17:::1;:38:::0;75070:150::o;79429:216::-;70337:13;:11;:13::i;:::-;79520::::1;79515:123;79539:25:::0;;::::1;79515:123;;;79621:5;79590:9;:28;79600:10;;79611:5;79600:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;79590:28:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;79590:28:0;:36;;-1:-1:-1;;79590:36:0::1;::::0;::::1;;::::0;;;::::1;::::0;;79566:7;::::1;::::0;::::1;:::i;:::-;;;;79515:123;;49542:301:::0;49703:41;44861:10;49736:7;49703:18;:41::i;:::-;49695:99;;;;-1:-1:-1;;;49695:99:0;;;;;;;:::i;:::-;49807:28;49817:4;49823:2;49827:7;49807:9;:28::i;79653:323::-;79749:14;;-1:-1:-1;;;;;79780:18:0;;79709:7;79780:18;;;:9;:18;;;;;;79709:7;;79749:14;79780:18;;:26;;:18;:26;79776:88;;-1:-1:-1;79835:17:0;;79776:88;70524:6;;-1:-1:-1;;;;;70524:6:0;-1:-1:-1;;;;;79880:18:0;:7;-1:-1:-1;;;;;79880:18:0;;79876:64;;-1:-1:-1;79927:1:0;79959:9;79653:323;-1:-1:-1;;79653:323:0:o;63589:256::-;63686:7;63722:23;63739:5;63722:16;:23::i;:::-;63714:5;:31;63706:87;;;;-1:-1:-1;;;63706:87:0;;9803:2:1;63706:87:0;;;9785:21:1;9842:2;9822:18;;;9815:30;9881:34;9861:18;;;9854:62;-1:-1:-1;;;9932:18:1;;;9925:41;9983:19;;63706:87:0;9601:407:1;63706:87:0;-1:-1:-1;;;;;;63811:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;63589:256::o;75688:127::-;70337:13;:11;:13::i;:::-;75771:16:::1;:36:::0;;;::::1;;::::0;::::1;-1:-1:-1::0;;75771:36:0;;::::1;::::0;;;::::1;::::0;;75688:127::o;74683:293::-;74788:11;;74751:4;;74788:11;;;:67;;;74836:18;;74817:15;:37;;74788:67;:180;;;-1:-1:-1;;;;;;74873:19:0;;;;;;:9;:19;;;;;;;;:27;;:19;:27;:94;;;;;74940:27;;74921:15;:46;;74768:200;74683:293;-1:-1:-1;;74683:293:0:o;74984:78::-;70337:13;:11;:13::i;:::-;75037:10:::1;:17:::0;;-1:-1:-1;;75037:17:0::1;::::0;::::1;::::0;;74984:78::o;49914:151::-;50018:39;50035:4;50041:2;50045:7;50018:39;;;;;;;;;;;;:16;:39::i;64111:233::-;64186:7;64222:30;64009:10;:17;;63921:113;64222:30;64214:5;:38;64206:95;;;;-1:-1:-1;;;64206:95:0;;10215:2:1;64206:95:0;;;10197:21:1;10254:2;10234:18;;;10227:30;10293:34;10273:18;;;10266:62;-1:-1:-1;;;10344:18:1;;;10337:42;10396:19;;64206:95:0;10013:408:1;64206:95:0;64319:10;64330:5;64319:17;;;;;;;;:::i;:::-;;;;;;;;;64312:24;;64111:233;;;:::o;47040:223::-;47112:7;51773:16;;;:7;:16;;;;;;-1:-1:-1;;;;;51773:16:0;;47176:56;;;;-1:-1:-1;;;47176:56:0;;10628:2:1;47176:56:0;;;10610:21:1;10667:2;10647:18;;;10640:30;-1:-1:-1;;;10686:18:1;;;10679:54;10750:18;;47176:56:0;10426:348:1;46771:207:0;46843:7;-1:-1:-1;;;;;46871:19:0;;46863:73;;;;-1:-1:-1;;;46863:73:0;;10981:2:1;46863:73:0;;;10963:21:1;11020:2;11000:18;;;10993:30;11059:34;11039:18;;;11032:62;-1:-1:-1;;;11110:18:1;;;11103:39;11159:19;;46863:73:0;10779:405:1;46863:73:0;-1:-1:-1;;;;;;46954:16:0;;;;;:9;:16;;;;;;;46771:207::o;81470:96::-;81515:13;81548:10;:8;:10::i;:::-;81541:17;;81470:96;:::o;71092:103::-;70337:13;:11;:13::i;:::-;71157:30:::1;71184:1;71157:18;:30::i;:::-;71092:103::o:0;82053:432::-;82137:16;82166:15;82184:24;82194:13;82184:9;:24::i;:::-;82166:42;;82221:27;82265:7;82251:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;82251:22:0;;82221:52;;82289:9;82284:164;82308:7;82304:1;:11;82284:164;;;82337:18;82358:37;82378:13;82393:1;82358:19;:37::i;:::-;82337:58;;82426:10;82410;82421:1;82410:13;;;;;;;;:::i;:::-;;;;;;;;;;:26;-1:-1:-1;82317:3:0;;;;:::i;:::-;;;;82284:164;;;-1:-1:-1;82467:10:0;82053:432;-1:-1:-1;;;82053:432:0:o;75228:101::-;70337:13;:11;:13::i;:::-;75304:7:::1;:17;75314:7:::0;75304;:17:::1;:::i;:::-;;75228:101:::0;:::o;47499:104::-;47555:13;47588:7;47581:14;;;;;:::i;75823:150::-;70337:13;:11;:13::i;:::-;75927:17:::1;:38:::0;;-1:-1:-1;;;;;;75927:38:0::1;-1:-1:-1::0;;;;;75927:38:0;;;::::1;::::0;;;::::1;::::0;;75823:150::o;75337:105::-;70337:13;:11;:13::i;:::-;75415:9:::1;:19;75427:7:::0;75415:9;:19:::1;:::i;76597:132::-:0;73071:11;;;;;:71;;;73123:18;;73104:15;:37;;73071:71;:194;;;-1:-1:-1;73174:10:0;73164:21;;;;:9;:21;;;;;;;;:29;;:21;:29;:100;;;;;73237:27;;73218:15;:46;;73164:100;73049:257;;;;-1:-1:-1;;;73049:257:0;;13595:2:1;73049:257:0;;;13577:21:1;13634:2;13614:18;;;13607:30;-1:-1:-1;;;13653:18:1;;;13646:43;13706:18;;73049:257:0;13393:337:1;73049:257:0;73376:13:::1;::::0;::::1;::::0;::::1;;;73372:99;;;73428:10;81303:4:::0;81327:19;;;:9;:19;;;;;;;;73406:53:::1;;;::::0;-1:-1:-1;;;73406:53:0;;13937:2:1;73406:53:0::1;::::0;::::1;13919:21:1::0;13976:2;13956:18;;;13949:30;-1:-1:-1;;;13995:18:1;;;13988:45;14050:18;;73406:53:0::1;13735:339:1::0;73406:53:0::1;76704:17:::2;76713:7;76704:8;:17::i;:::-;76597:132:::0;:::o;49085:155::-;49180:52;44861:10;49213:8;49223;49180:18;:52::i;50136:279::-;50267:41;44861:10;50300:7;50267:18;:41::i;:::-;50259:99;;;;-1:-1:-1;;;50259:99:0;;;;;;;:::i;:::-;50369:38;50383:4;50389:2;50393:7;50402:4;50369:13;:38::i;:::-;50136:279;;;;:::o;80105:376::-;80186:11;;80162:7;;80186:11;;:20;;;;80182:61;;-1:-1:-1;80230:1:0;;80105:376;-1:-1:-1;80105:376:0:o;80182:61::-;80259:13;;;;;;;;:21;;:13;:21;:56;;;;-1:-1:-1;;;;;;81327:19:0;;81303:4;81327:19;;;:9;:19;;;;;;;;80284:31;80259:56;80255:97;;;-1:-1:-1;80339:1:0;;80105:376;-1:-1:-1;80105:376:0:o;80255:97::-;72125:4;80368:13;64009:10;:17;;63921:113;80368:13;:25;80364:66;;-1:-1:-1;80417:1:0;;80105:376;-1:-1:-1;80105:376:0:o;80364:66::-;-1:-1:-1;72180:2:0;;80105:376;-1:-1:-1;80105:376:0:o;81761:284::-;81880:10;;81850:13;;81880:10;;;;;:18;;81894:4;81880:18;81876:93;;81946:9;81929:27;;;;;;;;:::i;:::-;;;;;;;;;;;;;81915:42;;81761:284;;;:::o;81876:93::-;82012:23;82027:7;82012:14;:23::i;:::-;81995:41;;;;;;;;:::i;76318:271::-;70337:13;:11;:13::i;:::-;76472:18:::1;:40:::0;;;;76523:27:::1;:58:::0;76318:271::o;1215:122::-;1267:7;1317:12;1090:11;;;1020:89;1317:12;1294:35;;803:19;1294:35;:::i;75565:115::-;70337:13;:11;:13::i;:::-;75642::::1;:30:::0;;;::::1;;;;-1:-1:-1::0;;75642:30:0;;::::1;::::0;;;::::1;::::0;;75565:115::o;80489:293::-;70337:13;:11;:13::i;:::-;80579:1:::1;80555:21;:25;80547:57;;;::::0;-1:-1:-1;;;80547:57:0;;15555:2:1;80547:57:0::1;::::0;::::1;15537:21:1::0;15594:2;15574:18;;;15567:30;-1:-1:-1;;;15613:18:1;;;15606:49;15672:18;;80547:57:0::1;15353:343:1::0;80547:57:0::1;80636:82;::::0;80618:12:::1;::::0;80644:10:::1;::::0;80682:21:::1;::::0;80618:12;80636:82;80618:12;80636:82;80682:21;80644:10;80636:82:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80617:101;;;80739:7;80731:43;;;::::0;-1:-1:-1;;;80731:43:0;;16113:2:1;80731:43:0::1;::::0;::::1;16095:21:1::0;16152:2;16132:18;;;16125:30;16191:25;16171:18;;;16164:53;16234:18;;80731:43:0::1;15911:347:1::0;79209:212:0;70337:13;:11;:13::i;:::-;79297::::1;79292:122;79316:25:::0;;::::1;79292:122;;;79398:4;79367:9;:28;79377:10;;79388:5;79377:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;79367:28:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;79367:28:0;:35;;-1:-1:-1;;79367:35:0::1;::::0;::::1;;::::0;;;::::1;::::0;;79343:7;::::1;::::0;::::1;:::i;:::-;;;;79292:122;;71350:201:::0;70337:13;:11;:13::i;:::-;-1:-1:-1;;;;;71439:22:0;::::1;71431:73;;;::::0;-1:-1:-1;;;71431:73:0;;16465:2:1;71431:73:0::1;::::0;::::1;16447:21:1::0;16504:2;16484:18;;;16477:30;16543:34;16523:18;;;16516:62;-1:-1:-1;;;16594:18:1;;;16587:36;16640:19;;71431:73:0::1;16263:402:1::0;71431:73:0::1;71515:28;71534:8;71515:18;:28::i;75450:107::-:0;70337:13;:11;:13::i;:::-;75523:11:::1;:26:::0;;-1:-1:-1;;75523:26:0::1;::::0;::::1;;::::0;;;::::1;::::0;;75450:107::o;76737:1068::-;73071:11;;;;;:71;;;73123:18;;73104:15;:37;;73071:71;:194;;;-1:-1:-1;73174:10:0;73164:21;;;;:9;:21;;;;;;;;:29;;:21;:29;:100;;;;;73237:27;;73218:15;:46;;73164:100;73049:257;;;;-1:-1:-1;;;73049:257:0;;13595:2:1;73049:257:0;;;13577:21:1;13634:2;13614:18;;;13607:30;-1:-1:-1;;;13653:18:1;;;13646:43;13706:18;;73049:257:0;13393:337:1;73049:257:0;73376:13:::1;::::0;::::1;::::0;::::1;;;73372:99;;;73428:10;81303:4:::0;81327:19;;;:9;:19;;;;;;;;73406:53:::1;;;::::0;-1:-1:-1;;;73406:53:0;;13937:2:1;73406:53:0::1;::::0;::::1;13919:21:1::0;13976:2;13956:18;;;13949:30;-1:-1:-1;;;13995:18:1;;;13988:45;14050:18;;73406:53:0::1;13735:339:1::0;73406:53:0::1;73548:16:::2;::::0;;;::::2;;;:24;;73568:4;73548:24;73540:68;;;::::0;-1:-1:-1;;;73540:68:0;;16872:2:1;73540:68:0::2;::::0;::::2;16854:21:1::0;16911:2;16891:18;;;16884:30;16950:33;16930:18;;;16923:61;17001:18;;73540:68:0::2;16670:355:1::0;73540:68:0::2;72180:2:::3;76878:7;:35;;76870:67;;;;-1:-1:-1::0;;;76870:67:0::3;;;;;;;:::i;:::-;76966:1;76956:7;:11;76948:43;;;;-1:-1:-1::0;;;76948:43:0::3;;;;;;;:::i;:::-;72125:4;77040:7;77024:13;64009:10:::0;:17;;63921:113;77024:13:::3;:23;;;;:::i;:::-;:35;;77002:109;;;::::0;-1:-1:-1;;;77002:109:0;;17710:2:1;77002:109:0::3;::::0;::::3;17692:21:1::0;17749:2;17729:18;;;17722:30;-1:-1:-1;;;17768:18:1;;;17761:54;17832:18;;77002:109:0::3;17508:348:1::0;77002:109:0::3;77144:17;::::0;:22;;:100:::3;;-1:-1:-1::0;77227:17:0::3;::::0;77202:10:::3;77187:26;::::0;;;:14:::3;:26;::::0;;;;;:36:::3;::::0;77216:7;;77187:36:::3;:::i;:::-;:57;;77144:100;:142;;;-1:-1:-1::0;70524:6:0;;-1:-1:-1;;;;;70524:6:0;77265:10:::3;:21;77144:142;77122:222;;;::::0;-1:-1:-1;;;77122:222:0;;18063:2:1;77122:222:0::3;::::0;::::3;18045:21:1::0;18102:2;18082:18;;;18075:30;18141:32;18121:18;;;18114:60;18191:18;;77122:222:0::3;17861:354:1::0;77122:222:0::3;77357:22;77410:7;77382:25;;:35;;;;:::i;:::-;77470:17;::::0;77463:131:::3;::::0;-1:-1:-1;;;77463:131:0;;77516:10:::3;77463:131;::::0;::::3;18633:34:1::0;77549:4:0::3;18683:18:1::0;;;18676:43;18735:18;;;18728:34;;;77357:60:0;;-1:-1:-1;;;;;;77470:17:0::3;::::0;77463:38:::3;::::0;18568:18:1;;77463:131:0::3;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;77612:9;77607:141;77631:7;77627:1;:11;77607:141;;;77660:13;77676;64009:10:::0;:17;;63921:113;77676:13:::3;:17;::::0;77692:1:::3;77676:17;:::i;:::-;77660:33;;77708:28;77718:10;77730:5;77708:9;:28::i;:::-;-1:-1:-1::0;77640:3:0;::::3;::::0;::::3;:::i;:::-;;;;77607:141;;;-1:-1:-1::0;77775:10:0::3;77760:26;::::0;;;:14:::3;:26;::::0;;;;:37;;77790:7;;77760:26;:37:::3;::::0;77790:7;;77760:37:::3;:::i;:::-;::::0;;;-1:-1:-1;;;;76737:1068:0:o;80790:348::-;70337:13;:11;:13::i;:::-;80893:46:::1;::::0;-1:-1:-1;;;80893:46:0;;80933:4:::1;80893:46;::::0;::::1;1861:51:1::0;80942:1:0::1;::::0;-1:-1:-1;;;;;80893:31:0;::::1;::::0;::::1;::::0;1834:18:1;;80893:46:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:50;80871:121;;;::::0;-1:-1:-1;;;80871:121:0;;19414:2:1;80871:121:0::1;::::0;::::1;19396:21:1::0;19453:2;19433:18;;;19426:30;-1:-1:-1;;;19472:18:1;;;19465:51;19533:18;;80871:121:0::1;19212:345:1::0;80871:121:0::1;81073:46;::::0;-1:-1:-1;;;81073:46:0;;81113:4:::1;81073:46;::::0;::::1;1861:51:1::0;-1:-1:-1;;;;;81003:30:0;::::1;::::0;::::1;::::0;81048:10:::1;::::0;81003:30;;81073:31:::1;::::0;1834:18:1;;81073:46:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81003:127;::::0;-1:-1:-1;;;;;;81003:127:0::1;::::0;;;;;;-1:-1:-1;;;;;19754:32:1;;;81003:127:0::1;::::0;::::1;19736:51:1::0;19803:18;;;19796:34;19709:18;;81003:127:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;1447:114::-:0;1513:7;1703:1;1679:21;:19;:21::i;:::-;:25;1671:62;;;;-1:-1:-1;;;1671:62:0;;20043:2:1;1671:62:0;;;20025:21:1;20082:2;20062:18;;;20055:30;20121:26;20101:18;;;20094:54;20165:18;;1671:62:0;19841:348:1;1671:62:0;1540:11:::1;:13:::0;;;:11:::1;:13;::::0;::::1;:::i;:::-;;;;;1533:20;;1447:114:::0;:::o;23213:326::-;-1:-1:-1;;;;;23508:19:0;;:23;;;23213:326::o;63281:224::-;63383:4;-1:-1:-1;;;;;;63407:50:0;;-1:-1:-1;;;63407:50:0;;:90;;;63461:36;63485:11;63461:23;:36::i;58405:135::-;52175:4;51773:16;;;:7;:16;;;;;;-1:-1:-1;;;;;51773:16:0;58479:53;;;;-1:-1:-1;;;58479:53:0;;10628:2:1;58479:53:0;;;10610:21:1;10667:2;10647:18;;;10640:30;-1:-1:-1;;;10686:18:1;;;10679:54;10750:18;;58479:53:0;10426:348:1;57718:174:0;57793:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;57793:29:0;-1:-1:-1;;;;;57793:29:0;;;;;;;;:24;;57847:23;57793:24;57847:14;:23::i;:::-;-1:-1:-1;;;;;57838:46:0;;;;;;;;;;;57718:174;;:::o;70616:132::-;70524:6;;-1:-1:-1;;;;;70524:6:0;44861:10;70680:23;70672:68;;;;-1:-1:-1;;;70672:68:0;;20396:2:1;70672:68:0;;;20378:21:1;;;20415:18;;;20408:30;20474:34;20454:18;;;20447:62;20526:18;;70672:68:0;20194:356:1;52405:264:0;52498:4;52515:13;52531:23;52546:7;52531:14;:23::i;:::-;52515:39;;52584:5;-1:-1:-1;;;;;52573:16:0;:7;-1:-1:-1;;;;;52573:16:0;;:52;;;-1:-1:-1;;;;;;49432:25:0;;;49408:4;49432:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;52593:32;52573:87;;;;52653:7;-1:-1:-1;;;;;52629:31:0;:20;52641:7;52629:11;:20::i;:::-;-1:-1:-1;;;;;52629:31:0;;52573:87;52565:96;52405:264;-1:-1:-1;;;;52405:264:0:o;56370:1229::-;56495:4;-1:-1:-1;;;;;56468:31:0;:23;56483:7;56468:14;:23::i;:::-;-1:-1:-1;;;;;56468:31:0;;56460:81;;;;-1:-1:-1;;;56460:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;56560:16:0;;56552:65;;;;-1:-1:-1;;;56552:65:0;;21163:2:1;56552:65:0;;;21145:21:1;21202:2;21182:18;;;21175:30;21241:34;21221:18;;;21214:62;-1:-1:-1;;;21292:18:1;;;21285:34;21336:19;;56552:65:0;20961:400:1;56552:65:0;56630:42;56651:4;56657:2;56661:7;56670:1;56630:20;:42::i;:::-;56802:4;-1:-1:-1;;;;;56775:31:0;:23;56790:7;56775:14;:23::i;:::-;-1:-1:-1;;;;;56775:31:0;;56767:81;;;;-1:-1:-1;;;56767:81:0;;;;;;;:::i;:::-;56920:24;;;;:15;:24;;;;;;;;56913:31;;-1:-1:-1;;;;;;56913:31:0;;;;;;-1:-1:-1;;;;;57396:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;57396:20:0;;;57431:13;;;;;;;;;:18;;56913:31;57431:18;;;57471:16;;;:7;:16;;;;;;:21;;;;;;;;;;57510:27;;56936:7;;57510:27;;;48430:346;48360:416;;:::o;81362:100::-;81414:13;81447:7;81440:14;;;;;:::i;71711:191::-;71804:6;;;-1:-1:-1;;;;;71821:17:0;;;-1:-1:-1;;;;;;71821:17:0;;;;;;;71854:40;;71804:6;;;71821:17;71804:6;;71854:40;;71785:16;;71854:40;71774:128;71711:191;:::o;77813:1388::-;72180:2;77876:7;:35;;77868:67;;;;-1:-1:-1;;;77868:67:0;;;;;;;:::i;:::-;77964:1;77954:7;:11;77946:43;;;;-1:-1:-1;;;77946:43:0;;;;;;;:::i;:::-;72125:4;78038:7;78022:13;64009:10;:17;;63921:113;78022:13;:23;;;;:::i;:::-;:35;;78000:109;;;;-1:-1:-1;;;78000:109:0;;17710:2:1;78000:109:0;;;17692:21:1;17749:2;17729:18;;;17722:30;-1:-1:-1;;;17768:18:1;;;17761:54;17832:18;;78000:109:0;17508:348:1;78000:109:0;78142:17;;:22;;:100;;-1:-1:-1;78225:17:0;;78200:10;78185:26;;;;:14;:26;;;;;;:36;;78214:7;;78185:36;:::i;:::-;:57;;78142:100;:142;;;-1:-1:-1;70524:6:0;;-1:-1:-1;;;;;70524:6:0;78263:10;:21;78142:142;78120:222;;;;-1:-1:-1;;;78120:222:0;;18063:2:1;78120:222:0;;;18045:21:1;18102:2;18082:18;;;18075:30;18141:32;18121:18;;;18114:60;18191:18;;78120:222:0;17861:354:1;78120:222:0;78355:22;78403:7;78380:20;78389:10;78380:8;:20::i;:::-;:30;;;;:::i;:::-;78355:55;-1:-1:-1;78421:19:0;78677:14;78664:9;:27;:52;;;-1:-1:-1;70524:6:0;;-1:-1:-1;;;;;70524:6:0;78695:10;:21;78664:52;78642:122;;;;-1:-1:-1;;;78642:122:0;;21825:2:1;78642:122:0;;;21807:21:1;21864:2;21844:18;;;21837:30;-1:-1:-1;;;21883:18:1;;;21876:50;21943:18;;78642:122:0;21623:344:1;78642:122:0;78833:15;;78829:168;;78881:45;;78866:9;;72638:42;;78910:11;;78866:9;78881:45;78866:9;78881:45;78910:11;72638:42;78881:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78865:61;;;78949:4;78941:44;;;;-1:-1:-1;;;78941:44:0;;22174:2:1;78941:44:0;;;22156:21:1;22213:2;22193:18;;;22186:30;22252:29;22232:18;;;22225:57;22299:18;;78941:44:0;21972:351:1;78941:44:0;78850:147;78829:168;79014:9;79009:135;79033:7;79029:1;:11;79009:135;;;79062:13;79078:11;:9;:11::i;:::-;79062:27;;79104:28;79114:10;79126:5;79104:9;:28::i;:::-;-1:-1:-1;79042:3:0;;;;:::i;:::-;;;;79009:135;;;-1:-1:-1;79171:10:0;79156:26;;;;:14;:26;;;;;:37;;79186:7;;79156:26;:37;;79186:7;;79156:37;:::i;:::-;;;;-1:-1:-1;;;;;77813:1388:0:o;58035:281::-;58156:8;-1:-1:-1;;;;;58147:17:0;:5;-1:-1:-1;;;;;58147:17:0;;58139:55;;;;-1:-1:-1;;;58139:55:0;;22530:2:1;58139:55:0;;;22512:21:1;22569:2;22549:18;;;22542:30;22608:27;22588:18;;;22581:55;22653:18;;58139:55:0;22328:349:1;58139:55:0;-1:-1:-1;;;;;58205:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;58205:46:0;;;;;;;;;;58267:41;;722::1;;;58267::0;;695:18:1;58267:41:0;;;;;;;58035:281;;;:::o;51296:270::-;51409:28;51419:4;51425:2;51429:7;51409:9;:28::i;:::-;51456:47;51479:4;51485:2;51489:7;51498:4;51456:22;:47::i;:::-;51448:110;;;;-1:-1:-1;;;51448:110:0;;;;;;;:::i;47674:281::-;47747:13;47773:23;47788:7;47773:14;:23::i;:::-;47809:21;47833:10;:8;:10::i;:::-;47809:34;;47885:1;47867:7;47861:21;:25;:86;;;;;;;;;;;;;;;;;47913:7;47922:18;:7;:16;:18::i;:::-;47896:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;47861:86;47854:93;47674:281;-1:-1:-1;;;47674:281:0:o;53011:110::-;53087:26;53097:2;53101:7;53087:26;;;;;;;;;;;;:9;:26::i;46402:305::-;46504:4;-1:-1:-1;;;;;;46541:40:0;;-1:-1:-1;;;46541:40:0;;:105;;-1:-1:-1;;;;;;;46598:48:0;;-1:-1:-1;;;46598:48:0;46541:105;:158;;;-1:-1:-1;;;;;;;;;;34317:40:0;;;46663:36;34208:157;64418:915;64685:1;64673:9;:13;64669:222;;;64816:63;;-1:-1:-1;;;64816:63:0;;23804:2:1;64816:63:0;;;23786:21:1;23843:2;23823:18;;;23816:30;23882:34;23862:18;;;23855:62;-1:-1:-1;;;23933:18:1;;;23926:51;23994:19;;64816:63:0;23602:417:1;64669:222:0;64921:12;-1:-1:-1;;;;;64950:18:0;;64946:187;;64985:40;65017:7;66160:10;:17;;66133:24;;;;:15;:24;;;;;:44;;;66188:24;;;;;;;;;;;;66056:164;64985:40;64946:187;;;65055:2;-1:-1:-1;;;;;65047:10:0;:4;-1:-1:-1;;;;;65047:10:0;;65043:90;;65074:47;65107:4;65113:7;65074:32;:47::i;:::-;-1:-1:-1;;;;;65147:16:0;;65143:183;;65180:45;65217:7;65180:36;:45::i;:::-;65143:183;;;65253:4;-1:-1:-1;;;;;65247:10:0;:2;-1:-1:-1;;;;;65247:10:0;;65243:83;;65274:40;65302:2;65306:7;65274:27;:40::i;:::-;64584:749;64418:915;;;;:::o;3085:1325::-;3133:7;3153:16;3195:12;1090:11;;;1020:89;3195:12;3172:35;;803:19;3172:35;:::i;:::-;3285:219;;-1:-1:-1;;3324:10:0;24351:2:1;24347:15;;;24343:24;;3285:219:0;;;24331:37:1;3357:14:0;24402:15:1;;24398:24;24384:12;;;24377:46;3394:16:0;24439:12:1;;;24432:28;3433:14:0;24476:12:1;;;24469:28;3470:15:0;24513:13:1;;;24506:29;3153:54:0;;-1:-1:-1;3218:14:0;;3153:54;;24551:13:1;;3285:219:0;;;;;;;;;;;;3257:262;;;;;;3235:295;;:306;;;;:::i;:::-;3554:13;3586:19;;;:11;:19;;;;;;3218:323;;-1:-1:-1;3554:13:0;3586:24;;3582:304;;-1:-1:-1;3731:6:0;3582:304;;;-1:-1:-1;3855:19:0;;;;:11;:19;;;;;;3582:304;3963:11;:25;3975:12;3986:1;3975:8;:12;:::i;:::-;3963:25;;;;;;;;;;;;3992:1;3963:30;3959:331;;4097:12;4108:1;4097:8;:12;:::i;:::-;4075:19;;;;:11;:19;;;;;:34;3959:331;;;4253:11;:25;4265:12;4276:1;4265:8;:12;:::i;:::-;4253:25;;;;;;;;;;;;;;-1:-1:-1;4253:25:0;;;;4231:19;;;:11;:19;;;;:47;3959:331;4348:17;:15;:17::i;:::-;-1:-1:-1;4385:17:0;4393:9;4385:5;:17;:::i;:::-;4378:24;;;;;3085:1325;:::o;59104:853::-;59258:4;-1:-1:-1;;;;;59279:13:0;;23508:19;:23;59275:675;;59315:71;;-1:-1:-1;;;59315:71:0;;-1:-1:-1;;;;;59315:36:0;;;;;:71;;44861:10;;59366:4;;59372:7;;59381:4;;59315:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59315:71:0;;;;;;;;-1:-1:-1;;59315:71:0;;;;;;;;;;;;:::i;:::-;;;59311:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59556:6;:13;59573:1;59556:18;59552:328;;59599:60;;-1:-1:-1;;;59599:60:0;;;;;;;:::i;59552:328::-;59830:6;59824:13;59815:6;59811:2;59807:15;59800:38;59311:584;-1:-1:-1;;;;;;59437:51:0;-1:-1:-1;;;59437:51:0;;-1:-1:-1;59430:58:0;;59275:675;-1:-1:-1;59934:4:0;59104:853;;;;;;:::o;19337:716::-;19393:13;19444:14;19461:17;19472:5;19461:10;:17::i;:::-;19481:1;19461:21;19444:38;;19497:20;19531:6;19520:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19520:18:0;-1:-1:-1;19497:41:0;-1:-1:-1;19662:28:0;;;19678:2;19662:28;19719:288;-1:-1:-1;;19751:5:0;-1:-1:-1;;;19888:2:0;19877:14;;19872:30;19751:5;19859:44;19949:2;19940:11;;;-1:-1:-1;19970:21:0;19719:288;19970:21;-1:-1:-1;20028:6:0;19337:716;-1:-1:-1;;;19337:716:0:o;53348:285::-;53443:18;53449:2;53453:7;53443:5;:18::i;:::-;53494:53;53525:1;53529:2;53533:7;53542:4;53494:22;:53::i;:::-;53472:153;;;;-1:-1:-1;;;53472:153:0;;;;;;;:::i;66847:988::-;67113:22;67163:1;67138:22;67155:4;67138:16;:22::i;:::-;:26;;;;:::i;:::-;67175:18;67196:26;;;:17;:26;;;;;;67113:51;;-1:-1:-1;67329:28:0;;;67325:328;;-1:-1:-1;;;;;67396:18:0;;67374:19;67396:18;;;:12;:18;;;;;;;;:34;;;;;;;;;67447:30;;;;;;:44;;;67564:30;;:17;:30;;;;;:43;;;67325:328;-1:-1:-1;67749:26:0;;;;:17;:26;;;;;;;;67742:33;;;-1:-1:-1;;;;;67793:18:0;;;;;:12;:18;;;;;:34;;;;;;;67786:41;66847:988::o;68130:1079::-;68408:10;:17;68383:22;;68408:21;;68428:1;;68408:21;:::i;:::-;68440:18;68461:24;;;:15;:24;;;;;;68834:10;:26;;68383:46;;-1:-1:-1;68461:24:0;;68383:46;;68834:26;;;;;;:::i;:::-;;;;;;;;;68812:48;;68898:11;68873:10;68884;68873:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;68978:28;;;:15;:28;;;;;;;:41;;;69150:24;;;;;69143:31;69185:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;68201:1008;;;68130:1079;:::o;65634:221::-;65719:14;65736:20;65753:2;65736:16;:20::i;:::-;-1:-1:-1;;;;;65767:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;65812:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;65634:221:0:o;16171:948::-;16224:7;;-1:-1:-1;;;16302:17:0;;16298:106;;-1:-1:-1;;;16340:17:0;;;-1:-1:-1;16386:2:0;16376:12;16298:106;16431:8;16422:5;:17;16418:106;;16469:8;16460:17;;;-1:-1:-1;16506:2:0;16496:12;16418:106;16551:8;16542:5;:17;16538:106;;16589:8;16580:17;;;-1:-1:-1;16626:2:0;16616:12;16538:106;16671:7;16662:5;:16;16658:103;;16708:7;16699:16;;;-1:-1:-1;16744:1:0;16734:11;16658:103;16788:7;16779:5;:16;16775:103;;16825:7;16816:16;;;-1:-1:-1;16861:1:0;16851:11;16775:103;16905:7;16896:5;:16;16892:103;;16942:7;16933:16;;;-1:-1:-1;16978:1:0;16968:11;16892:103;17022:7;17013:5;:16;17009:68;;17060:1;17050:11;17105:6;16171:948;-1:-1:-1;;16171:948:0:o;53969:942::-;-1:-1:-1;;;;;54049:16:0;;54041:61;;;;-1:-1:-1;;;54041:61:0;;25774:2:1;54041:61:0;;;25756:21:1;;;25793:18;;;25786:30;25852:34;25832:18;;;25825:62;25904:18;;54041:61:0;25572:356:1;54041:61:0;52175:4;51773:16;;;:7;:16;;;;;;-1:-1:-1;;;;;51773:16:0;52199:31;54113:58;;;;-1:-1:-1;;;54113:58:0;;26135:2:1;54113:58:0;;;26117:21:1;26174:2;26154:18;;;26147:30;26213;26193:18;;;26186:58;26261:18;;54113:58:0;25933:352:1;54113:58:0;54184:48;54213:1;54217:2;54221:7;54230:1;54184:20;:48::i;:::-;52175:4;51773:16;;;:7;:16;;;;;;-1:-1:-1;;;;;51773:16:0;52199:31;54322:58;;;;-1:-1:-1;;;54322:58:0;;26135:2:1;54322:58:0;;;26117:21:1;26174:2;26154:18;;;26147:30;26213;26193:18;;;26186:58;26261:18;;54322:58:0;25933:352:1;54322:58:0;-1:-1:-1;;;;;54729:13:0;;;;;;:9;:13;;;;;;;;:18;;54746:1;54729:18;;;54771:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;54771:21:0;;;;;54810:33;54779:7;;54729:13;;54810:33;;54729:13;;54810:33;75304:17:::1;75228:101:::0;:::o;196:131:1:-;-1:-1:-1;;;;;;270:32:1;;260:43;;250:71;;317:1;314;307:12;332:245;390:6;443:2;431:9;422:7;418:23;414:32;411:52;;;459:1;456;449:12;411:52;498:9;485:23;517:30;541:5;517:30;:::i;774:250::-;859:1;869:113;883:6;880:1;877:13;869:113;;;959:11;;;953:18;940:11;;;933:39;905:2;898:10;869:113;;;-1:-1:-1;;1016:1:1;998:16;;991:27;774:250::o;1029:271::-;1071:3;1109:5;1103:12;1136:6;1131:3;1124:19;1152:76;1221:6;1214:4;1209:3;1205:14;1198:4;1191:5;1187:16;1152:76;:::i;:::-;1282:2;1261:15;-1:-1:-1;;1257:29:1;1248:39;;;;1289:4;1244:50;;1029:271;-1:-1:-1;;1029:271:1:o;1305:220::-;1454:2;1443:9;1436:21;1417:4;1474:45;1515:2;1504:9;1500:18;1492:6;1474:45;:::i;1530:180::-;1589:6;1642:2;1630:9;1621:7;1617:23;1613:32;1610:52;;;1658:1;1655;1648:12;1610:52;-1:-1:-1;1681:23:1;;1530:180;-1:-1:-1;1530:180:1:o;1923:173::-;1991:20;;-1:-1:-1;;;;;2040:31:1;;2030:42;;2020:70;;2086:1;2083;2076:12;2020:70;1923:173;;;:::o;2101:254::-;2169:6;2177;2230:2;2218:9;2209:7;2205:23;2201:32;2198:52;;;2246:1;2243;2236:12;2198:52;2269:29;2288:9;2269:29;:::i;:::-;2259:39;2345:2;2330:18;;;;2317:32;;-1:-1:-1;;;2101:254:1:o;2360:186::-;2419:6;2472:2;2460:9;2451:7;2447:23;2443:32;2440:52;;;2488:1;2485;2478:12;2440:52;2511:29;2530:9;2511:29;:::i;2551:316::-;2628:6;2636;2644;2697:2;2685:9;2676:7;2672:23;2668:32;2665:52;;;2713:1;2710;2703:12;2665:52;-1:-1:-1;;2736:23:1;;;2806:2;2791:18;;2778:32;;-1:-1:-1;2857:2:1;2842:18;;;2829:32;;2551:316;-1:-1:-1;2551:316:1:o;2872:615::-;2958:6;2966;3019:2;3007:9;2998:7;2994:23;2990:32;2987:52;;;3035:1;3032;3025:12;2987:52;3075:9;3062:23;3104:18;3145:2;3137:6;3134:14;3131:34;;;3161:1;3158;3151:12;3131:34;3199:6;3188:9;3184:22;3174:32;;3244:7;3237:4;3233:2;3229:13;3225:27;3215:55;;3266:1;3263;3256:12;3215:55;3306:2;3293:16;3332:2;3324:6;3321:14;3318:34;;;3348:1;3345;3338:12;3318:34;3401:7;3396:2;3386:6;3383:1;3379:14;3375:2;3371:23;3367:32;3364:45;3361:65;;;3422:1;3419;3412:12;3361:65;3453:2;3445:11;;;;;3475:6;;-1:-1:-1;2872:615:1;;-1:-1:-1;;;;2872:615:1:o;3492:328::-;3569:6;3577;3585;3638:2;3626:9;3617:7;3613:23;3609:32;3606:52;;;3654:1;3651;3644:12;3606:52;3677:29;3696:9;3677:29;:::i;:::-;3667:39;;3725:38;3759:2;3748:9;3744:18;3725:38;:::i;:::-;3715:48;;3810:2;3799:9;3795:18;3782:32;3772:42;;3492:328;;;;;:::o;3825:118::-;3911:5;3904:13;3897:21;3890:5;3887:32;3877:60;;3933:1;3930;3923:12;3948:241;4004:6;4057:2;4045:9;4036:7;4032:23;4028:32;4025:52;;;4073:1;4070;4063:12;4025:52;4112:9;4099:23;4131:28;4153:5;4131:28;:::i;4194:632::-;4365:2;4417:21;;;4487:13;;4390:18;;;4509:22;;;4336:4;;4365:2;4588:15;;;;4562:2;4547:18;;;4336:4;4631:169;4645:6;4642:1;4639:13;4631:169;;;4706:13;;4694:26;;4775:15;;;;4740:12;;;;4667:1;4660:9;4631:169;;;-1:-1:-1;4817:3:1;;4194:632;-1:-1:-1;;;;;;4194:632:1:o;4831:127::-;4892:10;4887:3;4883:20;4880:1;4873:31;4923:4;4920:1;4913:15;4947:4;4944:1;4937:15;4963:632;5028:5;5058:18;5099:2;5091:6;5088:14;5085:40;;;5105:18;;:::i;:::-;5180:2;5174:9;5148:2;5234:15;;-1:-1:-1;;5230:24:1;;;5256:2;5226:33;5222:42;5210:55;;;5280:18;;;5300:22;;;5277:46;5274:72;;;5326:18;;:::i;:::-;5366:10;5362:2;5355:22;5395:6;5386:15;;5425:6;5417;5410:22;5465:3;5456:6;5451:3;5447:16;5444:25;5441:45;;;5482:1;5479;5472:12;5441:45;5532:6;5527:3;5520:4;5512:6;5508:17;5495:44;5587:1;5580:4;5571:6;5563;5559:19;5555:30;5548:41;;;;4963:632;;;;;:::o;5600:451::-;5669:6;5722:2;5710:9;5701:7;5697:23;5693:32;5690:52;;;5738:1;5735;5728:12;5690:52;5778:9;5765:23;5811:18;5803:6;5800:30;5797:50;;;5843:1;5840;5833:12;5797:50;5866:22;;5919:4;5911:13;;5907:27;-1:-1:-1;5897:55:1;;5948:1;5945;5938:12;5897:55;5971:74;6037:7;6032:2;6019:16;6014:2;6010;6006:11;5971:74;:::i;6056:315::-;6121:6;6129;6182:2;6170:9;6161:7;6157:23;6153:32;6150:52;;;6198:1;6195;6188:12;6150:52;6221:29;6240:9;6221:29;:::i;:::-;6211:39;;6300:2;6289:9;6285:18;6272:32;6313:28;6335:5;6313:28;:::i;:::-;6360:5;6350:15;;;6056:315;;;;;:::o;6376:667::-;6471:6;6479;6487;6495;6548:3;6536:9;6527:7;6523:23;6519:33;6516:53;;;6565:1;6562;6555:12;6516:53;6588:29;6607:9;6588:29;:::i;:::-;6578:39;;6636:38;6670:2;6659:9;6655:18;6636:38;:::i;:::-;6626:48;;6721:2;6710:9;6706:18;6693:32;6683:42;;6776:2;6765:9;6761:18;6748:32;6803:18;6795:6;6792:30;6789:50;;;6835:1;6832;6825:12;6789:50;6858:22;;6911:4;6903:13;;6899:27;-1:-1:-1;6889:55:1;;6940:1;6937;6930:12;6889:55;6963:74;7029:7;7024:2;7011:16;7006:2;7002;6998:11;6963:74;:::i;:::-;6953:84;;;6376:667;;;;;;;:::o;7048:248::-;7116:6;7124;7177:2;7165:9;7156:7;7152:23;7148:32;7145:52;;;7193:1;7190;7183:12;7145:52;-1:-1:-1;;7216:23:1;;;7286:2;7271:18;;;7258:32;;-1:-1:-1;7048:248:1:o;7301:260::-;7369:6;7377;7430:2;7418:9;7409:7;7405:23;7401:32;7398:52;;;7446:1;7443;7436:12;7398:52;7469:29;7488:9;7469:29;:::i;:::-;7459:39;;7517:38;7551:2;7540:9;7536:18;7517:38;:::i;:::-;7507:48;;7301:260;;;;;:::o;7566:380::-;7645:1;7641:12;;;;7688;;;7709:61;;7763:4;7755:6;7751:17;7741:27;;7709:61;7816:2;7808:6;7805:14;7785:18;7782:38;7779:161;;7862:10;7857:3;7853:20;7850:1;7843:31;7897:4;7894:1;7887:15;7925:4;7922:1;7915:15;7779:161;;7566:380;;;:::o;8783:127::-;8844:10;8839:3;8835:20;8832:1;8825:31;8875:4;8872:1;8865:15;8899:4;8896:1;8889:15;8915:127;8976:10;8971:3;8967:20;8964:1;8957:31;9007:4;9004:1;8997:15;9031:4;9028:1;9021:15;9047:135;9086:3;9107:17;;;9104:43;;9127:18;;:::i;:::-;-1:-1:-1;9174:1:1;9163:13;;9047:135::o;9187:409::-;9389:2;9371:21;;;9428:2;9408:18;;;9401:30;9467:34;9462:2;9447:18;;9440:62;-1:-1:-1;;;9533:2:1;9518:18;;9511:43;9586:3;9571:19;;9187:409::o;11315:545::-;11417:2;11412:3;11409:11;11406:448;;;11453:1;11478:5;11474:2;11467:17;11523:4;11519:2;11509:19;11593:2;11581:10;11577:19;11574:1;11570:27;11564:4;11560:38;11629:4;11617:10;11614:20;11611:47;;;-1:-1:-1;11652:4:1;11611:47;11707:2;11702:3;11698:12;11695:1;11691:20;11685:4;11681:31;11671:41;;11762:82;11780:2;11773:5;11770:13;11762:82;;;11825:17;;;11806:1;11795:13;11762:82;;;11766:3;;;11315:545;;;:::o;12036:1352::-;12162:3;12156:10;12189:18;12181:6;12178:30;12175:56;;;12211:18;;:::i;:::-;12240:97;12330:6;12290:38;12322:4;12316:11;12290:38;:::i;:::-;12284:4;12240:97;:::i;:::-;12392:4;;12456:2;12445:14;;12473:1;12468:663;;;;13175:1;13192:6;13189:89;;;-1:-1:-1;13244:19:1;;;13238:26;13189:89;-1:-1:-1;;11993:1:1;11989:11;;;11985:24;11981:29;11971:40;12017:1;12013:11;;;11968:57;13291:81;;12438:944;;12468:663;11262:1;11255:14;;;11299:4;11286:18;;-1:-1:-1;;12504:20:1;;;12622:236;12636:7;12633:1;12630:14;12622:236;;;12725:19;;;12719:26;12704:42;;12817:27;;;;12785:1;12773:14;;;;12652:19;;12622:236;;;12626:3;12886:6;12877:7;12874:19;12871:201;;;12947:19;;;12941:26;-1:-1:-1;;13030:1:1;13026:14;;;13042:3;13022:24;13018:37;13014:42;12999:58;12984:74;;12871:201;-1:-1:-1;;;;;13118:1:1;13102:14;;;13098:22;13085:36;;-1:-1:-1;12036:1352:1:o;14079:842::-;14207:3;14236:1;14269:6;14263:13;14299:36;14325:9;14299:36;:::i;:::-;14354:1;14371:18;;;14398:133;;;;14545:1;14540:356;;;;14364:532;;14398:133;-1:-1:-1;;14431:24:1;;14419:37;;14504:14;;14497:22;14485:35;;14476:45;;;-1:-1:-1;14398:133:1;;14540:356;14571:6;14568:1;14561:17;14601:4;14646:2;14643:1;14633:16;14671:1;14685:165;14699:6;14696:1;14693:13;14685:165;;;14777:14;;14764:11;;;14757:35;14820:16;;;;14714:10;;14685:165;;;14689:3;;;14879:6;14874:3;14870:16;14863:23;;14364:532;-1:-1:-1;14912:3:1;;14079:842;-1:-1:-1;;;;;;14079:842:1:o;14926:289::-;15057:3;15095:6;15089:13;15111:66;15170:6;15165:3;15158:4;15150:6;15146:17;15111:66;:::i;:::-;15193:16;;;;;14926:289;-1:-1:-1;;14926:289:1:o;15220:128::-;15287:9;;;15308:11;;;15305:37;;;15322:18;;:::i;17030:343::-;17232:2;17214:21;;;17271:2;17251:18;;;17244:30;-1:-1:-1;;;17305:2:1;17290:18;;17283:49;17364:2;17349:18;;17030:343::o;17378:125::-;17443:9;;;17464:10;;;17461:36;;;17477:18;;:::i;18220:168::-;18293:9;;;18324;;18341:15;;;18335:22;;18321:37;18311:71;;18362:18;;:::i;18773:245::-;18840:6;18893:2;18881:9;18872:7;18868:23;18864:32;18861:52;;;18909:1;18906;18899:12;18861:52;18941:9;18935:16;18960:28;18982:5;18960:28;:::i;19023:184::-;19093:6;19146:2;19134:9;19125:7;19121:23;19117:32;19114:52;;;19162:1;19159;19152:12;19114:52;-1:-1:-1;19185:16:1;;19023:184;-1:-1:-1;19023:184:1:o;20555:401::-;20757:2;20739:21;;;20796:2;20776:18;;;20769:30;20835:34;20830:2;20815:18;;20808:62;-1:-1:-1;;;20901:2:1;20886:18;;20879:35;20946:3;20931:19;;20555:401::o;21366:127::-;21427:10;21422:3;21418:20;21415:1;21408:31;21458:4;21455:1;21448:15;21482:4;21479:1;21472:15;22682:414;22884:2;22866:21;;;22923:2;22903:18;;;22896:30;22962:34;22957:2;22942:18;;22935:62;-1:-1:-1;;;23028:2:1;23013:18;;23006:48;23086:3;23071:19;;22682:414::o;23101:496::-;23280:3;23318:6;23312:13;23334:66;23393:6;23388:3;23381:4;23373:6;23369:17;23334:66;:::i;:::-;23463:13;;23422:16;;;;23485:70;23463:13;23422:16;23532:4;23520:17;;23485:70;:::i;:::-;23571:20;;23101:496;-1:-1:-1;;;;23101:496:1:o;24575:112::-;24607:1;24633;24623:35;;24638:18;;:::i;:::-;-1:-1:-1;24672:9:1;;24575:112::o;24692:489::-;-1:-1:-1;;;;;24961:15:1;;;24943:34;;25013:15;;25008:2;24993:18;;24986:43;25060:2;25045:18;;25038:34;;;25108:3;25103:2;25088:18;;25081:31;;;24886:4;;25129:46;;25155:19;;25147:6;25129:46;:::i;:::-;25121:54;24692:489;-1:-1:-1;;;;;;24692:489:1:o;25186:249::-;25255:6;25308:2;25296:9;25287:7;25283:23;25279:32;25276:52;;;25324:1;25321;25314:12;25276:52;25356:9;25350:16;25375:30;25399:5;25375:30;:::i;25440:127::-;25501:10;25496:3;25492:20;25489:1;25482:31;25532:4;25529:1;25522:15;25556:4;25553:1;25546:15

Swarm Source

ipfs://4b4b1618d256a256403870b0e2e5681c53809d68b3802be315781b0473fd5cdf
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.