ETH Price: $3,151.74 (+2.38%)
Gas: 18.5 Gwei

Cosmic Labs (CLABS)
 

Overview

TokenID

2665

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

1,000 Legendary Animated Ducks I 8,000 Uniquely Generated Cosmic Ducks

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
CosmicLabs

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, Unlicense license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-11-06
*/

// File: openzeppelin-solidity/contracts/utils/math/SafeMath.sol



pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts v4.3.2 (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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 `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, 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 `sender` to `recipient` 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 sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/IERC20Metadata.sol


// OpenZeppelin Contracts v4.3.2 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Counters.sol


// OpenZeppelin Contracts v4.3.2 (utils/Counters.sol)

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/Math.sol


// OpenZeppelin Contracts v4.3.2 (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @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 / b + (a % b == 0 ? 0 : 1);
    }
}

// File: @openzeppelin/contracts/utils/structs/EnumerableSet.sol



pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastvalue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastvalue;
                // Update the index for the moved value
                set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        return _values(set._inner);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        assembly {
            result := store
        }

        return result;
    }
}

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol


// OpenZeppelin Contracts v4.3.2 (utils/Strings.sol)

pragma solidity ^0.8.0;

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

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

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Context.sol


// OpenZeppelin Contracts v4.3.2 (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: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol


// OpenZeppelin Contracts v4.3.2 (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;




/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

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

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        unchecked {
            _approve(sender, _msgSender(), currentAllowance - amount);
        }

        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);

        _afterTokenTransfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

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

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

// File: Artifacts/cosmicToken.sol

pragma solidity 0.8.7;



interface IDuck {
	function balanceOG(address _user) external view returns(uint256);
}

contract CosmicToken is ERC20("CosmicUtilityToken", "CUT") 
{
   
    using SafeMath for uint256;
   
    uint256 public totalTokensBurned = 0;
    address[] internal stakeholders;
    address  payable private owner;
    

    //token Genesis per day
    uint256 constant public GENESIS_RATE = 20 ether; 
    
    //token duck per day
    uint256 constant public DUCK_RATE = 5 ether; 
    
    //token for  genesis minting
	uint256 constant public GENESIS_ISSUANCE = 280 ether;
	
	//token for duck minting
	uint256 constant public DUCK_ISSUANCE = 70 ether;
	
	
	
	// Tue Mar 18 2031 17:46:47 GMT+0000
	uint256 constant public END = 1931622407;

	mapping(address => uint256) public rewards;
	mapping(address => uint256) public lastUpdate;
	
	
    IDuck public ducksContract;
   
    constructor(address initDuckContract) 
    {
        owner = payable(msg.sender);
        ducksContract = IDuck(initDuckContract);
    }
   

    function WhoOwns() public view returns (address) {
        return owner;
    }
   
    modifier Owned {
         require(msg.sender == owner);
         _;
 }
   
    function getContractAddress() public view returns (address) {
        return address(this);
    }

	function min(uint256 a, uint256 b) internal pure returns (uint256) {
		return a < b ? a : b;
	}    
	
	modifier contractAddressOnly
    {
         require(msg.sender == address(ducksContract));
         _;
    }
    
   	// called when minting many NFTs
	function updateRewardOnMint(address _user, uint256 _tokenId) external contractAddressOnly
	{
	    if(_tokenId <= 1000)
		{
            _mint(_user,GENESIS_ISSUANCE);	  	        
		}
		else if(_tokenId >= 1001)
		{
            _mint(_user,DUCK_ISSUANCE);	  	        	        
		}
	}
	

	function getReward(address _to, uint256 totalPayout) external contractAddressOnly
	{
		_mint(_to, (totalPayout * 10 ** 18));
		
	}
	
	function burn(address _from, uint256 _amount) external 
	{
	    require(msg.sender == _from, "You do not own these tokens");
		_burn(_from, _amount);
		totalTokensBurned += _amount;
	}


  
   
}
// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol


// OpenZeppelin Contracts v4.3.2 (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 Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol


// OpenZeppelin Contracts v4.3.2 (utils/Address.sol)

pragma solidity ^0.8.0;

/**
 * @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
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721Receiver.sol


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

pragma solidity ^0.8.0;

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol


// OpenZeppelin Contracts v4.3.2 (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: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/ERC165.sol


// OpenZeppelin Contracts v4.3.2 (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: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/IERC721Enumerable.sol


// OpenZeppelin Contracts v4.3.2 (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 tokenId);

    /**
     * @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: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/IERC721Metadata.sol


// OpenZeppelin Contracts v4.3.2 (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: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol


// OpenZeppelin Contracts v4.3.2 (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: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        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) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        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 overriden 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 owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        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: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

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

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @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 of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {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 a {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 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 {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/ERC721Enumerable.sol


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

pragma solidity ^0.8.0;



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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: Artifacts/cosmicLabs.sol

pragma solidity 0.8.7;









/// SPDX-License-Identifier: UNLICENSED

contract CosmicLabs is ERC721Enumerable, IERC721Receiver, Ownable {
   
   using Strings for uint256;
   using EnumerableSet for EnumerableSet.UintSet;
   
    CosmicToken public cosmictoken;
    
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIdTracker;
    
    string public baseURI;
    string public baseExtension = ".json";

    
    uint public maxGenesisTx = 4;
    uint public maxDuckTx = 20;
    
    
    uint public maxSupply = 9000;
    uint public genesisSupply = 1000;
    
    uint256 public price = 0.05 ether;
   

    bool public GensisSaleOpen = true;
    bool public GenesisFreeMintOpen = false;
    bool public DuckMintOpen = false;
    
    
    
    modifier isSaleOpen
    {
         require(GensisSaleOpen == true);
         _;
    }
    
    modifier isFreeMintOpen
    {
         require(GenesisFreeMintOpen == true);
         _;
    }
    
    modifier isDuckMintOpen
    {
         require(DuckMintOpen == true);
         _;
    }
    

    
    function switchFromFreeToDuckMint() public onlyOwner
    {
        GenesisFreeMintOpen = false;
        DuckMintOpen = true;
    }
    
    
    
    event mint(address to, uint total);
    event withdraw(uint total);
    event giveawayNft(address to, uint tokenID);
    
    mapping(address => uint256) public balanceOG;
    
    mapping(address => uint256) public maxWalletGenesisTX;
    mapping(address => uint256) public maxWalletDuckTX;
    
    mapping(address => EnumerableSet.UintSet) private _deposits;
    
    
    mapping(uint256 => uint256) public _deposit_blocks;
    
    mapping(address => bool) public addressStaked;
    
    //ID - Days staked;
    mapping(uint256 => uint256) public IDvsDaysStaked;
    mapping (address => uint256) public whitelistMintAmount;
    

   address internal communityWallet = 0xea25545d846ecF4999C2875bC77dE5B5151Fa633;
   
    constructor(string memory _initBaseURI) ERC721("Cosmic Labs", "CLABS")
    {
        setBaseURI(_initBaseURI);
    }
   
   
    function setPrice(uint256 newPrice) external onlyOwner {
        price = newPrice;
    }
   
    
    function setYieldToken(address _yield) external onlyOwner {
		cosmictoken = CosmicToken(_yield);
	}
	
	function totalToken() public view returns (uint256) {
            return _tokenIdTracker.current();
    }
    
    modifier communityWalletOnly
    {
         require(msg.sender == communityWallet);
         _;
    }
    	
	function communityDuckMint(uint256 amountForAirdrops) public onlyOwner
	{
        for(uint256 i; i<amountForAirdrops; i++)
        {
             _tokenIdTracker.increment();
            _safeMint(communityWallet, totalToken());
        }
	}

    function GenesisSale(uint8 mintTotal) public payable isSaleOpen
    {
        uint256 totalMinted = maxWalletGenesisTX[msg.sender];
        totalMinted = totalMinted + mintTotal;
        
        require(mintTotal >= 1 && mintTotal <= maxGenesisTx, "Mint Amount Incorrect");
        require(totalToken() < genesisSupply, "SOLD OUT!");
        require(maxWalletGenesisTX[msg.sender] <= maxGenesisTx, "You've maxed your limit!");
        require(msg.value >= price * mintTotal, "Minting a Genesis Costs 0.05 Ether Each!");
        require(totalMinted <= maxGenesisTx, "You'll surpass your limit!");
        
        
        for(uint8 i=0;i<mintTotal;i++)
        {
            whitelistMintAmount[msg.sender] += 1;
            maxWalletGenesisTX[msg.sender] += 1;
            _tokenIdTracker.increment();
            _safeMint(msg.sender, totalToken());
            cosmictoken.updateRewardOnMint(msg.sender, totalToken());
            emit mint(msg.sender, totalToken());
        }
        
        if(totalToken() == genesisSupply)
        {
            GensisSaleOpen = false;
            GenesisFreeMintOpen = true;
        }
       
    }	

    function GenesisFreeMint(uint8 mintTotal)public payable isFreeMintOpen
    {
        require(whitelistMintAmount[msg.sender] > 0, "You don't have any free mints!");
        require(totalToken() < maxSupply, "SOLD OUT!");
        require(mintTotal <= whitelistMintAmount[msg.sender], "You are passing your limit!");
        
        for(uint8 i=0;i<mintTotal;i++)
        {
            whitelistMintAmount[msg.sender] -= 1;
            _tokenIdTracker.increment();
            _safeMint(msg.sender, totalToken());
            cosmictoken.updateRewardOnMint(msg.sender, totalToken());
            emit mint(msg.sender, totalToken());
        }
    }
	

    function DuckSale(uint8 mintTotal)public payable isDuckMintOpen
    {
        uint256 totalMinted = maxWalletDuckTX[msg.sender];
        totalMinted = totalMinted + mintTotal;        
    
        require(mintTotal >= 1 && mintTotal <= maxDuckTx, "Mint Amount Incorrect");
        require(msg.value >= price * mintTotal, "Minting a Duck Costs 0.05 Ether Each!");
        require(totalToken() < maxSupply, "SOLD OUT!");
        require(maxWalletDuckTX[msg.sender] <= maxDuckTx, "You've maxed your limit!");
        require(totalMinted <= maxDuckTx, "You'll surpass your limit!");
        
        for(uint8 i=0;i<mintTotal;i++)
        {
            maxWalletDuckTX[msg.sender] += 1;
            _tokenIdTracker.increment();
            _safeMint(msg.sender, totalToken());
            cosmictoken.updateRewardOnMint(msg.sender, totalToken());
            emit mint(msg.sender, totalToken());
        }
        
        if(totalToken() == maxSupply)
        {
            DuckMintOpen = false;
        }
    }
   
   
    function airdropNft(address airdropPatricipent, uint16 tokenID) public payable communityWalletOnly
    {
        _transfer(msg.sender, airdropPatricipent, tokenID);
        emit giveawayNft(airdropPatricipent, tokenID);
    }
    
    function airdropMany(address[] memory airdropPatricipents) public payable communityWalletOnly
    {
        uint256[] memory tempWalletOfUser = this.walletOfOwner(msg.sender);
        
        require(tempWalletOfUser.length >= airdropPatricipents.length, "You dont have enough tokens to airdrop all!");
        
       for(uint256 i=0; i<airdropPatricipents.length; i++)
       {
            _transfer(msg.sender, airdropPatricipents[i], tempWalletOfUser[i]);
            emit giveawayNft(airdropPatricipents[i], tempWalletOfUser[i]);
       }

    }    
    
    function withdrawContractEther(address payable recipient) external onlyOwner
    {
        emit withdraw(getBalance());
        recipient.transfer(getBalance());
    }
    function getBalance() public view returns(uint)
    {
        return address(this).balance;
    }
   
    function _baseURI() internal view virtual override returns (string memory) {
        return baseURI;
    }
   
    function setBaseURI(string memory _newBaseURI) public onlyOwner {
        baseURI = _newBaseURI;
    }
   
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory)
    {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory currentBaseURI = _baseURI();
        return bytes(currentBaseURI).length > 0 ? string(abi.encodePacked(currentBaseURI, tokenId.toString(), baseExtension)) : "";
    }
    
	function getReward(uint256 CalculatedPayout) internal
	{
		cosmictoken.getReward(msg.sender, CalculatedPayout);
	}    
    
    //Staking Functions
    function depositStake(uint256[] calldata tokenIds) external {
        
        require(isApprovedForAll(msg.sender, address(this)), "You are not Approved!");
        
        
        for (uint256 i; i < tokenIds.length; i++) {
            safeTransferFrom(
                msg.sender,
                address(this),
                tokenIds[i],
                ''
            );
            
            _deposits[msg.sender].add(tokenIds[i]);
            addressStaked[msg.sender] = true;
            
            
            _deposit_blocks[tokenIds[i]] = block.timestamp;
            

            IDvsDaysStaked[tokenIds[i]] = block.timestamp;
        }
        
    }
    function withdrawStake(uint256[] calldata tokenIds) external {
        
        require(isApprovedForAll(msg.sender, address(this)), "You are not Approved!");
        
        for (uint256 i; i < tokenIds.length; i++) {
            require(
                _deposits[msg.sender].contains(tokenIds[i]),
                'Token not deposited'
            );
            
            cosmictoken.getReward(msg.sender,totalRewardsToPay(tokenIds[i]));
            
            _deposits[msg.sender].remove(tokenIds[i]);
             _deposit_blocks[tokenIds[i]] = 0;
            addressStaked[msg.sender] = false;
            IDvsDaysStaked[tokenIds[i]] = block.timestamp;
            
            this.safeTransferFrom(
                address(this),
                msg.sender,
                tokenIds[i],
                ''
            );
        }
    }

    
    function viewRewards() external view returns (uint256)
    {
        uint256 payout = 0;
        
        for(uint256 i = 0; i < _deposits[msg.sender].length(); i++)
        {
            payout = payout + totalRewardsToPay(_deposits[msg.sender].at(i));
        }
        return payout;
    }
    
    function claimRewards() external
    {
        for(uint256 i = 0; i < _deposits[msg.sender].length(); i++)
        {
            cosmictoken.getReward(msg.sender, totalRewardsToPay(_deposits[msg.sender].at(i)));
            IDvsDaysStaked[_deposits[msg.sender].at(i)] = block.timestamp;
        }
    }   
    
    function totalRewardsToPay(uint256 tokenId) internal view returns(uint256)
    {
        uint256 payout = 0;
        
        if(tokenId > 0 && tokenId <= genesisSupply)
        {
            payout = howManyDaysStaked(tokenId) * 20;
        }
        else if (tokenId > genesisSupply && tokenId <= maxSupply)
        {
            payout = howManyDaysStaked(tokenId) * 5;
        }
        
        return payout;
    }
    
    function howManyDaysStaked(uint256 tokenId) public view returns(uint256)
    {
        
        require(
            _deposits[msg.sender].contains(tokenId),
            'Token not deposited'
        );
        
        uint256 returndays;
        uint256 timeCalc = block.timestamp - IDvsDaysStaked[tokenId];
        returndays = timeCalc / 86400;
       
        return returndays;
    }
    
    function walletOfOwner(address _owner) external view returns (uint256[] memory) {
        uint256 tokenCount = balanceOf(_owner);

        uint256[] memory tokensId = new uint256[](tokenCount);
        for (uint256 i = 0; i < tokenCount; i++) {
            tokensId[i] = tokenOfOwnerByIndex(_owner, i);
        }

        return tokensId;
    }
    
    function returnStakedTokens() public view returns (uint256[] memory)
    {
        return _deposits[msg.sender].values();
    }
    
    function totalTokensInWallet() public view returns(uint256)
    {
        return cosmictoken.balanceOf(msg.sender);
    }
    
   
    function onERC721Received(
        address,
        address,
        uint256,
        bytes calldata
    ) external pure override returns (bytes4) {
        return IERC721Receiver.onERC721Received.selector;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_initBaseURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenID","type":"uint256"}],"name":"giveawayNft","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"total","type":"uint256"}],"name":"mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"total","type":"uint256"}],"name":"withdraw","type":"event"},{"inputs":[],"name":"DuckMintOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"mintTotal","type":"uint8"}],"name":"DuckSale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8","name":"mintTotal","type":"uint8"}],"name":"GenesisFreeMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"GenesisFreeMintOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"mintTotal","type":"uint8"}],"name":"GenesisSale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"GensisSaleOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"IDvsDaysStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_deposit_blocks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressStaked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"airdropPatricipents","type":"address[]"}],"name":"airdropMany","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"airdropPatricipent","type":"address"},{"internalType":"uint16","name":"tokenID","type":"uint16"}],"name":"airdropNft","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOG","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountForAirdrops","type":"uint256"}],"name":"communityDuckMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cosmictoken","outputs":[{"internalType":"contract CosmicToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"depositStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"genesisSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"howManyDaysStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"maxDuckTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxGenesisTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxWalletDuckTX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxWalletGenesisTX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","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":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"returnStakedTokens","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":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_yield","type":"address"}],"name":"setYieldToken","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":"switchFromFreeToDuckMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTokensInWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"viewRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistMintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"recipient","type":"address"}],"name":"withdrawContractEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"withdrawStake","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c06040526005608081905264173539b7b760d91b60a09081526200002891600e919062000212565b506004600f55601460108190556123286011556103e860125566b1a2bc2ec50000601355805462ffffff19166001179055601d80546001600160a01b03191673ea25545d846ecf4999c2875bc77de5b5151fa6331790553480156200008c57600080fd5b50604051620041c7380380620041c7833981016040819052620000af91620002b8565b604080518082018252600b81526a436f736d6963204c61627360a81b602080830191825283518085019094526005845264434c41425360d81b908401528151919291620000ff9160009162000212565b5080516200011590600190602084019062000212565b505050620001326200012c6200014460201b60201c565b62000148565b6200013d816200019a565b50620003e7565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600a546001600160a01b03163314620001f95760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640160405180910390fd5b80516200020e90600d90602084019062000212565b5050565b828054620002209062000394565b90600052602060002090601f0160209004810192826200024457600085556200028f565b82601f106200025f57805160ff19168380011785556200028f565b828001600101855582156200028f579182015b828111156200028f57825182559160200191906001019062000272565b506200029d929150620002a1565b5090565b5b808211156200029d5760008155600101620002a2565b60006020808385031215620002cc57600080fd5b82516001600160401b0380821115620002e457600080fd5b818501915085601f830112620002f957600080fd5b8151818111156200030e576200030e620003d1565b604051601f8201601f19908116603f01168101908382118183101715620003395762000339620003d1565b8160405282815288868487010111156200035257600080fd5b600093505b8284101562000376578484018601518185018701529285019262000357565b82841115620003885760008684830101525b98975050505050505050565b600181811c90821680620003a957607f821691505b60208210811415620003cb57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b613dd080620003f76000396000f3fe60806040526004361061038c5760003560e01c806365b71d94116101dc578063ae97c03c11610102578063ca48bd40116100a0578063e985e9c51161006f578063e985e9c514610a52578063f2fde38b14610a72578063f4da811914610a92578063f6cbe5cc14610aa557600080fd5b8063ca48bd40146109d6578063d532bdfe146109ec578063d5abeb0114610a0c578063e74d059f14610a2257600080fd5b8063bb9e1f64116100dc578063bb9e1f6414610978578063c4d1957b1461098e578063c6682862146109a1578063c87b56dd146109b657600080fd5b8063ae97c03c14610918578063af7bfef214610938578063b88d4fde1461095857600080fd5b80638da5cb5b1161017a5780639e87a489116101495780639e87a489146108af578063a035b1fe146108c2578063a16d605a146108d8578063a22cb465146108f857600080fd5b80638da5cb5b1461082f57806391b7f5ed1461084d57806395d89b411461086d57806399f3732c1461088257600080fd5b8063715018a6116101b6578063715018a6146107ad5780637b19d281146107c25780638135fbdf146107ef5780638620a4b81461081c57600080fd5b806365b71d94146107635780636c0360eb1461077857806370a082311461078d57600080fd5b80633b420046116102c15780634f6ccce71161025f578063580d32451161022e578063580d3245146106e15780635de7e0071461070e578063626be5671461072e5780636352211e1461074357600080fd5b80634f6ccce7146106545780634feafc0914610674578063519031fb1461069457806355f804b3146106c157600080fd5b8063438b63001161029b578063438b6300146105e25780634bbf179b1461060f5780634c68e4e9146106255780634e5cb2ee1461063f57600080fd5b80633b4200461461059a5780633dfa83b3146105ad57806342842e0e146105c257600080fd5b806318160ddd1161032e57806323ffce851161030857806323ffce85146105185780632f745c5914610538578063372500ab1461055857806338712d8d1461056d57600080fd5b806318160ddd146104c35780631c2865a0146104d857806323b872dd146104f857600080fd5b8063095ea7b31161036a578063095ea7b31461042057806311ce6be11461044257806312065fe014610461578063150b7a021461047e57600080fd5b806301ffc9a71461039157806306fdde03146103c6578063081812fc146103e8575b600080fd5b34801561039d57600080fd5b506103b16103ac366004613843565b610aba565b60405190151581526020015b60405180910390f35b3480156103d257600080fd5b506103db610ae5565b6040516103bd9190613a8c565b3480156103f457600080fd5b506104086104033660046138c6565b610b77565b6040516001600160a01b0390911681526020016103bd565b34801561042c57600080fd5b5061044061043b366004613670565b610c11565b005b34801561044e57600080fd5b506014546103b190610100900460ff1681565b34801561046d57600080fd5b50475b6040519081526020016103bd565b34801561048a57600080fd5b506104aa6104993660046134e9565b630a85bd0160e11b95945050505050565b6040516001600160e01b031990911681526020016103bd565b3480156104cf57600080fd5b50600854610470565b3480156104e457600080fd5b506104706104f33660046138c6565b610d27565b34801561050457600080fd5b506104406105133660046134a8565b610db4565b34801561052457600080fd5b50610440610533366004613452565b610de5565b34801561054457600080fd5b50610470610553366004613670565b610e31565b34801561056457600080fd5b50610440610ec7565b34801561057957600080fd5b50610470610588366004613452565b60156020526000908152604090205481565b6104406105a83660046138f8565b610fc3565b3480156105b957600080fd5b506104706112e6565b3480156105ce57600080fd5b506104406105dd3660046134a8565b61134b565b3480156105ee57600080fd5b506106026105fd366004613452565b611366565b6040516103bd9190613a48565b34801561061b57600080fd5b5061047060125481565b34801561063157600080fd5b506014546103b19060ff1681565b34801561064b57600080fd5b50610440611408565b34801561066057600080fd5b5061047061066f3660046138c6565b611445565b34801561068057600080fd5b50600b54610408906001600160a01b031681565b3480156106a057600080fd5b506104706106af3660046138c6565b601b6020526000908152604090205481565b3480156106cd57600080fd5b506104406106dc36600461387d565b6114d8565b3480156106ed57600080fd5b506104706106fc366004613452565b60176020526000908152604090205481565b34801561071a57600080fd5b50610440610729366004613742565b611515565b34801561073a57600080fd5b50610470611662565b34801561074f57600080fd5b5061040861075e3660046138c6565b611672565b34801561076f57600080fd5b506104706116e9565b34801561078457600080fd5b506103db611765565b34801561079957600080fd5b506104706107a8366004613452565b6117f3565b3480156107b957600080fd5b5061044061187a565b3480156107ce57600080fd5b506104706107dd366004613452565b60166020526000908152604090205481565b3480156107fb57600080fd5b5061047061080a366004613452565b601c6020526000908152604090205481565b61044061082a36600461363b565b6118b0565b34801561083b57600080fd5b50600a546001600160a01b0316610408565b34801561085957600080fd5b506104406108683660046138c6565b61191f565b34801561087957600080fd5b506103db61194e565b34801561088e57600080fd5b5061047061089d3660046138c6565b60196020526000908152604090205481565b6104406108bd3660046138f8565b61195d565b3480156108ce57600080fd5b5061047060135481565b3480156108e457600080fd5b506104406108f3366004613452565b611b7e565b34801561090457600080fd5b50610440610913366004613608565b611c10565b34801561092457600080fd5b506014546103b19062010000900460ff1681565b34801561094457600080fd5b506104406109533660046138c6565b611c1b565b34801561096457600080fd5b50610440610973366004613588565b611c88565b34801561098457600080fd5b50610470600f5481565b61044061099c36600461369c565b611cc0565b3480156109ad57600080fd5b506103db611e8d565b3480156109c257600080fd5b506103db6109d13660046138c6565b611e9a565b3480156109e257600080fd5b5061047060105481565b3480156109f857600080fd5b50610440610a07366004613742565b611f78565b348015610a1857600080fd5b5061047060115481565b348015610a2e57600080fd5b506103b1610a3d366004613452565b601a6020526000908152604090205460ff1681565b348015610a5e57600080fd5b506103b1610a6d36600461346f565b61223a565b348015610a7e57600080fd5b50610440610a8d366004613452565b612268565b610440610aa03660046138f8565b612300565b348015610ab157600080fd5b50610602612642565b60006001600160e01b0319821663780e9d6360e01b1480610adf5750610adf8261265d565b92915050565b606060008054610af490613c7d565b80601f0160208091040260200160405190810160405280929190818152602001828054610b2090613c7d565b8015610b6d5780601f10610b4257610100808354040283529160200191610b6d565b820191906000526020600020905b815481529060010190602001808311610b5057829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b0316610bf55760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610c1c82611672565b9050806001600160a01b0316836001600160a01b03161415610c8a5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610bec565b336001600160a01b0382161480610ca65750610ca6813361223a565b610d185760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610bec565b610d2283836126ad565b505050565b336000908152601860205260408120610d40908361271b565b610d825760405162461bcd60e51b8152602060048201526013602482015272151bdad95b881b9bdd0819195c1bdcda5d1959606a1b6044820152606401610bec565b6000828152601b60205260408120548190610d9d9042613c3a565b9050610dac6201518082613c07565b949350505050565b610dbe3382612733565b610dda5760405162461bcd60e51b8152600401610bec90613b49565b610d22838383612802565b600a546001600160a01b03163314610e0f5760405162461bcd60e51b8152600401610bec90613b14565b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610e3c836117f3565b8210610e9e5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610bec565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b60005b336000908152601860205260409020610ee2906129ad565b811015610fc057600b543360008181526018602052604090206001600160a01b039092169163f474c8ce9190610f2190610f1c90866129b7565b6129c3565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015610f6757600080fd5b505af1158015610f7b573d6000803e3d6000fd5b5050336000908152601860205260408120429350601b9250610f9d90856129b7565b815260208101919091526040016000205580610fb881613cb2565b915050610eca565b50565b60145462010000900460ff161515600114610fdd57600080fd5b33600090815260176020526040902054610ffa60ff831682613bef565b905060018260ff161015801561101557506010548260ff1611155b6110595760405162461bcd60e51b8152602060048201526015602482015274135a5b9d08105b5bdd5b9d08125b98dbdc9c9958dd605a1b6044820152606401610bec565b8160ff1660135461106a9190613c1b565b3410156110c75760405162461bcd60e51b815260206004820152602560248201527f4d696e74696e672061204475636b20436f73747320302e303520457468657220604482015264456163682160d81b6064820152608401610bec565b6011546110d2611662565b106110ef5760405162461bcd60e51b8152600401610bec90613af1565b60105433600090815260176020526040902054111561114b5760405162461bcd60e51b8152602060048201526018602482015277596f75277665206d6178656420796f7572206c696d69742160401b6044820152606401610bec565b60105481111561119d5760405162461bcd60e51b815260206004820152601a60248201527f596f75276c6c207375727061737320796f7572206c696d6974210000000000006044820152606401610bec565b60005b8260ff168160ff1610156112c3573360009081526017602052604081208054600192906111ce908490613bef565b9091555050600c805460010190556111ed336111e8611662565b612a23565b600b546001600160a01b031663cc240c0133611207611662565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561124d57600080fd5b505af1158015611261573d6000803e3d6000fd5b505050507f40c10f19c047ae7dfa66d6312b683d2ea3dfbcb4159e96b967c5f4b0a86f28423361128f611662565b604080516001600160a01b03909316835260208301919091520160405180910390a1806112bb81613ccd565b9150506111a0565b506011546112cf611662565b14156112e2576014805462ff0000191690555b5050565b600080805b336000908152601860205260409020611303906129ad565b8110156113455733600090815260186020526040902061132790610f1c90836129b7565b6113319083613bef565b91508061133d81613cb2565b9150506112eb565b50919050565b610d2283838360405180602001604052806000815250611c88565b60606000611373836117f3565b905060008167ffffffffffffffff81111561139057611390613d59565b6040519080825280602002602001820160405280156113b9578160200160208202803683370190505b50905060005b82811015611400576113d18582610e31565b8282815181106113e3576113e3613d43565b6020908102919091010152806113f881613cb2565b9150506113bf565b509392505050565b600a546001600160a01b031633146114325760405162461bcd60e51b8152600401610bec90613b14565b6014805462ffff00191662010000179055565b600061145060085490565b82106114b35760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610bec565b600882815481106114c6576114c6613d43565b90600052602060002001549050919050565b600a546001600160a01b031633146115025760405162461bcd60e51b8152600401610bec90613b14565b80516112e290600d906020840190613361565b61151f333061223a565b6115635760405162461bcd60e51b8152602060048201526015602482015274596f7520617265206e6f7420417070726f7665642160581b6044820152606401610bec565b60005b81811015610d22576115a1333085858581811061158557611585613d43565b9050602002013560405180602001604052806000815250611c88565b6115d48383838181106115b6576115b6613d43565b33600090815260186020908152604090912093910201359050612a3d565b50336000908152601a60205260408120805460ff19166001179055429060199085858581811061160657611606613d43565b9050602002013581526020019081526020016000208190555042601b600085858581811061163657611636613d43565b90506020020135815260200190815260200160002081905550808061165a90613cb2565b915050611566565b600061166d600c5490565b905090565b6000818152600260205260408120546001600160a01b031680610adf5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610bec565b600b546040516370a0823160e01b81523360048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561172d57600080fd5b505afa158015611741573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166d91906138df565b600d805461177290613c7d565b80601f016020809104026020016040519081016040528092919081815260200182805461179e90613c7d565b80156117eb5780601f106117c0576101008083540402835291602001916117eb565b820191906000526020600020905b8154815290600101906020018083116117ce57829003601f168201915b505050505081565b60006001600160a01b03821661185e5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610bec565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b031633146118a45760405162461bcd60e51b8152600401610bec90613b14565b6118ae6000612a49565b565b601d546001600160a01b031633146118c757600080fd5b6118d633838361ffff16612802565b604080516001600160a01b038416815261ffff831660208201527fe2ae2d4299019f247f9b47047a994e121c067a8a2099ad43a45a99a0e4906d87910160405180910390a15050565b600a546001600160a01b031633146119495760405162461bcd60e51b8152600401610bec90613b14565b601355565b606060018054610af490613c7d565b60145460ff61010090910416151560011461197757600080fd5b336000908152601c60205260409020546119d35760405162461bcd60e51b815260206004820152601e60248201527f596f7520646f6e2774206861766520616e792066726565206d696e74732100006044820152606401610bec565b6011546119de611662565b106119fb5760405162461bcd60e51b8152600401610bec90613af1565b336000908152601c602052604090205460ff82161115611a5d5760405162461bcd60e51b815260206004820152601b60248201527f596f75206172652070617373696e6720796f7572206c696d69742100000000006044820152606401610bec565b60005b8160ff168160ff1610156112e257336000908152601c60205260408120805460019290611a8e908490613c3a565b9091555050600c80546001019055611aa8336111e8611662565b600b546001600160a01b031663cc240c0133611ac2611662565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015611b0857600080fd5b505af1158015611b1c573d6000803e3d6000fd5b505050507f40c10f19c047ae7dfa66d6312b683d2ea3dfbcb4159e96b967c5f4b0a86f284233611b4a611662565b604080516001600160a01b03909316835260208301919091520160405180910390a180611b7681613ccd565b915050611a60565b600a546001600160a01b03163314611ba85760405162461bcd60e51b8152600401610bec90613b14565b7f2e1a7d4d13322e7b96f9a57413e1525c250fb7a9021cf91d1540d5b69f16a49f4760405190815260200160405180910390a16040516001600160a01b038216904780156108fc02916000818181858888f193505050501580156112e2573d6000803e3d6000fd5b6112e2338383612a9b565b600a546001600160a01b03163314611c455760405162461bcd60e51b8152600401610bec90613b14565b60005b818110156112e257611c5e600c80546001019055565b601d54611c76906001600160a01b03166111e8611662565b80611c8081613cb2565b915050611c48565b611c923383612733565b611cae5760405162461bcd60e51b8152600401610bec90613b49565b611cba84848484612b6a565b50505050565b601d546001600160a01b03163314611cd757600080fd5b60405162438b6360e81b8152336004820152600090309063438b63009060240160006040518083038186803b158015611d0f57600080fd5b505afa158015611d23573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611d4b91908101906137b7565b9050815181511015611db35760405162461bcd60e51b815260206004820152602b60248201527f596f7520646f6e74206861766520656e6f75676820746f6b656e7320746f206160448201526a697264726f7020616c6c2160a81b6064820152608401610bec565b60005b8251811015610d2257611dfc33848381518110611dd557611dd5613d43565b6020026020010151848481518110611def57611def613d43565b6020026020010151612802565b7fe2ae2d4299019f247f9b47047a994e121c067a8a2099ad43a45a99a0e4906d87838281518110611e2f57611e2f613d43565b6020026020010151838381518110611e4957611e49613d43565b6020026020010151604051611e739291906001600160a01b03929092168252602082015260400190565b60405180910390a180611e8581613cb2565b915050611db6565b600e805461177290613c7d565b6000818152600260205260409020546060906001600160a01b0316611f195760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610bec565b6000611f23612b9d565b90506000815111611f435760405180602001604052806000815250611f71565b80611f4d84612bac565b600e604051602001611f6193929190613947565b6040516020818303038152906040525b9392505050565b611f82333061223a565b611fc65760405162461bcd60e51b8152602060048201526015602482015274596f7520617265206e6f7420417070726f7665642160581b6044820152606401610bec565b60005b81811015610d2257612004838383818110611fe657611fe6613d43565b3360009081526018602090815260409091209391020135905061271b565b6120465760405162461bcd60e51b8152602060048201526013602482015272151bdad95b881b9bdd0819195c1bdcda5d1959606a1b6044820152606401610bec565b600b546001600160a01b031663f474c8ce3361207986868681811061206d5761206d613d43565b905060200201356129c3565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156120bf57600080fd5b505af11580156120d3573d6000803e3d6000fd5b5050505061210a8383838181106120ec576120ec613d43565b33600090815260186020908152604090912093910201359050612caa565b5060006019600085858581811061212357612123613d43565b60209081029290920135835250818101929092526040908101600090812093909355338352601a9091528120805460ff191690554290601b9085858581811061216e5761216e613d43565b90506020020135815260200190815260200160002081905550306001600160a01b031663b88d4fde30338686868181106121aa576121aa613d43565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152608060648201526000608482015260a401600060405180830381600087803b15801561220f57600080fd5b505af1158015612223573d6000803e3d6000fd5b50505050808061223290613cb2565b915050611fc9565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b600a546001600160a01b031633146122925760405162461bcd60e51b8152600401610bec90613b14565b6001600160a01b0381166122f75760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610bec565b610fc081612a49565b60145460ff16151560011461231457600080fd5b3360009081526016602052604090205461233160ff831682613bef565b905060018260ff161015801561234c5750600f548260ff1611155b6123905760405162461bcd60e51b8152602060048201526015602482015274135a5b9d08105b5bdd5b9d08125b98dbdc9c9958dd605a1b6044820152606401610bec565b60125461239b611662565b106123b85760405162461bcd60e51b8152600401610bec90613af1565b600f543360009081526016602052604090205411156124145760405162461bcd60e51b8152602060048201526018602482015277596f75277665206d6178656420796f7572206c696d69742160401b6044820152606401610bec565b8160ff166013546124259190613c1b565b3410156124855760405162461bcd60e51b815260206004820152602860248201527f4d696e74696e6720612047656e6573697320436f73747320302e303520457468604482015267657220456163682160c01b6064820152608401610bec565b600f548111156124d75760405162461bcd60e51b815260206004820152601a60248201527f596f75276c6c207375727061737320796f7572206c696d6974210000000000006044820152606401610bec565b60005b8260ff168160ff16101561261d57336000908152601c60205260408120805460019290612508908490613bef565b909155505033600090815260166020526040812080546001929061252d908490613bef565b9091555050600c80546001019055612547336111e8611662565b600b546001600160a01b031663cc240c0133612561611662565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156125a757600080fd5b505af11580156125bb573d6000803e3d6000fd5b505050507f40c10f19c047ae7dfa66d6312b683d2ea3dfbcb4159e96b967c5f4b0a86f2842336125e9611662565b604080516001600160a01b03909316835260208301919091520160405180910390a18061261581613ccd565b9150506124da565b50601254612629611662565b14156112e2576014805461ffff19166101001790555050565b33600090815260186020526040902060609061166d90612cb6565b60006001600160e01b031982166380ac58cd60e01b148061268e57506001600160e01b03198216635b5e139f60e01b145b80610adf57506301ffc9a760e01b6001600160e01b0319831614610adf565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906126e282611672565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008181526001830160205260408120541515611f71565b6000818152600260205260408120546001600160a01b03166127ac5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610bec565b60006127b783611672565b9050806001600160a01b0316846001600160a01b031614806127f25750836001600160a01b03166127e784610b77565b6001600160a01b0316145b80610dac5750610dac818561223a565b826001600160a01b031661281582611672565b6001600160a01b03161461287d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610bec565b6001600160a01b0382166128df5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610bec565b6128ea838383612cc3565b6128f56000826126ad565b6001600160a01b038316600090815260036020526040812080546001929061291e908490613c3a565b90915550506001600160a01b038216600090815260036020526040812080546001929061294c908490613bef565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000610adf825490565b6000611f718383612d7b565b60008082158015906129d757506012548311155b156129f7576129e583610d27565b6129f0906014613c1b565b9050610adf565b60125483118015612a0a57506011548311155b15610adf57612a1883610d27565b611f71906005613c1b565b6112e2828260405180602001604052806000815250612da5565b6000611f718383612dd8565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b03161415612afd5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610bec565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612b75848484612802565b612b8184848484612e27565b611cba5760405162461bcd60e51b8152600401610bec90613a9f565b6060600d8054610af490613c7d565b606081612bd05750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612bfa5780612be481613cb2565b9150612bf39050600a83613c07565b9150612bd4565b60008167ffffffffffffffff811115612c1557612c15613d59565b6040519080825280601f01601f191660200182016040528015612c3f576020820181803683370190505b5090505b8415610dac57612c54600183613c3a565b9150612c61600a86613ced565b612c6c906030613bef565b60f81b818381518110612c8157612c81613d43565b60200101906001600160f81b031916908160001a905350612ca3600a86613c07565b9450612c43565b6000611f718383612f34565b60606000611f7183613027565b6001600160a01b038316612d1e57612d1981600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612d41565b816001600160a01b0316836001600160a01b031614612d4157612d418382613083565b6001600160a01b038216612d5857610d2281613120565b826001600160a01b0316826001600160a01b031614610d2257610d2282826131cf565b6000826000018281548110612d9257612d92613d43565b9060005260206000200154905092915050565b612daf8383613213565b612dbc6000848484612e27565b610d225760405162461bcd60e51b8152600401610bec90613a9f565b6000818152600183016020526040812054612e1f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610adf565b506000610adf565b60006001600160a01b0384163b15612f2957604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612e6b903390899088908890600401613a0b565b602060405180830381600087803b158015612e8557600080fd5b505af1925050508015612eb5575060408051601f3d908101601f19168201909252612eb291810190613860565b60015b612f0f573d808015612ee3576040519150601f19603f3d011682016040523d82523d6000602084013e612ee8565b606091505b508051612f075760405162461bcd60e51b8152600401610bec90613a9f565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610dac565b506001949350505050565b6000818152600183016020526040812054801561301d576000612f58600183613c3a565b8554909150600090612f6c90600190613c3a565b9050818114612fd1576000866000018281548110612f8c57612f8c613d43565b9060005260206000200154905080876000018481548110612faf57612faf613d43565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612fe257612fe2613d2d565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610adf565b6000915050610adf565b60608160000180548060200260200160405190810160405280929190818152602001828054801561307757602002820191906000526020600020905b815481526020019060010190808311613063575b50505050509050919050565b60006001613090846117f3565b61309a9190613c3a565b6000838152600760205260409020549091508082146130ed576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061313290600190613c3a565b6000838152600960205260408120546008805493945090928490811061315a5761315a613d43565b90600052602060002001549050806008838154811061317b5761317b613d43565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806131b3576131b3613d2d565b6001900381819060005260206000200160009055905550505050565b60006131da836117f3565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b0382166132695760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610bec565b6000818152600260205260409020546001600160a01b0316156132ce5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610bec565b6132da60008383612cc3565b6001600160a01b0382166000908152600360205260408120805460019290613303908490613bef565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b82805461336d90613c7d565b90600052602060002090601f01602090048101928261338f57600085556133d5565b82601f106133a857805160ff19168380011785556133d5565b828001600101855582156133d5579182015b828111156133d55782518255916020019190600101906133ba565b506133e19291506133e5565b5090565b5b808211156133e157600081556001016133e6565b600067ffffffffffffffff83111561341457613414613d59565b613427601f8401601f1916602001613b9a565b905082815283838301111561343b57600080fd5b828260208301376000602084830101529392505050565b60006020828403121561346457600080fd5b8135611f7181613d6f565b6000806040838503121561348257600080fd5b823561348d81613d6f565b9150602083013561349d81613d6f565b809150509250929050565b6000806000606084860312156134bd57600080fd5b83356134c881613d6f565b925060208401356134d881613d6f565b929592945050506040919091013590565b60008060008060006080868803121561350157600080fd5b853561350c81613d6f565b9450602086013561351c81613d6f565b935060408601359250606086013567ffffffffffffffff8082111561354057600080fd5b818801915088601f83011261355457600080fd5b81358181111561356357600080fd5b89602082850101111561357557600080fd5b9699959850939650602001949392505050565b6000806000806080858703121561359e57600080fd5b84356135a981613d6f565b935060208501356135b981613d6f565b925060408501359150606085013567ffffffffffffffff8111156135dc57600080fd5b8501601f810187136135ed57600080fd5b6135fc878235602084016133fa565b91505092959194509250565b6000806040838503121561361b57600080fd5b823561362681613d6f565b91506020830135801515811461349d57600080fd5b6000806040838503121561364e57600080fd5b823561365981613d6f565b9150602083013561ffff8116811461349d57600080fd5b6000806040838503121561368357600080fd5b823561368e81613d6f565b946020939093013593505050565b600060208083850312156136af57600080fd5b823567ffffffffffffffff8111156136c657600080fd5b8301601f810185136136d757600080fd5b80356136ea6136e582613bcb565b613b9a565b80828252848201915084840188868560051b870101111561370a57600080fd5b600094505b8385101561373657803561372281613d6f565b83526001949094019391850191850161370f565b50979650505050505050565b6000806020838503121561375557600080fd5b823567ffffffffffffffff8082111561376d57600080fd5b818501915085601f83011261378157600080fd5b81358181111561379057600080fd5b8660208260051b85010111156137a557600080fd5b60209290920196919550909350505050565b600060208083850312156137ca57600080fd5b825167ffffffffffffffff8111156137e157600080fd5b8301601f810185136137f257600080fd5b80516138006136e582613bcb565b80828252848201915084840188868560051b870101111561382057600080fd5b600094505b83851015613736578051835260019490940193918501918501613825565b60006020828403121561385557600080fd5b8135611f7181613d84565b60006020828403121561387257600080fd5b8151611f7181613d84565b60006020828403121561388f57600080fd5b813567ffffffffffffffff8111156138a657600080fd5b8201601f810184136138b757600080fd5b610dac848235602084016133fa565b6000602082840312156138d857600080fd5b5035919050565b6000602082840312156138f157600080fd5b5051919050565b60006020828403121561390a57600080fd5b813560ff81168114611f7157600080fd5b60008151808452613933816020860160208601613c51565b601f01601f19169290920160200192915050565b60008451602061395a8285838a01613c51565b85519184019161396d8184848a01613c51565b8554920191600090600181811c908083168061398a57607f831692505b8583108114156139a857634e487b7160e01b85526022600452602485fd5b8080156139bc57600181146139cd576139fa565b60ff198516885283880195506139fa565b60008b81526020902060005b858110156139f25781548a8201529084019088016139d9565b505083880195505b50939b9a5050505050505050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613a3e9083018461391b565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613a8057835183529284019291840191600101613a64565b50909695505050505050565b602081526000611f71602083018461391b565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b602080825260099082015268534f4c44204f55542160b81b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b604051601f8201601f1916810167ffffffffffffffff81118282101715613bc357613bc3613d59565b604052919050565b600067ffffffffffffffff821115613be557613be5613d59565b5060051b60200190565b60008219821115613c0257613c02613d01565b500190565b600082613c1657613c16613d17565b500490565b6000816000190483118215151615613c3557613c35613d01565b500290565b600082821015613c4c57613c4c613d01565b500390565b60005b83811015613c6c578181015183820152602001613c54565b83811115611cba5750506000910152565b600181811c90821680613c9157607f821691505b6020821081141561134557634e487b7160e01b600052602260045260246000fd5b6000600019821415613cc657613cc6613d01565b5060010190565b600060ff821660ff811415613ce457613ce4613d01565b60010192915050565b600082613cfc57613cfc613d17565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610fc057600080fd5b6001600160e01b031981168114610fc057600080fdfea2646970667358221220a10847e6cf20c66bce0dfc9f136d780180511ecda3b9a86ce938006f46eec85264736f6c634300080700330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005668747470733a2f2f636f736d69636c6162732e6d7970696e6174612e636c6f75642f697066732f516d4e594866635074567a58686d487a645a576f66746377465377627453335669536a4a47576b524663655a53352f00000000000000000000

Deployed Bytecode

0x60806040526004361061038c5760003560e01c806365b71d94116101dc578063ae97c03c11610102578063ca48bd40116100a0578063e985e9c51161006f578063e985e9c514610a52578063f2fde38b14610a72578063f4da811914610a92578063f6cbe5cc14610aa557600080fd5b8063ca48bd40146109d6578063d532bdfe146109ec578063d5abeb0114610a0c578063e74d059f14610a2257600080fd5b8063bb9e1f64116100dc578063bb9e1f6414610978578063c4d1957b1461098e578063c6682862146109a1578063c87b56dd146109b657600080fd5b8063ae97c03c14610918578063af7bfef214610938578063b88d4fde1461095857600080fd5b80638da5cb5b1161017a5780639e87a489116101495780639e87a489146108af578063a035b1fe146108c2578063a16d605a146108d8578063a22cb465146108f857600080fd5b80638da5cb5b1461082f57806391b7f5ed1461084d57806395d89b411461086d57806399f3732c1461088257600080fd5b8063715018a6116101b6578063715018a6146107ad5780637b19d281146107c25780638135fbdf146107ef5780638620a4b81461081c57600080fd5b806365b71d94146107635780636c0360eb1461077857806370a082311461078d57600080fd5b80633b420046116102c15780634f6ccce71161025f578063580d32451161022e578063580d3245146106e15780635de7e0071461070e578063626be5671461072e5780636352211e1461074357600080fd5b80634f6ccce7146106545780634feafc0914610674578063519031fb1461069457806355f804b3146106c157600080fd5b8063438b63001161029b578063438b6300146105e25780634bbf179b1461060f5780634c68e4e9146106255780634e5cb2ee1461063f57600080fd5b80633b4200461461059a5780633dfa83b3146105ad57806342842e0e146105c257600080fd5b806318160ddd1161032e57806323ffce851161030857806323ffce85146105185780632f745c5914610538578063372500ab1461055857806338712d8d1461056d57600080fd5b806318160ddd146104c35780631c2865a0146104d857806323b872dd146104f857600080fd5b8063095ea7b31161036a578063095ea7b31461042057806311ce6be11461044257806312065fe014610461578063150b7a021461047e57600080fd5b806301ffc9a71461039157806306fdde03146103c6578063081812fc146103e8575b600080fd5b34801561039d57600080fd5b506103b16103ac366004613843565b610aba565b60405190151581526020015b60405180910390f35b3480156103d257600080fd5b506103db610ae5565b6040516103bd9190613a8c565b3480156103f457600080fd5b506104086104033660046138c6565b610b77565b6040516001600160a01b0390911681526020016103bd565b34801561042c57600080fd5b5061044061043b366004613670565b610c11565b005b34801561044e57600080fd5b506014546103b190610100900460ff1681565b34801561046d57600080fd5b50475b6040519081526020016103bd565b34801561048a57600080fd5b506104aa6104993660046134e9565b630a85bd0160e11b95945050505050565b6040516001600160e01b031990911681526020016103bd565b3480156104cf57600080fd5b50600854610470565b3480156104e457600080fd5b506104706104f33660046138c6565b610d27565b34801561050457600080fd5b506104406105133660046134a8565b610db4565b34801561052457600080fd5b50610440610533366004613452565b610de5565b34801561054457600080fd5b50610470610553366004613670565b610e31565b34801561056457600080fd5b50610440610ec7565b34801561057957600080fd5b50610470610588366004613452565b60156020526000908152604090205481565b6104406105a83660046138f8565b610fc3565b3480156105b957600080fd5b506104706112e6565b3480156105ce57600080fd5b506104406105dd3660046134a8565b61134b565b3480156105ee57600080fd5b506106026105fd366004613452565b611366565b6040516103bd9190613a48565b34801561061b57600080fd5b5061047060125481565b34801561063157600080fd5b506014546103b19060ff1681565b34801561064b57600080fd5b50610440611408565b34801561066057600080fd5b5061047061066f3660046138c6565b611445565b34801561068057600080fd5b50600b54610408906001600160a01b031681565b3480156106a057600080fd5b506104706106af3660046138c6565b601b6020526000908152604090205481565b3480156106cd57600080fd5b506104406106dc36600461387d565b6114d8565b3480156106ed57600080fd5b506104706106fc366004613452565b60176020526000908152604090205481565b34801561071a57600080fd5b50610440610729366004613742565b611515565b34801561073a57600080fd5b50610470611662565b34801561074f57600080fd5b5061040861075e3660046138c6565b611672565b34801561076f57600080fd5b506104706116e9565b34801561078457600080fd5b506103db611765565b34801561079957600080fd5b506104706107a8366004613452565b6117f3565b3480156107b957600080fd5b5061044061187a565b3480156107ce57600080fd5b506104706107dd366004613452565b60166020526000908152604090205481565b3480156107fb57600080fd5b5061047061080a366004613452565b601c6020526000908152604090205481565b61044061082a36600461363b565b6118b0565b34801561083b57600080fd5b50600a546001600160a01b0316610408565b34801561085957600080fd5b506104406108683660046138c6565b61191f565b34801561087957600080fd5b506103db61194e565b34801561088e57600080fd5b5061047061089d3660046138c6565b60196020526000908152604090205481565b6104406108bd3660046138f8565b61195d565b3480156108ce57600080fd5b5061047060135481565b3480156108e457600080fd5b506104406108f3366004613452565b611b7e565b34801561090457600080fd5b50610440610913366004613608565b611c10565b34801561092457600080fd5b506014546103b19062010000900460ff1681565b34801561094457600080fd5b506104406109533660046138c6565b611c1b565b34801561096457600080fd5b50610440610973366004613588565b611c88565b34801561098457600080fd5b50610470600f5481565b61044061099c36600461369c565b611cc0565b3480156109ad57600080fd5b506103db611e8d565b3480156109c257600080fd5b506103db6109d13660046138c6565b611e9a565b3480156109e257600080fd5b5061047060105481565b3480156109f857600080fd5b50610440610a07366004613742565b611f78565b348015610a1857600080fd5b5061047060115481565b348015610a2e57600080fd5b506103b1610a3d366004613452565b601a6020526000908152604090205460ff1681565b348015610a5e57600080fd5b506103b1610a6d36600461346f565b61223a565b348015610a7e57600080fd5b50610440610a8d366004613452565b612268565b610440610aa03660046138f8565b612300565b348015610ab157600080fd5b50610602612642565b60006001600160e01b0319821663780e9d6360e01b1480610adf5750610adf8261265d565b92915050565b606060008054610af490613c7d565b80601f0160208091040260200160405190810160405280929190818152602001828054610b2090613c7d565b8015610b6d5780601f10610b4257610100808354040283529160200191610b6d565b820191906000526020600020905b815481529060010190602001808311610b5057829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b0316610bf55760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610c1c82611672565b9050806001600160a01b0316836001600160a01b03161415610c8a5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610bec565b336001600160a01b0382161480610ca65750610ca6813361223a565b610d185760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610bec565b610d2283836126ad565b505050565b336000908152601860205260408120610d40908361271b565b610d825760405162461bcd60e51b8152602060048201526013602482015272151bdad95b881b9bdd0819195c1bdcda5d1959606a1b6044820152606401610bec565b6000828152601b60205260408120548190610d9d9042613c3a565b9050610dac6201518082613c07565b949350505050565b610dbe3382612733565b610dda5760405162461bcd60e51b8152600401610bec90613b49565b610d22838383612802565b600a546001600160a01b03163314610e0f5760405162461bcd60e51b8152600401610bec90613b14565b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610e3c836117f3565b8210610e9e5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610bec565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b60005b336000908152601860205260409020610ee2906129ad565b811015610fc057600b543360008181526018602052604090206001600160a01b039092169163f474c8ce9190610f2190610f1c90866129b7565b6129c3565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015610f6757600080fd5b505af1158015610f7b573d6000803e3d6000fd5b5050336000908152601860205260408120429350601b9250610f9d90856129b7565b815260208101919091526040016000205580610fb881613cb2565b915050610eca565b50565b60145462010000900460ff161515600114610fdd57600080fd5b33600090815260176020526040902054610ffa60ff831682613bef565b905060018260ff161015801561101557506010548260ff1611155b6110595760405162461bcd60e51b8152602060048201526015602482015274135a5b9d08105b5bdd5b9d08125b98dbdc9c9958dd605a1b6044820152606401610bec565b8160ff1660135461106a9190613c1b565b3410156110c75760405162461bcd60e51b815260206004820152602560248201527f4d696e74696e672061204475636b20436f73747320302e303520457468657220604482015264456163682160d81b6064820152608401610bec565b6011546110d2611662565b106110ef5760405162461bcd60e51b8152600401610bec90613af1565b60105433600090815260176020526040902054111561114b5760405162461bcd60e51b8152602060048201526018602482015277596f75277665206d6178656420796f7572206c696d69742160401b6044820152606401610bec565b60105481111561119d5760405162461bcd60e51b815260206004820152601a60248201527f596f75276c6c207375727061737320796f7572206c696d6974210000000000006044820152606401610bec565b60005b8260ff168160ff1610156112c3573360009081526017602052604081208054600192906111ce908490613bef565b9091555050600c805460010190556111ed336111e8611662565b612a23565b600b546001600160a01b031663cc240c0133611207611662565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561124d57600080fd5b505af1158015611261573d6000803e3d6000fd5b505050507f40c10f19c047ae7dfa66d6312b683d2ea3dfbcb4159e96b967c5f4b0a86f28423361128f611662565b604080516001600160a01b03909316835260208301919091520160405180910390a1806112bb81613ccd565b9150506111a0565b506011546112cf611662565b14156112e2576014805462ff0000191690555b5050565b600080805b336000908152601860205260409020611303906129ad565b8110156113455733600090815260186020526040902061132790610f1c90836129b7565b6113319083613bef565b91508061133d81613cb2565b9150506112eb565b50919050565b610d2283838360405180602001604052806000815250611c88565b60606000611373836117f3565b905060008167ffffffffffffffff81111561139057611390613d59565b6040519080825280602002602001820160405280156113b9578160200160208202803683370190505b50905060005b82811015611400576113d18582610e31565b8282815181106113e3576113e3613d43565b6020908102919091010152806113f881613cb2565b9150506113bf565b509392505050565b600a546001600160a01b031633146114325760405162461bcd60e51b8152600401610bec90613b14565b6014805462ffff00191662010000179055565b600061145060085490565b82106114b35760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610bec565b600882815481106114c6576114c6613d43565b90600052602060002001549050919050565b600a546001600160a01b031633146115025760405162461bcd60e51b8152600401610bec90613b14565b80516112e290600d906020840190613361565b61151f333061223a565b6115635760405162461bcd60e51b8152602060048201526015602482015274596f7520617265206e6f7420417070726f7665642160581b6044820152606401610bec565b60005b81811015610d22576115a1333085858581811061158557611585613d43565b9050602002013560405180602001604052806000815250611c88565b6115d48383838181106115b6576115b6613d43565b33600090815260186020908152604090912093910201359050612a3d565b50336000908152601a60205260408120805460ff19166001179055429060199085858581811061160657611606613d43565b9050602002013581526020019081526020016000208190555042601b600085858581811061163657611636613d43565b90506020020135815260200190815260200160002081905550808061165a90613cb2565b915050611566565b600061166d600c5490565b905090565b6000818152600260205260408120546001600160a01b031680610adf5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610bec565b600b546040516370a0823160e01b81523360048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561172d57600080fd5b505afa158015611741573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166d91906138df565b600d805461177290613c7d565b80601f016020809104026020016040519081016040528092919081815260200182805461179e90613c7d565b80156117eb5780601f106117c0576101008083540402835291602001916117eb565b820191906000526020600020905b8154815290600101906020018083116117ce57829003601f168201915b505050505081565b60006001600160a01b03821661185e5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610bec565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b031633146118a45760405162461bcd60e51b8152600401610bec90613b14565b6118ae6000612a49565b565b601d546001600160a01b031633146118c757600080fd5b6118d633838361ffff16612802565b604080516001600160a01b038416815261ffff831660208201527fe2ae2d4299019f247f9b47047a994e121c067a8a2099ad43a45a99a0e4906d87910160405180910390a15050565b600a546001600160a01b031633146119495760405162461bcd60e51b8152600401610bec90613b14565b601355565b606060018054610af490613c7d565b60145460ff61010090910416151560011461197757600080fd5b336000908152601c60205260409020546119d35760405162461bcd60e51b815260206004820152601e60248201527f596f7520646f6e2774206861766520616e792066726565206d696e74732100006044820152606401610bec565b6011546119de611662565b106119fb5760405162461bcd60e51b8152600401610bec90613af1565b336000908152601c602052604090205460ff82161115611a5d5760405162461bcd60e51b815260206004820152601b60248201527f596f75206172652070617373696e6720796f7572206c696d69742100000000006044820152606401610bec565b60005b8160ff168160ff1610156112e257336000908152601c60205260408120805460019290611a8e908490613c3a565b9091555050600c80546001019055611aa8336111e8611662565b600b546001600160a01b031663cc240c0133611ac2611662565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015611b0857600080fd5b505af1158015611b1c573d6000803e3d6000fd5b505050507f40c10f19c047ae7dfa66d6312b683d2ea3dfbcb4159e96b967c5f4b0a86f284233611b4a611662565b604080516001600160a01b03909316835260208301919091520160405180910390a180611b7681613ccd565b915050611a60565b600a546001600160a01b03163314611ba85760405162461bcd60e51b8152600401610bec90613b14565b7f2e1a7d4d13322e7b96f9a57413e1525c250fb7a9021cf91d1540d5b69f16a49f4760405190815260200160405180910390a16040516001600160a01b038216904780156108fc02916000818181858888f193505050501580156112e2573d6000803e3d6000fd5b6112e2338383612a9b565b600a546001600160a01b03163314611c455760405162461bcd60e51b8152600401610bec90613b14565b60005b818110156112e257611c5e600c80546001019055565b601d54611c76906001600160a01b03166111e8611662565b80611c8081613cb2565b915050611c48565b611c923383612733565b611cae5760405162461bcd60e51b8152600401610bec90613b49565b611cba84848484612b6a565b50505050565b601d546001600160a01b03163314611cd757600080fd5b60405162438b6360e81b8152336004820152600090309063438b63009060240160006040518083038186803b158015611d0f57600080fd5b505afa158015611d23573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611d4b91908101906137b7565b9050815181511015611db35760405162461bcd60e51b815260206004820152602b60248201527f596f7520646f6e74206861766520656e6f75676820746f6b656e7320746f206160448201526a697264726f7020616c6c2160a81b6064820152608401610bec565b60005b8251811015610d2257611dfc33848381518110611dd557611dd5613d43565b6020026020010151848481518110611def57611def613d43565b6020026020010151612802565b7fe2ae2d4299019f247f9b47047a994e121c067a8a2099ad43a45a99a0e4906d87838281518110611e2f57611e2f613d43565b6020026020010151838381518110611e4957611e49613d43565b6020026020010151604051611e739291906001600160a01b03929092168252602082015260400190565b60405180910390a180611e8581613cb2565b915050611db6565b600e805461177290613c7d565b6000818152600260205260409020546060906001600160a01b0316611f195760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610bec565b6000611f23612b9d565b90506000815111611f435760405180602001604052806000815250611f71565b80611f4d84612bac565b600e604051602001611f6193929190613947565b6040516020818303038152906040525b9392505050565b611f82333061223a565b611fc65760405162461bcd60e51b8152602060048201526015602482015274596f7520617265206e6f7420417070726f7665642160581b6044820152606401610bec565b60005b81811015610d2257612004838383818110611fe657611fe6613d43565b3360009081526018602090815260409091209391020135905061271b565b6120465760405162461bcd60e51b8152602060048201526013602482015272151bdad95b881b9bdd0819195c1bdcda5d1959606a1b6044820152606401610bec565b600b546001600160a01b031663f474c8ce3361207986868681811061206d5761206d613d43565b905060200201356129c3565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156120bf57600080fd5b505af11580156120d3573d6000803e3d6000fd5b5050505061210a8383838181106120ec576120ec613d43565b33600090815260186020908152604090912093910201359050612caa565b5060006019600085858581811061212357612123613d43565b60209081029290920135835250818101929092526040908101600090812093909355338352601a9091528120805460ff191690554290601b9085858581811061216e5761216e613d43565b90506020020135815260200190815260200160002081905550306001600160a01b031663b88d4fde30338686868181106121aa576121aa613d43565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152608060648201526000608482015260a401600060405180830381600087803b15801561220f57600080fd5b505af1158015612223573d6000803e3d6000fd5b50505050808061223290613cb2565b915050611fc9565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b600a546001600160a01b031633146122925760405162461bcd60e51b8152600401610bec90613b14565b6001600160a01b0381166122f75760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610bec565b610fc081612a49565b60145460ff16151560011461231457600080fd5b3360009081526016602052604090205461233160ff831682613bef565b905060018260ff161015801561234c5750600f548260ff1611155b6123905760405162461bcd60e51b8152602060048201526015602482015274135a5b9d08105b5bdd5b9d08125b98dbdc9c9958dd605a1b6044820152606401610bec565b60125461239b611662565b106123b85760405162461bcd60e51b8152600401610bec90613af1565b600f543360009081526016602052604090205411156124145760405162461bcd60e51b8152602060048201526018602482015277596f75277665206d6178656420796f7572206c696d69742160401b6044820152606401610bec565b8160ff166013546124259190613c1b565b3410156124855760405162461bcd60e51b815260206004820152602860248201527f4d696e74696e6720612047656e6573697320436f73747320302e303520457468604482015267657220456163682160c01b6064820152608401610bec565b600f548111156124d75760405162461bcd60e51b815260206004820152601a60248201527f596f75276c6c207375727061737320796f7572206c696d6974210000000000006044820152606401610bec565b60005b8260ff168160ff16101561261d57336000908152601c60205260408120805460019290612508908490613bef565b909155505033600090815260166020526040812080546001929061252d908490613bef565b9091555050600c80546001019055612547336111e8611662565b600b546001600160a01b031663cc240c0133612561611662565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156125a757600080fd5b505af11580156125bb573d6000803e3d6000fd5b505050507f40c10f19c047ae7dfa66d6312b683d2ea3dfbcb4159e96b967c5f4b0a86f2842336125e9611662565b604080516001600160a01b03909316835260208301919091520160405180910390a18061261581613ccd565b9150506124da565b50601254612629611662565b14156112e2576014805461ffff19166101001790555050565b33600090815260186020526040902060609061166d90612cb6565b60006001600160e01b031982166380ac58cd60e01b148061268e57506001600160e01b03198216635b5e139f60e01b145b80610adf57506301ffc9a760e01b6001600160e01b0319831614610adf565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906126e282611672565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008181526001830160205260408120541515611f71565b6000818152600260205260408120546001600160a01b03166127ac5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610bec565b60006127b783611672565b9050806001600160a01b0316846001600160a01b031614806127f25750836001600160a01b03166127e784610b77565b6001600160a01b0316145b80610dac5750610dac818561223a565b826001600160a01b031661281582611672565b6001600160a01b03161461287d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610bec565b6001600160a01b0382166128df5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610bec565b6128ea838383612cc3565b6128f56000826126ad565b6001600160a01b038316600090815260036020526040812080546001929061291e908490613c3a565b90915550506001600160a01b038216600090815260036020526040812080546001929061294c908490613bef565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000610adf825490565b6000611f718383612d7b565b60008082158015906129d757506012548311155b156129f7576129e583610d27565b6129f0906014613c1b565b9050610adf565b60125483118015612a0a57506011548311155b15610adf57612a1883610d27565b611f71906005613c1b565b6112e2828260405180602001604052806000815250612da5565b6000611f718383612dd8565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b03161415612afd5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610bec565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612b75848484612802565b612b8184848484612e27565b611cba5760405162461bcd60e51b8152600401610bec90613a9f565b6060600d8054610af490613c7d565b606081612bd05750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612bfa5780612be481613cb2565b9150612bf39050600a83613c07565b9150612bd4565b60008167ffffffffffffffff811115612c1557612c15613d59565b6040519080825280601f01601f191660200182016040528015612c3f576020820181803683370190505b5090505b8415610dac57612c54600183613c3a565b9150612c61600a86613ced565b612c6c906030613bef565b60f81b818381518110612c8157612c81613d43565b60200101906001600160f81b031916908160001a905350612ca3600a86613c07565b9450612c43565b6000611f718383612f34565b60606000611f7183613027565b6001600160a01b038316612d1e57612d1981600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612d41565b816001600160a01b0316836001600160a01b031614612d4157612d418382613083565b6001600160a01b038216612d5857610d2281613120565b826001600160a01b0316826001600160a01b031614610d2257610d2282826131cf565b6000826000018281548110612d9257612d92613d43565b9060005260206000200154905092915050565b612daf8383613213565b612dbc6000848484612e27565b610d225760405162461bcd60e51b8152600401610bec90613a9f565b6000818152600183016020526040812054612e1f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610adf565b506000610adf565b60006001600160a01b0384163b15612f2957604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612e6b903390899088908890600401613a0b565b602060405180830381600087803b158015612e8557600080fd5b505af1925050508015612eb5575060408051601f3d908101601f19168201909252612eb291810190613860565b60015b612f0f573d808015612ee3576040519150601f19603f3d011682016040523d82523d6000602084013e612ee8565b606091505b508051612f075760405162461bcd60e51b8152600401610bec90613a9f565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610dac565b506001949350505050565b6000818152600183016020526040812054801561301d576000612f58600183613c3a565b8554909150600090612f6c90600190613c3a565b9050818114612fd1576000866000018281548110612f8c57612f8c613d43565b9060005260206000200154905080876000018481548110612faf57612faf613d43565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612fe257612fe2613d2d565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610adf565b6000915050610adf565b60608160000180548060200260200160405190810160405280929190818152602001828054801561307757602002820191906000526020600020905b815481526020019060010190808311613063575b50505050509050919050565b60006001613090846117f3565b61309a9190613c3a565b6000838152600760205260409020549091508082146130ed576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061313290600190613c3a565b6000838152600960205260408120546008805493945090928490811061315a5761315a613d43565b90600052602060002001549050806008838154811061317b5761317b613d43565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806131b3576131b3613d2d565b6001900381819060005260206000200160009055905550505050565b60006131da836117f3565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b0382166132695760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610bec565b6000818152600260205260409020546001600160a01b0316156132ce5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610bec565b6132da60008383612cc3565b6001600160a01b0382166000908152600360205260408120805460019290613303908490613bef565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b82805461336d90613c7d565b90600052602060002090601f01602090048101928261338f57600085556133d5565b82601f106133a857805160ff19168380011785556133d5565b828001600101855582156133d5579182015b828111156133d55782518255916020019190600101906133ba565b506133e19291506133e5565b5090565b5b808211156133e157600081556001016133e6565b600067ffffffffffffffff83111561341457613414613d59565b613427601f8401601f1916602001613b9a565b905082815283838301111561343b57600080fd5b828260208301376000602084830101529392505050565b60006020828403121561346457600080fd5b8135611f7181613d6f565b6000806040838503121561348257600080fd5b823561348d81613d6f565b9150602083013561349d81613d6f565b809150509250929050565b6000806000606084860312156134bd57600080fd5b83356134c881613d6f565b925060208401356134d881613d6f565b929592945050506040919091013590565b60008060008060006080868803121561350157600080fd5b853561350c81613d6f565b9450602086013561351c81613d6f565b935060408601359250606086013567ffffffffffffffff8082111561354057600080fd5b818801915088601f83011261355457600080fd5b81358181111561356357600080fd5b89602082850101111561357557600080fd5b9699959850939650602001949392505050565b6000806000806080858703121561359e57600080fd5b84356135a981613d6f565b935060208501356135b981613d6f565b925060408501359150606085013567ffffffffffffffff8111156135dc57600080fd5b8501601f810187136135ed57600080fd5b6135fc878235602084016133fa565b91505092959194509250565b6000806040838503121561361b57600080fd5b823561362681613d6f565b91506020830135801515811461349d57600080fd5b6000806040838503121561364e57600080fd5b823561365981613d6f565b9150602083013561ffff8116811461349d57600080fd5b6000806040838503121561368357600080fd5b823561368e81613d6f565b946020939093013593505050565b600060208083850312156136af57600080fd5b823567ffffffffffffffff8111156136c657600080fd5b8301601f810185136136d757600080fd5b80356136ea6136e582613bcb565b613b9a565b80828252848201915084840188868560051b870101111561370a57600080fd5b600094505b8385101561373657803561372281613d6f565b83526001949094019391850191850161370f565b50979650505050505050565b6000806020838503121561375557600080fd5b823567ffffffffffffffff8082111561376d57600080fd5b818501915085601f83011261378157600080fd5b81358181111561379057600080fd5b8660208260051b85010111156137a557600080fd5b60209290920196919550909350505050565b600060208083850312156137ca57600080fd5b825167ffffffffffffffff8111156137e157600080fd5b8301601f810185136137f257600080fd5b80516138006136e582613bcb565b80828252848201915084840188868560051b870101111561382057600080fd5b600094505b83851015613736578051835260019490940193918501918501613825565b60006020828403121561385557600080fd5b8135611f7181613d84565b60006020828403121561387257600080fd5b8151611f7181613d84565b60006020828403121561388f57600080fd5b813567ffffffffffffffff8111156138a657600080fd5b8201601f810184136138b757600080fd5b610dac848235602084016133fa565b6000602082840312156138d857600080fd5b5035919050565b6000602082840312156138f157600080fd5b5051919050565b60006020828403121561390a57600080fd5b813560ff81168114611f7157600080fd5b60008151808452613933816020860160208601613c51565b601f01601f19169290920160200192915050565b60008451602061395a8285838a01613c51565b85519184019161396d8184848a01613c51565b8554920191600090600181811c908083168061398a57607f831692505b8583108114156139a857634e487b7160e01b85526022600452602485fd5b8080156139bc57600181146139cd576139fa565b60ff198516885283880195506139fa565b60008b81526020902060005b858110156139f25781548a8201529084019088016139d9565b505083880195505b50939b9a5050505050505050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613a3e9083018461391b565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613a8057835183529284019291840191600101613a64565b50909695505050505050565b602081526000611f71602083018461391b565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b602080825260099082015268534f4c44204f55542160b81b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b604051601f8201601f1916810167ffffffffffffffff81118282101715613bc357613bc3613d59565b604052919050565b600067ffffffffffffffff821115613be557613be5613d59565b5060051b60200190565b60008219821115613c0257613c02613d01565b500190565b600082613c1657613c16613d17565b500490565b6000816000190483118215151615613c3557613c35613d01565b500290565b600082821015613c4c57613c4c613d01565b500390565b60005b83811015613c6c578181015183820152602001613c54565b83811115611cba5750506000910152565b600181811c90821680613c9157607f821691505b6020821081141561134557634e487b7160e01b600052602260045260246000fd5b6000600019821415613cc657613cc6613d01565b5060010190565b600060ff821660ff811415613ce457613ce4613d01565b60010192915050565b600082613cfc57613cfc613d17565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610fc057600080fd5b6001600160e01b031981168114610fc057600080fdfea2646970667358221220a10847e6cf20c66bce0dfc9f136d780180511ecda3b9a86ce938006f46eec85264736f6c63430008070033

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

0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005668747470733a2f2f636f736d69636c6162732e6d7970696e6174612e636c6f75642f697066732f516d4e594866635074567a58686d487a645a576f66746377465377627453335669536a4a47576b524663655a53352f00000000000000000000

-----Decoded View---------------
Arg [0] : _initBaseURI (string): https://cosmiclabs.mypinata.cloud/ipfs/QmNYHfcPtVzXhmHzdZWoftcwFSwbtS3ViSjJGWkRFceZS5/

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000056
Arg [2] : 68747470733a2f2f636f736d69636c6162732e6d7970696e6174612e636c6f75
Arg [3] : 642f697066732f516d4e594866635074567a58686d487a645a576f6674637746
Arg [4] : 5377627453335669536a4a47576b524663655a53352f00000000000000000000


Deployed Bytecode Sourcemap

85700:11543:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79430:224;;;;;;;;;;-1:-1:-1;79430:224:0;;;;;:::i;:::-;;:::i;:::-;;;13225:14:1;;13218:22;13200:41;;13188:2;13173:18;79430:224:0;;;;;;;;66871:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;68430:221::-;;;;;;;;;;-1:-1:-1;68430:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;10756:32:1;;;10738:51;;10726:2;10711:18;68430:221:0;10592:203:1;67953:411:0;;;;;;;;;;-1:-1:-1;67953:411:0;;;;;:::i;:::-;;:::i;:::-;;86330:39;;;;;;;;;;-1:-1:-1;86330:39:0;;;;;;;;;;;92396:100;;;;;;;;;;-1:-1:-1;92467:21:0;92396:100;;;25299:25:1;;;25287:2;25272:18;92396:100:0;25153:177:1;97021:219:0;;;;;;;;;;-1:-1:-1;97021:219:0;;;;;:::i;:::-;-1:-1:-1;;;97021:219:0;;;;;;;;;;;-1:-1:-1;;;;;;13414:33:1;;;13396:52;;13384:2;13369:18;97021:219:0;13252:202:1;80070:113:0;;;;;;;;;;-1:-1:-1;80158:10:0;:17;80070:113;;95959:402;;;;;;;;;;-1:-1:-1;95959:402:0;;;;;:::i;:::-;;:::i;69180:339::-;;;;;;;;;;-1:-1:-1;69180:339:0;;;;;:::i;:::-;;:::i;87903:101::-;;;;;;;;;;-1:-1:-1;87903:101:0;;;;;:::i;:::-;;:::i;79738:256::-;;;;;;;;;;-1:-1:-1;79738:256:0;;;;;:::i;:::-;;:::i;95189:309::-;;;;;;;;;;;;;:::i;87043:44::-;;;;;;;;;;-1:-1:-1;87043:44:0;;;;;:::i;:::-;;;;;;;;;;;;;;90351:1032;;;;;;:::i;:::-;;:::i;94876:301::-;;;;;;;;;;;;;:::i;69590:185::-;;;;;;;;;;-1:-1:-1;69590:185:0;;;;;:::i;:::-;;:::i;96373:353::-;;;;;;;;;;-1:-1:-1;96373:353:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;86198:32::-;;;;;;;;;;;;;;;;86290:33;;;;;;;;;;-1:-1:-1;86290:33:0;;;;;;;;86755:134;;;;;;;;;;;;;:::i;80260:233::-;;;;;;;;;;-1:-1:-1;80260:233:0;;;;;:::i;:::-;;:::i;85865:30::-;;;;;;;;;;-1:-1:-1;85865:30:0;;;;-1:-1:-1;;;;;85865:30:0;;;87447:49;;;;;;;;;;-1:-1:-1;87447:49:0;;;;;:::i;:::-;;;;;;;;;;;;;;92626:104;;;;;;;;;;-1:-1:-1;92626:104:0;;;;;:::i;:::-;;:::i;87160:50::-;;;;;;;;;;-1:-1:-1;87160:50:0;;;;;:::i;:::-;;;;;;;;;;;;;;93283:697;;;;;;;;;;-1:-1:-1;93283:697:0;;;;;:::i;:::-;;:::i;88010:107::-;;;;;;;;;;;;;:::i;66565:239::-;;;;;;;;;;-1:-1:-1;66565:239:0;;;;;:::i;:::-;;:::i;96880:124::-;;;;;;;;;;;;;:::i;86003:21::-;;;;;;;;;;;;;:::i;66295:208::-;;;;;;;;;;-1:-1:-1;66295:208:0;;;;;:::i;:::-;;:::i;45417:103::-;;;;;;;;;;;;;:::i;87100:53::-;;;;;;;;;;-1:-1:-1;87100:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;87503:55;;;;;;;;;;-1:-1:-1;87503:55:0;;;;;:::i;:::-;;;;;;;;;;;;;;91399:229;;;;;;:::i;:::-;;:::i;44766:87::-;;;;;;;;;;-1:-1:-1;44839:6:0;;-1:-1:-1;;;;;44839:6:0;44766:87;;87796:90;;;;;;;;;;-1:-1:-1;87796:90:0;;;;;:::i;:::-;;:::i;67040:104::-;;;;;;;;;;;;;:::i;87301:50::-;;;;;;;;;;-1:-1:-1;87301:50:0;;;;;:::i;:::-;;;;;;;;;;;;;;89679:661;;;;;;:::i;:::-;;:::i;86243:33::-;;;;;;;;;;;;;;;;92219:171;;;;;;;;;;-1:-1:-1;92219:171:0;;;;;:::i;:::-;;:::i;68723:155::-;;;;;;;;;;-1:-1:-1;68723:155:0;;;;;:::i;:::-;;:::i;86376:32::-;;;;;;;;;;-1:-1:-1;86376:32:0;;;;;;;;;;;88244:248;;;;;;;;;;-1:-1:-1;88244:248:0;;;;;:::i;:::-;;:::i;69846:328::-;;;;;;;;;;-1:-1:-1;69846:328:0;;;;;:::i;:::-;;:::i;86083:28::-;;;;;;;;;;;;;;;;91640:563;;;;;;:::i;:::-;;:::i;86031:37::-;;;;;;;;;;;;;:::i;92741:375::-;;;;;;;;;;-1:-1:-1;92741:375:0;;;;;:::i;:::-;;:::i;86118:26::-;;;;;;;;;;;;;;;;93986:876;;;;;;;;;;-1:-1:-1;93986:876:0;;;;;:::i;:::-;;:::i;86163:28::-;;;;;;;;;;;;;;;;87364:45;;;;;;;;;;-1:-1:-1;87364:45:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;68949:164;;;;;;;;;;-1:-1:-1;68949:164:0;;;;;:::i;:::-;;:::i;45675:201::-;;;;;;;;;;-1:-1:-1;45675:201:0;;;;;:::i;:::-;;:::i;88500:1170::-;;;;;;:::i;:::-;;:::i;96738:130::-;;;;;;;;;;;;;:::i;79430:224::-;79532:4;-1:-1:-1;;;;;;79556:50:0;;-1:-1:-1;;;79556:50:0;;:90;;;79610:36;79634:11;79610:23;:36::i;:::-;79549:97;79430:224;-1:-1:-1;;79430:224:0:o;66871:100::-;66925:13;66958:5;66951:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66871:100;:::o;68430:221::-;68506:7;71773:16;;;:7;:16;;;;;;-1:-1:-1;;;;;71773:16:0;68526:73;;;;-1:-1:-1;;;68526:73:0;;20720:2:1;68526:73:0;;;20702:21:1;20759:2;20739:18;;;20732:30;20798:34;20778:18;;;20771:62;-1:-1:-1;;;20849:18:1;;;20842:42;20901:19;;68526:73:0;;;;;;;;;-1:-1:-1;68619:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;68619:24:0;;68430:221::o;67953:411::-;68034:13;68050:23;68065:7;68050:14;:23::i;:::-;68034:39;;68098:5;-1:-1:-1;;;;;68092:11:0;:2;-1:-1:-1;;;;;68092:11:0;;;68084:57;;;;-1:-1:-1;;;68084:57:0;;23763:2:1;68084:57:0;;;23745:21:1;23802:2;23782:18;;;23775:30;23841:34;23821:18;;;23814:62;-1:-1:-1;;;23892:18:1;;;23885:31;23933:19;;68084:57:0;23561:397:1;68084:57:0;29053:10;-1:-1:-1;;;;;68176:21:0;;;;:62;;-1:-1:-1;68201:37:0;68218:5;29053:10;68949:164;:::i;68201:37::-;68154:168;;;;-1:-1:-1;;;68154:168:0;;17648:2:1;68154:168:0;;;17630:21:1;17687:2;17667:18;;;17660:30;17726:34;17706:18;;;17699:62;17797:26;17777:18;;;17770:54;17841:19;;68154:168:0;17446:420:1;68154:168:0;68335:21;68344:2;68348:7;68335:8;:21::i;:::-;68023:341;67953:411;;:::o;95959:402::-;96090:10;96023:7;96080:21;;;:9;:21;;;;;:39;;96111:7;96080:30;:39::i;:::-;96058:108;;;;-1:-1:-1;;;96058:108:0;;20011:2:1;96058:108:0;;;19993:21:1;20050:2;20030:18;;;20023:30;-1:-1:-1;;;20069:18:1;;;20062:49;20128:18;;96058:108:0;19809:343:1;96058:108:0;96187:18;96253:23;;;:14;:23;;;;;;96187:18;;96235:41;;:15;:41;:::i;:::-;96216:60;-1:-1:-1;96300:16:0;96311:5;96216:60;96300:16;:::i;:::-;96287:29;95959:402;-1:-1:-1;;;;95959:402:0:o;69180:339::-;69375:41;29053:10;69408:7;69375:18;:41::i;:::-;69367:103;;;;-1:-1:-1;;;69367:103:0;;;;;;;:::i;:::-;69483:28;69493:4;69499:2;69503:7;69483:9;:28::i;87903:101::-;44839:6;;-1:-1:-1;;;;;44839:6:0;29053:10;44986:23;44978:68;;;;-1:-1:-1;;;44978:68:0;;;;;;;:::i;:::-;87966:11:::1;:33:::0;;-1:-1:-1;;;;;;87966:33:0::1;-1:-1:-1::0;;;;;87966:33:0;;;::::1;::::0;;;::::1;::::0;;87903:101::o;79738:256::-;79835:7;79871:23;79888:5;79871:16;:23::i;:::-;79863:5;:31;79855:87;;;;-1:-1:-1;;;79855:87:0;;14113:2:1;79855:87:0;;;14095:21:1;14152:2;14132:18;;;14125:30;14191:34;14171:18;;;14164:62;-1:-1:-1;;;14242:18:1;;;14235:41;14293:19;;79855:87:0;13911:407:1;79855:87:0;-1:-1:-1;;;;;;79960:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;79738:256::o;95189:309::-;95242:9;95238:253;95271:10;95261:21;;;;:9;:21;;;;;:30;;:28;:30::i;:::-;95257:1;:34;95238:253;;;95322:11;;95344:10;95322:11;95374:21;;;:9;:21;;;;;-1:-1:-1;;;;;95322:11:0;;;;:21;;95344:10;95356:46;;95374:27;;95399:1;95374:24;:27::i;:::-;95356:17;:46::i;:::-;95322:81;;-1:-1:-1;;;;;;95322:81:0;;;;;;;-1:-1:-1;;;;;12336:32:1;;;95322:81:0;;;12318:51:1;12385:18;;;12378:34;12291:18;;95322:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;95443:10:0;95418:43;95433:21;;;:9;:21;;;;;95464:15;;-1:-1:-1;95418:14:0;;-1:-1:-1;95433:27:0;;95458:1;95433:24;:27::i;:::-;95418:43;;;;;;;;;;;-1:-1:-1;95418:43:0;:61;95293:3;;;;:::i;:::-;;;;95238:253;;;;95189:309::o;90351:1032::-;86693:12;;;;;;;:20;;86709:4;86693:20;86685:29;;;;;;90469:10:::1;90431:19;90453:27:::0;;;:15:::1;:27;::::0;;;;;90505:23:::1;;::::0;::::1;90453:27:::0;90505:23:::1;:::i;:::-;90491:37;;90574:1;90561:9;:14;;;;:40;;;;;90592:9;;90579;:22;;;;90561:40;90553:74;;;::::0;-1:-1:-1;;;90553:74:0;;21470:2:1;90553:74:0::1;::::0;::::1;21452:21:1::0;21509:2;21489:18;;;21482:30;-1:-1:-1;;;21528:18:1;;;21521:51;21589:18;;90553:74:0::1;21268:345:1::0;90553:74:0::1;90667:9;90659:17;;:5;;:17;;;;:::i;:::-;90646:9;:30;;90638:80;;;::::0;-1:-1:-1;;;90638:80:0;;22181:2:1;90638:80:0::1;::::0;::::1;22163:21:1::0;22220:2;22200:18;;;22193:30;22259:34;22239:18;;;22232:62;-1:-1:-1;;;22310:18:1;;;22303:35;22355:19;;90638:80:0::1;21979:401:1::0;90638:80:0::1;90752:9;;90737:12;:10;:12::i;:::-;:24;90729:46;;;;-1:-1:-1::0;;;90729:46:0::1;;;;;;;:::i;:::-;90825:9;::::0;90810:10:::1;90794:27;::::0;;;:15:::1;:27;::::0;;;;;:40:::1;;90786:77;;;::::0;-1:-1:-1;;;90786:77:0;;19658:2:1;90786:77:0::1;::::0;::::1;19640:21:1::0;19697:2;19677:18;;;19670:30;-1:-1:-1;;;19716:18:1;;;19709:54;19780:18;;90786:77:0::1;19456:348:1::0;90786:77:0::1;90897:9;;90882:11;:24;;90874:63;;;::::0;-1:-1:-1;;;90874:63:0;;19303:2:1;90874:63:0::1;::::0;::::1;19285:21:1::0;19342:2;19322:18;;;19315:30;19381:28;19361:18;;;19354:56;19427:18;;90874:63:0::1;19101:350:1::0;90874:63:0::1;90962:7;90958:312;90974:9;90972:11;;:1;:11;;;90958:312;;;91029:10;91013:27;::::0;;;:15:::1;:27;::::0;;;;:32;;91044:1:::1;::::0;91013:27;:32:::1;::::0;91044:1;;91013:32:::1;:::i;:::-;::::0;;;-1:-1:-1;;91060:15:0::1;11838:19:::0;;11856:1;11838:19;;;91102:35:::1;91112:10;91124:12;:10;:12::i;:::-;91102:9;:35::i;:::-;91152:11;::::0;-1:-1:-1;;;;;91152:11:0::1;:30;91183:10;91195:12;:10;:12::i;:::-;91152:56;::::0;-1:-1:-1;;;;;;91152:56:0::1;::::0;;;;;;-1:-1:-1;;;;;12336:32:1;;;91152:56:0::1;::::0;::::1;12318:51:1::0;12385:18;;;12378:34;12291:18;;91152:56:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;91228:30;91233:10;91245:12;:10;:12::i;:::-;91228:30;::::0;;-1:-1:-1;;;;;12336:32:1;;;12318:51;;12400:2;12385:18;;12378:34;;;;12291:18;91228:30:0::1;;;;;;;90984:3:::0;::::1;::::0;::::1;:::i;:::-;;;;90958:312;;;;91309:9;;91293:12;:10;:12::i;:::-;:25;91290:86;;;91344:12;:20:::0;;-1:-1:-1;;91344:20:0::1;::::0;;91290:86:::1;90420:963;90351:1032:::0;:::o;94876:301::-;94922:7;;;94986:160;95019:10;95009:21;;;;:9;:21;;;;;:30;;:28;:30::i;:::-;95005:1;:34;94986:160;;;95116:10;95106:21;;;;:9;:21;;;;;95088:46;;95106:27;;95131:1;95106:24;:27::i;95088:46::-;95079:55;;:6;:55;:::i;:::-;95070:64;-1:-1:-1;95041:3:0;;;;:::i;:::-;;;;94986:160;;;-1:-1:-1;95163:6:0;94876:301;-1:-1:-1;94876:301:0:o;69590:185::-;69728:39;69745:4;69751:2;69755:7;69728:39;;;;;;;;;;;;:16;:39::i;96373:353::-;96435:16;96464:18;96485:17;96495:6;96485:9;:17::i;:::-;96464:38;;96515:25;96557:10;96543:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;96543:25:0;;96515:53;;96584:9;96579:112;96603:10;96599:1;:14;96579:112;;;96649:30;96669:6;96677:1;96649:19;:30::i;:::-;96635:8;96644:1;96635:11;;;;;;;;:::i;:::-;;;;;;;;;;:44;96615:3;;;;:::i;:::-;;;;96579:112;;;-1:-1:-1;96710:8:0;96373:353;-1:-1:-1;;;96373:353:0:o;86755:134::-;44839:6;;-1:-1:-1;;;;;44839:6:0;29053:10;44986:23;44978:68;;;;-1:-1:-1;;;44978:68:0;;;;;;;:::i;:::-;86824:19:::1;:27:::0;;-1:-1:-1;;86862:19:0;;::::1;::::0;;86755:134::o;80260:233::-;80335:7;80371:30;80158:10;:17;;80070:113;80371:30;80363:5;:38;80355:95;;;;-1:-1:-1;;;80355:95:0;;24583:2:1;80355:95:0;;;24565:21:1;24622:2;24602:18;;;24595:30;24661:34;24641:18;;;24634:62;-1:-1:-1;;;24712:18:1;;;24705:42;24764:19;;80355:95:0;24381:408:1;80355:95:0;80468:10;80479:5;80468:17;;;;;;;;:::i;:::-;;;;;;;;;80461:24;;80260:233;;;:::o;92626:104::-;44839:6;;-1:-1:-1;;;;;44839:6:0;29053:10;44986:23;44978:68;;;;-1:-1:-1;;;44978:68:0;;;;;;;:::i;:::-;92701:21;;::::1;::::0;:7:::1;::::0;:21:::1;::::0;::::1;::::0;::::1;:::i;93283:697::-:0;93372:43;93389:10;93409:4;93372:16;:43::i;:::-;93364:77;;;;-1:-1:-1;;;93364:77:0;;23413:2:1;93364:77:0;;;23395:21:1;23452:2;23432:18;;;23425:30;-1:-1:-1;;;23471:18:1;;;23464:51;23532:18;;93364:77:0;23211:345:1;93364:77:0;93477:9;93472:491;93488:19;;;93472:491;;;93529:143;93564:10;93601:4;93625:8;;93634:1;93625:11;;;;;;;:::i;:::-;;;;;;;93529:143;;;;;;;;;;;;:16;:143::i;:::-;93701:38;93727:8;;93736:1;93727:11;;;;;;;:::i;:::-;93711:10;93701:21;;;;:9;93727:11;93701:21;;;;;;;;93727:11;;;;;-1:-1:-1;93701:25:0;:38::i;:::-;-1:-1:-1;93768:10:0;93754:25;;;;:13;:25;;;;;:32;;-1:-1:-1;;93754:32:0;93782:4;93754:32;;;93860:15;;93829;;93845:8;;93854:1;93845:11;;;;;;;:::i;:::-;;;;;;;93829:28;;;;;;;;;;;:46;;;;93936:15;93906:14;:27;93921:8;;93930:1;93921:11;;;;;;;:::i;:::-;;;;;;;93906:27;;;;;;;;;;;:45;;;;93509:3;;;;;:::i;:::-;;;;93472:491;;88010:107;88053:7;88084:25;:15;11719:14;;11627:114;88084:25;88077:32;;88010:107;:::o;66565:239::-;66637:7;66673:16;;;:7;:16;;;;;;-1:-1:-1;;;;;66673:16:0;66708:19;66700:73;;;;-1:-1:-1;;;66700:73:0;;18893:2:1;66700:73:0;;;18875:21:1;18932:2;18912:18;;;18905:30;18971:34;18951:18;;;18944:62;-1:-1:-1;;;19022:18:1;;;19015:39;19071:19;;66700:73:0;18691:405:1;96880:124:0;96963:11;;:33;;-1:-1:-1;;;96963:33:0;;96985:10;96963:33;;;10738:51:1;96931:7:0;;-1:-1:-1;;;;;96963:11:0;;:21;;10711:18:1;;96963:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;86003:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;66295:208::-;66367:7;-1:-1:-1;;;;;66395:19:0;;66387:74;;;;-1:-1:-1;;;66387:74:0;;18482:2:1;66387:74:0;;;18464:21:1;18521:2;18501:18;;;18494:30;18560:34;18540:18;;;18533:62;-1:-1:-1;;;18611:18:1;;;18604:40;18661:19;;66387:74:0;18280:406:1;66387:74:0;-1:-1:-1;;;;;;66479:16:0;;;;;:9;:16;;;;;;;66295:208::o;45417:103::-;44839:6;;-1:-1:-1;;;;;44839:6:0;29053:10;44986:23;44978:68;;;;-1:-1:-1;;;44978:68:0;;;;;;;:::i;:::-;45482:30:::1;45509:1;45482:18;:30::i;:::-;45417:103::o:0;91399:229::-;88197:15;;-1:-1:-1;;;;;88197:15:0;88183:10;:29;88175:38;;;;;;91514:50:::1;91524:10;91536:18;91556:7;91514:50;;:9;:50::i;:::-;91580:40;::::0;;-1:-1:-1;;;;;12044:32:1;;12026:51;;12125:6;12113:19;;12108:2;12093:18;;12086:47;91580:40:0::1;::::0;11999:18:1;91580:40:0::1;;;;;;;91399:229:::0;;:::o;87796:90::-;44839:6;;-1:-1:-1;;;;;44839:6:0;29053:10;44986:23;44978:68;;;;-1:-1:-1;;;44978:68:0;;;;;;;:::i;:::-;87862:5:::1;:16:::0;87796:90::o;67040:104::-;67096:13;67129:7;67122:14;;;;;:::i;89679:661::-;86583:19;;;;;;;;:27;;:19;:27;86575:36;;;;;;89794:10:::1;89808:1;89774:31:::0;;;:19:::1;:31;::::0;;;;;89766:78:::1;;;::::0;-1:-1:-1;;;89766:78:0;;24996:2:1;89766:78:0::1;::::0;::::1;24978:21:1::0;25035:2;25015:18;;;25008:30;25074:32;25054:18;;;25047:60;25124:18;;89766:78:0::1;24794:354:1::0;89766:78:0::1;89878:9;;89863:12;:10;:12::i;:::-;:24;89855:46;;;;-1:-1:-1::0;;;89855:46:0::1;;;;;;;:::i;:::-;89953:10;89933:31;::::0;;;:19:::1;:31;::::0;;;;;89920:44:::1;::::0;::::1;;;89912:84;;;::::0;-1:-1:-1;;;89912:84:0;;15708:2:1;89912:84:0::1;::::0;::::1;15690:21:1::0;15747:2;15727:18;;;15720:30;15786:29;15766:18;;;15759:57;15833:18;;89912:84:0::1;15506:351:1::0;89912:84:0::1;90021:7;90017:316;90033:9;90031:11;;:1;:11;;;90017:316;;;90092:10;90072:31;::::0;;;:19:::1;:31;::::0;;;;:36;;90107:1:::1;::::0;90072:31;:36:::1;::::0;90107:1;;90072:36:::1;:::i;:::-;::::0;;;-1:-1:-1;;90123:15:0::1;11838:19:::0;;11856:1;11838:19;;;90165:35:::1;90175:10;90187:12;:10;:12::i;90165:35::-;90215:11;::::0;-1:-1:-1;;;;;90215:11:0::1;:30;90246:10;90258:12;:10;:12::i;:::-;90215:56;::::0;-1:-1:-1;;;;;;90215:56:0::1;::::0;;;;;;-1:-1:-1;;;;;12336:32:1;;;90215:56:0::1;::::0;::::1;12318:51:1::0;12385:18;;;12378:34;12291:18;;90215:56:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;90291:30;90296:10;90308:12;:10;:12::i;:::-;90291:30;::::0;;-1:-1:-1;;;;;12336:32:1;;;12318:51;;12400:2;12385:18;;12378:34;;;;12291:18;90291:30:0::1;;;;;;;90043:3:::0;::::1;::::0;::::1;:::i;:::-;;;;90017:316;;92219:171:::0;44839:6;;-1:-1:-1;;;;;44839:6:0;29053:10;44986:23;44978:68;;;;-1:-1:-1;;;44978:68:0;;;;;;;:::i;:::-;92317:22:::1;92467:21:::0;92317:22:::1;::::0;25299:25:1;;;25287:2;25272:18;92317:22:0::1;;;;;;;92350:32;::::0;-1:-1:-1;;;;;92350:18:0;::::1;::::0;92467:21;92350:32;::::1;;;::::0;::::1;::::0;;;92467:21;92350:18;:32;::::1;;;;;;;;;;;;;::::0;::::1;;;;68723:155:::0;68818:52;29053:10;68851:8;68861;68818:18;:52::i;88244:248::-;44839:6;;-1:-1:-1;;;;;44839:6:0;29053:10;44986:23;44978:68;;;;-1:-1:-1;;;44978:68:0;;;;;;;:::i;:::-;88332:9:::1;88328:160;88345:17;88343:1;:19;88328:160;;;88394:27;:15;11838:19:::0;;11856:1;11838:19;;;11749:127;88394:27:::1;88446:15;::::0;88436:40:::1;::::0;-1:-1:-1;;;;;88446:15:0::1;88463:12;:10;:12::i;88436:40::-;88364:3:::0;::::1;::::0;::::1;:::i;:::-;;;;88328:160;;69846:328:::0;70021:41;29053:10;70054:7;70021:18;:41::i;:::-;70013:103;;;;-1:-1:-1;;;70013:103:0;;;;;;;:::i;:::-;70127:39;70141:4;70147:2;70151:7;70160:5;70127:13;:39::i;:::-;69846:328;;;;:::o;91640:563::-;88197:15;;-1:-1:-1;;;;;88197:15:0;88183:10;:29;88175:38;;;;;;91786:30:::1;::::0;-1:-1:-1;;;91786:30:0;;91805:10:::1;91786:30;::::0;::::1;10738:51:1::0;91750:33:0::1;::::0;91786:4:::1;::::0;:18:::1;::::0;10711::1;;91786:30:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;91786:30:0::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;91750:66;;91872:19;:26;91845:16;:23;:53;;91837:109;;;::::0;-1:-1:-1;;;91837:109:0;;16064:2:1;91837:109:0::1;::::0;::::1;16046:21:1::0;16103:2;16083:18;;;16076:30;16142:34;16122:18;;;16115:62;-1:-1:-1;;;16193:18:1;;;16186:41;16244:19;;91837:109:0::1;15862:407:1::0;91837:109:0::1;91970:9;91966:228;91985:19;:26;91983:1;:28;91966:228;;;92041:66;92051:10;92063:19;92083:1;92063:22;;;;;;;;:::i;:::-;;;;;;;92087:16;92104:1;92087:19;;;;;;;;:::i;:::-;;;;;;;92041:9;:66::i;:::-;92127:56;92139:19;92159:1;92139:22;;;;;;;;:::i;:::-;;;;;;;92163:16;92180:1;92163:19;;;;;;;;:::i;:::-;;;;;;;92127:56;;;;;;-1:-1:-1::0;;;;;12336:32:1;;;;12318:51;;12400:2;12385:18;;12378:34;12306:2;12291:18;;12144:274;92127:56:0::1;;;;;;;;92013:3:::0;::::1;::::0;::::1;:::i;:::-;;;;91966:228;;86031:37:::0;;;;;;;:::i;92741:375::-;71749:4;71773:16;;;:7;:16;;;;;;92814:13;;-1:-1:-1;;;;;71773:16:0;92845:76;;;;-1:-1:-1;;;92845:76:0;;22997:2:1;92845:76:0;;;22979:21:1;23036:2;23016:18;;;23009:30;23075:34;23055:18;;;23048:62;-1:-1:-1;;;23126:18:1;;;23119:45;23181:19;;92845:76:0;22795:411:1;92845:76:0;92934:28;92965:10;:8;:10::i;:::-;92934:41;;93024:1;92999:14;92993:28;:32;:115;;;;;;;;;;;;;;;;;93052:14;93068:18;:7;:16;:18::i;:::-;93088:13;93035:67;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;92993:115;92986:122;92741:375;-1:-1:-1;;;92741:375:0:o;93986:876::-;94076:43;94093:10;94113:4;94076:16;:43::i;:::-;94068:77;;;;-1:-1:-1;;;94068:77:0;;23413:2:1;94068:77:0;;;23395:21:1;23452:2;23432:18;;;23425:30;-1:-1:-1;;;23471:18:1;;;23464:51;23532:18;;94068:77:0;23211:345:1;94068:77:0;94171:9;94166:689;94182:19;;;94166:689;;;94249:43;94280:8;;94289:1;94280:11;;;;;;;:::i;:::-;94259:10;94249:21;;;;:9;94280:11;94249:21;;;;;;;;94280:11;;;;;-1:-1:-1;94249:30:0;:43::i;:::-;94223:124;;;;-1:-1:-1;;;94223:124:0;;20011:2:1;94223:124:0;;;19993:21:1;20050:2;20030:18;;;20023:30;-1:-1:-1;;;20069:18:1;;;20062:49;20128:18;;94223:124:0;19809:343:1;94223:124:0;94376:11;;-1:-1:-1;;;;;94376:11:0;:21;94398:10;94409:30;94427:8;;94436:1;94427:11;;;;;;;:::i;:::-;;;;;;;94409:17;:30::i;:::-;94376:64;;-1:-1:-1;;;;;;94376:64:0;;;;;;;-1:-1:-1;;;;;12336:32:1;;;94376:64:0;;;12318:51:1;12385:18;;;12378:34;12291:18;;94376:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94469:41;94498:8;;94507:1;94498:11;;;;;;;:::i;:::-;94479:10;94469:21;;;;:9;94498:11;94469:21;;;;;;;;94498:11;;;;;-1:-1:-1;94469:28:0;:41::i;:::-;;94557:1;94526:15;:28;94542:8;;94551:1;94542:11;;;;;;;:::i;:::-;;;;;;;;;;94526:28;;-1:-1:-1;94526:28:0;;;;;;;;;;;-1:-1:-1;94526:28:0;;;:32;;;;94587:10;94573:25;;:13;:25;;;;;:33;;-1:-1:-1;;94573:33:0;;;94651:15;;94621:14;;94636:8;;94645:1;94636:11;;;;;;;:::i;:::-;;;;;;;94621:27;;;;;;;;;;;:45;;;;94695:4;-1:-1:-1;;;;;94695:21:0;;94743:4;94767:10;94796:8;;94805:1;94796:11;;;;;;;:::i;:::-;94695:148;;-1:-1:-1;;;;;;94695:148:0;;;;;;;-1:-1:-1;;;;;11616:15:1;;;94695:148:0;;;11598:34:1;11668:15;;;;11648:18;;;11641:43;-1:-1:-1;94796:11:0;;;;;;11700:18:1;;;11693:34;11763:3;11743:18;;;11736:31;-1:-1:-1;11783:19:1;;;11776:30;11823:19;;94695:148:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94203:3;;;;;:::i;:::-;;;;94166:689;;68949:164;-1:-1:-1;;;;;69070:25:0;;;69046:4;69070:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;68949:164::o;45675:201::-;44839:6;;-1:-1:-1;;;;;44839:6:0;29053:10;44986:23;44978:68;;;;-1:-1:-1;;;44978:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;45764:22:0;::::1;45756:73;;;::::0;-1:-1:-1;;;45756:73:0;;14944:2:1;45756:73:0::1;::::0;::::1;14926:21:1::0;14983:2;14963:18;;;14956:30;15022:34;15002:18;;;14995:62;-1:-1:-1;;;15073:18:1;;;15066:36;15119:19;;45756:73:0::1;14742:402:1::0;45756:73:0::1;45840:28;45859:8;45840:18;:28::i;88500:1170::-:0;86478:14;;;;:22;;:14;:22;86470:31;;;;;;88621:10:::1;88580:19;88602:30:::0;;;:18:::1;:30;::::0;;;;;88657:23:::1;;::::0;::::1;88602:30:::0;88657:23:::1;:::i;:::-;88643:37;;88722:1;88709:9;:14;;;;:43;;;;;88740:12;;88727:9;:25;;;;88709:43;88701:77;;;::::0;-1:-1:-1;;;88701:77:0;;21470:2:1;88701:77:0::1;::::0;::::1;21452:21:1::0;21509:2;21489:18;;;21482:30;-1:-1:-1;;;21528:18:1;;;21521:51;21589:18;;88701:77:0::1;21268:345:1::0;88701:77:0::1;88812:13;;88797:12;:10;:12::i;:::-;:28;88789:50;;;;-1:-1:-1::0;;;88789:50:0::1;;;;;;;:::i;:::-;88892:12;::::0;88877:10:::1;88858:30;::::0;;;:18:::1;:30;::::0;;;;;:46:::1;;88850:83;;;::::0;-1:-1:-1;;;88850:83:0;;19658:2:1;88850:83:0::1;::::0;::::1;19640:21:1::0;19697:2;19677:18;;;19670:30;-1:-1:-1;;;19716:18:1;;;19709:54;19780:18;;88850:83:0::1;19456:348:1::0;88850:83:0::1;88973:9;88965:17;;:5;;:17;;;;:::i;:::-;88952:9;:30;;88944:83;;;::::0;-1:-1:-1;;;88944:83:0;;18073:2:1;88944:83:0::1;::::0;::::1;18055:21:1::0;18112:2;18092:18;;;18085:30;18151:34;18131:18;;;18124:62;-1:-1:-1;;;18202:18:1;;;18195:38;18250:19;;88944:83:0::1;17871:404:1::0;88944:83:0::1;89061:12;;89046:11;:27;;89038:66;;;::::0;-1:-1:-1;;;89038:66:0;;19303:2:1;89038:66:0::1;::::0;::::1;19285:21:1::0;19342:2;19322:18;;;19315:30;19381:28;19361:18;;;19354:56;19427:18;;89038:66:0::1;19101:350:1::0;89038:66:0::1;89139:7;89135:366;89151:9;89149:11;;:1;:11;;;89135:366;;;89210:10;89190:31;::::0;;;:19:::1;:31;::::0;;;;:36;;89225:1:::1;::::0;89190:31;:36:::1;::::0;89225:1;;89190:36:::1;:::i;:::-;::::0;;;-1:-1:-1;;89260:10:0::1;89241:30;::::0;;;:18:::1;:30;::::0;;;;:35;;89275:1:::1;::::0;89241:30;:35:::1;::::0;89275:1;;89241:35:::1;:::i;:::-;::::0;;;-1:-1:-1;;89291:15:0::1;11838:19:::0;;11856:1;11838:19;;;89333:35:::1;89343:10;89355:12;:10;:12::i;89333:35::-;89383:11;::::0;-1:-1:-1;;;;;89383:11:0::1;:30;89414:10;89426:12;:10;:12::i;:::-;89383:56;::::0;-1:-1:-1;;;;;;89383:56:0::1;::::0;;;;;;-1:-1:-1;;;;;12336:32:1;;;89383:56:0::1;::::0;::::1;12318:51:1::0;12385:18;;;12378:34;12291:18;;89383:56:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;89459:30;89464:10;89476:12;:10;:12::i;:::-;89459:30;::::0;;-1:-1:-1;;;;;12336:32:1;;;12318:51;;12400:2;12385:18;;12378:34;;;;12291:18;89459:30:0::1;;;;;;;89161:3:::0;::::1;::::0;::::1;:::i;:::-;;;;89135:366;;;;89540:13;;89524:12;:10;:12::i;:::-;:29;89521:133;;;89579:14;:22:::0;;-1:-1:-1;;89616:26:0;89579:22:::1;89616:26;::::0;;88569:1101:::1;88500:1170:::0;:::o;96738:130::-;96840:10;96830:21;;;;:9;:21;;;;;96789:16;;96830:30;;:28;:30::i;65926:305::-;66028:4;-1:-1:-1;;;;;;66065:40:0;;-1:-1:-1;;;66065:40:0;;:105;;-1:-1:-1;;;;;;;66122:48:0;;-1:-1:-1;;;66122:48:0;66065:105;:158;;;-1:-1:-1;;;;;;;;;;57519:40:0;;;66187:36;57410:157;75666:174;75741:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;75741:29:0;-1:-1:-1;;;;;75741:29:0;;;;;;;;:24;;75795:23;75741:24;75795:14;:23::i;:::-;-1:-1:-1;;;;;75786:46:0;;;;;;;;;;;75666:174;;:::o;24407:146::-;24484:4;17467:19;;;:12;;;:19;;;;;;:24;;24508:37;17370:129;71978:348;72071:4;71773:16;;;:7;:16;;;;;;-1:-1:-1;;;;;71773:16:0;72088:73;;;;-1:-1:-1;;;72088:73:0;;17235:2:1;72088:73:0;;;17217:21:1;17274:2;17254:18;;;17247:30;17313:34;17293:18;;;17286:62;-1:-1:-1;;;17364:18:1;;;17357:42;17416:19;;72088:73:0;17033:408:1;72088:73:0;72172:13;72188:23;72203:7;72188:14;:23::i;:::-;72172:39;;72241:5;-1:-1:-1;;;;;72230:16:0;:7;-1:-1:-1;;;;;72230:16:0;;:51;;;;72274:7;-1:-1:-1;;;;;72250:31:0;:20;72262:7;72250:11;:20::i;:::-;-1:-1:-1;;;;;72250:31:0;;72230:51;:87;;;;72285:32;72302:5;72309:7;72285:16;:32::i;74970:578::-;75129:4;-1:-1:-1;;;;;75102:31:0;:23;75117:7;75102:14;:23::i;:::-;-1:-1:-1;;;;;75102:31:0;;75094:85;;;;-1:-1:-1;;;75094:85:0;;22587:2:1;75094:85:0;;;22569:21:1;22626:2;22606:18;;;22599:30;22665:34;22645:18;;;22638:62;-1:-1:-1;;;22716:18:1;;;22709:39;22765:19;;75094:85:0;22385:405:1;75094:85:0;-1:-1:-1;;;;;75198:16:0;;75190:65;;;;-1:-1:-1;;;75190:65:0;;16476:2:1;75190:65:0;;;16458:21:1;16515:2;16495:18;;;16488:30;16554:34;16534:18;;;16527:62;-1:-1:-1;;;16605:18:1;;;16598:34;16649:19;;75190:65:0;16274:400:1;75190:65:0;75268:39;75289:4;75295:2;75299:7;75268:20;:39::i;:::-;75372:29;75389:1;75393:7;75372:8;:29::i;:::-;-1:-1:-1;;;;;75414:15:0;;;;;;:9;:15;;;;;:20;;75433:1;;75414:15;:20;;75433:1;;75414:20;:::i;:::-;;;;-1:-1:-1;;;;;;;75445:13:0;;;;;;:9;:13;;;;;:18;;75462:1;;75445:13;:18;;75462:1;;75445:18;:::i;:::-;;;;-1:-1:-1;;75474:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;75474:21:0;-1:-1:-1;;;;;75474:21:0;;;;;;;;;75513:27;;75474:16;;75513:27;;;;;;;74970:578;;;:::o;24639:114::-;24699:7;24726:19;24734:3;17668:18;;17585:109;25107:137;25178:7;25213:22;25217:3;25229:5;25213:3;:22::i;95513:434::-;95579:7;;95646:11;;;;;:39;;;95672:13;;95661:7;:24;;95646:39;95643:263;;;95720:26;95738:7;95720:17;:26::i;:::-;:31;;95749:2;95720:31;:::i;:::-;95711:40;;95643:263;;;95792:13;;95782:7;:23;:47;;;;;95820:9;;95809:7;:20;;95782:47;95778:128;;;95864:26;95882:7;95864:17;:26::i;:::-;:30;;95893:1;95864:30;:::i;72668:110::-;72744:26;72754:2;72758:7;72744:26;;;;;;;;;;;;:9;:26::i;23877:131::-;23944:4;23968:32;23973:3;23993:5;23968:4;:32::i;46036:191::-;46129:6;;;-1:-1:-1;;;;;46146:17:0;;;-1:-1:-1;;;;;;46146:17:0;;;;;;;46179:40;;46129:6;;;46146:17;46129:6;;46179:40;;46110:16;;46179:40;46099:128;46036:191;:::o;75982:315::-;76137:8;-1:-1:-1;;;;;76128:17:0;:5;-1:-1:-1;;;;;76128:17:0;;;76120:55;;;;-1:-1:-1;;;76120:55:0;;16881:2:1;76120:55:0;;;16863:21:1;16920:2;16900:18;;;16893:30;16959:27;16939:18;;;16932:55;17004:18;;76120:55:0;16679:349:1;76120:55:0;-1:-1:-1;;;;;76186:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;76186:46:0;;;;;;;;;;76248:41;;13200::1;;;76248::0;;13173:18:1;76248:41:0;;;;;;;75982:315;;;:::o;71056:::-;71213:28;71223:4;71229:2;71233:7;71213:9;:28::i;:::-;71260:48;71283:4;71289:2;71293:7;71302:5;71260:22;:48::i;:::-;71252:111;;;;-1:-1:-1;;;71252:111:0;;;;;;;:::i;92507:108::-;92567:13;92600:7;92593:14;;;;;:::i;26482:723::-;26538:13;26759:10;26755:53;;-1:-1:-1;;26786:10:0;;;;;;;;;;;;-1:-1:-1;;;26786:10:0;;;;;26482:723::o;26755:53::-;26833:5;26818:12;26874:78;26881:9;;26874:78;;26907:8;;;;:::i;:::-;;-1:-1:-1;26930:10:0;;-1:-1:-1;26938:2:0;26930:10;;:::i;:::-;;;26874:78;;;26962:19;26994:6;26984:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26984:17:0;;26962:39;;27012:154;27019:10;;27012:154;;27046:11;27056:1;27046:11;;:::i;:::-;;-1:-1:-1;27115:10:0;27123:2;27115:5;:10;:::i;:::-;27102:24;;:2;:24;:::i;:::-;27089:39;;27072:6;27079;27072:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;27072:56:0;;;;;;;;-1:-1:-1;27143:11:0;27152:2;27143:11;;:::i;:::-;;;27012:154;;24184:137;24254:4;24278:35;24286:3;24306:5;24278:7;:35::i;25794:263::-;25854:16;25883:22;25908:19;25916:3;25908:7;:19::i;81106:589::-;-1:-1:-1;;;;;81312:18:0;;81308:187;;81347:40;81379:7;82522:10;:17;;82495:24;;;;:15;:24;;;;;:44;;;82550:24;;;;;;;;;;;;82418:164;81347:40;81308:187;;;81417:2;-1:-1:-1;;;;;81409:10:0;:4;-1:-1:-1;;;;;81409:10:0;;81405:90;;81436:47;81469:4;81475:7;81436:32;:47::i;:::-;-1:-1:-1;;;;;81509:16:0;;81505:183;;81542:45;81579:7;81542:36;:45::i;81505:183::-;81615:4;-1:-1:-1;;;;;81609:10:0;:2;-1:-1:-1;;;;;81609:10:0;;81605:83;;81636:40;81664:2;81668:7;81636:27;:40::i;18048:120::-;18115:7;18142:3;:11;;18154:5;18142:18;;;;;;;;:::i;:::-;;;;;;;;;18135:25;;18048:120;;;;:::o;73005:321::-;73135:18;73141:2;73145:7;73135:5;:18::i;:::-;73186:54;73217:1;73221:2;73225:7;73234:5;73186:22;:54::i;:::-;73164:154;;;;-1:-1:-1;;;73164:154:0;;;;;;;:::i;15274:414::-;15337:4;17467:19;;;:12;;;:19;;;;;;15354:327;;-1:-1:-1;15397:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;15580:18;;15558:19;;;:12;;;:19;;;;;;:40;;;;15613:11;;15354:327;-1:-1:-1;15664:5:0;15657:12;;76862:799;77017:4;-1:-1:-1;;;;;77038:13:0;;47430:20;47478:8;77034:620;;77074:72;;-1:-1:-1;;;77074:72:0;;-1:-1:-1;;;;;77074:36:0;;;;;:72;;29053:10;;77125:4;;77131:7;;77140:5;;77074:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77074:72:0;;;;;;;;-1:-1:-1;;77074:72:0;;;;;;;;;;;;:::i;:::-;;;77070:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77316:13:0;;77312:272;;77359:60;;-1:-1:-1;;;77359:60:0;;;;;;;:::i;77312:272::-;77534:6;77528:13;77519:6;77515:2;77511:15;77504:38;77070:529;-1:-1:-1;;;;;;77197:51:0;-1:-1:-1;;;77197:51:0;;-1:-1:-1;77190:58:0;;77034:620;-1:-1:-1;77638:4:0;76862:799;;;;;;:::o;15864:1420::-;15930:4;16069:19;;;:12;;;:19;;;;;;16105:15;;16101:1176;;16480:21;16504:14;16517:1;16504:10;:14;:::i;:::-;16553:18;;16480:38;;-1:-1:-1;16533:17:0;;16553:22;;16574:1;;16553:22;:::i;:::-;16533:42;;16609:13;16596:9;:26;16592:405;;16643:17;16663:3;:11;;16675:9;16663:22;;;;;;;;:::i;:::-;;;;;;;;;16643:42;;16817:9;16788:3;:11;;16800:13;16788:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;16902:23;;;:12;;;:23;;;;;:36;;;16592:405;17078:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;17173:3;:12;;:19;17186:5;17173:19;;;;;;;;;;;17166:26;;;17216:4;17209:11;;;;;;;16101:1176;17260:5;17253:12;;;;;18718:111;18774:16;18810:3;:11;;18803:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18718:111;;;:::o;83209:988::-;83475:22;83525:1;83500:22;83517:4;83500:16;:22::i;:::-;:26;;;;:::i;:::-;83537:18;83558:26;;;:17;:26;;;;;;83475:51;;-1:-1:-1;83691:28:0;;;83687:328;;-1:-1:-1;;;;;83758:18:0;;83736:19;83758:18;;;:12;:18;;;;;;;;:34;;;;;;;;;83809:30;;;;;;:44;;;83926:30;;:17;:30;;;;;:43;;;83687:328;-1:-1:-1;84111:26:0;;;;:17;:26;;;;;;;;84104:33;;;-1:-1:-1;;;;;84155:18:0;;;;;:12;:18;;;;;:34;;;;;;;84148:41;83209:988::o;84492:1079::-;84770:10;:17;84745:22;;84770:21;;84790:1;;84770:21;:::i;:::-;84802:18;84823:24;;;:15;:24;;;;;;85196:10;:26;;84745:46;;-1:-1:-1;84823:24:0;;84745:46;;85196:26;;;;;;:::i;:::-;;;;;;;;;85174:48;;85260:11;85235:10;85246;85235:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;85340:28;;;:15;:28;;;;;;;:41;;;85512:24;;;;;85505:31;85547:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;84563:1008;;;84492:1079;:::o;81996:221::-;82081:14;82098:20;82115:2;82098:16;:20::i;:::-;-1:-1:-1;;;;;82129:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;82174:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;81996:221:0:o;73662:382::-;-1:-1:-1;;;;;73742:16:0;;73734:61;;;;-1:-1:-1;;;73734:61:0;;20359:2:1;73734:61:0;;;20341:21:1;;;20378:18;;;20371:30;20437:34;20417:18;;;20410:62;20489:18;;73734:61:0;20157:356:1;73734:61:0;71749:4;71773:16;;;:7;:16;;;;;;-1:-1:-1;;;;;71773:16:0;:30;73806:58;;;;-1:-1:-1;;;73806:58:0;;15351:2:1;73806:58:0;;;15333:21:1;15390:2;15370:18;;;15363:30;15429;15409:18;;;15402:58;15477:18;;73806:58:0;15149:352:1;73806:58:0;73877:45;73906:1;73910:2;73914:7;73877:20;:45::i;:::-;-1:-1:-1;;;;;73935:13:0;;;;;;:9;:13;;;;;:18;;73952:1;;73935:13;:18;;73952:1;;73935:18;:::i;:::-;;;;-1:-1:-1;;73964:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;73964:21:0;-1:-1:-1;;;;;73964:21:0;;;;;;;;74003:33;;73964:16;;;74003:33;;73964:16;;74003:33;73662:382;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:406:1;78:5;112:18;104:6;101:30;98:56;;;134:18;;:::i;:::-;172:57;217:2;196:15;;-1:-1:-1;;192:29:1;223:4;188:40;172:57;:::i;:::-;163:66;;252:6;245:5;238:21;292:3;283:6;278:3;274:16;271:25;268:45;;;309:1;306;299:12;268:45;358:6;353:3;346:4;339:5;335:16;322:43;412:1;405:4;396:6;389:5;385:18;381:29;374:40;14:406;;;;;:::o;425:247::-;484:6;537:2;525:9;516:7;512:23;508:32;505:52;;;553:1;550;543:12;505:52;592:9;579:23;611:31;636:5;611:31;:::i;937:388::-;1005:6;1013;1066:2;1054:9;1045:7;1041:23;1037:32;1034:52;;;1082:1;1079;1072:12;1034:52;1121:9;1108:23;1140:31;1165:5;1140:31;:::i;:::-;1190:5;-1:-1:-1;1247:2:1;1232:18;;1219:32;1260:33;1219:32;1260:33;:::i;:::-;1312:7;1302:17;;;937:388;;;;;:::o;1330:456::-;1407:6;1415;1423;1476:2;1464:9;1455:7;1451:23;1447:32;1444:52;;;1492:1;1489;1482:12;1444:52;1531:9;1518:23;1550:31;1575:5;1550:31;:::i;:::-;1600:5;-1:-1:-1;1657:2:1;1642:18;;1629:32;1670:33;1629:32;1670:33;:::i;:::-;1330:456;;1722:7;;-1:-1:-1;;;1776:2:1;1761:18;;;;1748:32;;1330:456::o;1791:936::-;1888:6;1896;1904;1912;1920;1973:3;1961:9;1952:7;1948:23;1944:33;1941:53;;;1990:1;1987;1980:12;1941:53;2029:9;2016:23;2048:31;2073:5;2048:31;:::i;:::-;2098:5;-1:-1:-1;2155:2:1;2140:18;;2127:32;2168:33;2127:32;2168:33;:::i;:::-;2220:7;-1:-1:-1;2274:2:1;2259:18;;2246:32;;-1:-1:-1;2329:2:1;2314:18;;2301:32;2352:18;2382:14;;;2379:34;;;2409:1;2406;2399:12;2379:34;2447:6;2436:9;2432:22;2422:32;;2492:7;2485:4;2481:2;2477:13;2473:27;2463:55;;2514:1;2511;2504:12;2463:55;2554:2;2541:16;2580:2;2572:6;2569:14;2566:34;;;2596:1;2593;2586:12;2566:34;2641:7;2636:2;2627:6;2623:2;2619:15;2615:24;2612:37;2609:57;;;2662:1;2659;2652:12;2609:57;1791:936;;;;-1:-1:-1;1791:936:1;;-1:-1:-1;2693:2:1;2685:11;;2715:6;1791:936;-1:-1:-1;;;1791:936:1:o;2732:794::-;2827:6;2835;2843;2851;2904:3;2892:9;2883:7;2879:23;2875:33;2872:53;;;2921:1;2918;2911:12;2872:53;2960:9;2947:23;2979:31;3004:5;2979:31;:::i;:::-;3029:5;-1:-1:-1;3086:2:1;3071:18;;3058:32;3099:33;3058:32;3099:33;:::i;:::-;3151:7;-1:-1:-1;3205:2:1;3190:18;;3177:32;;-1:-1:-1;3260:2:1;3245:18;;3232:32;3287:18;3276:30;;3273:50;;;3319:1;3316;3309:12;3273:50;3342:22;;3395:4;3387:13;;3383:27;-1:-1:-1;3373:55:1;;3424:1;3421;3414:12;3373:55;3447:73;3512:7;3507:2;3494:16;3489:2;3485;3481:11;3447:73;:::i;:::-;3437:83;;;2732:794;;;;;;;:::o;3531:416::-;3596:6;3604;3657:2;3645:9;3636:7;3632:23;3628:32;3625:52;;;3673:1;3670;3663:12;3625:52;3712:9;3699:23;3731:31;3756:5;3731:31;:::i;:::-;3781:5;-1:-1:-1;3838:2:1;3823:18;;3810:32;3880:15;;3873:23;3861:36;;3851:64;;3911:1;3908;3901:12;3952:415;4019:6;4027;4080:2;4068:9;4059:7;4055:23;4051:32;4048:52;;;4096:1;4093;4086:12;4048:52;4135:9;4122:23;4154:31;4179:5;4154:31;:::i;:::-;4204:5;-1:-1:-1;4261:2:1;4246:18;;4233:32;4309:6;4296:20;;4284:33;;4274:61;;4331:1;4328;4321:12;4372:315;4440:6;4448;4501:2;4489:9;4480:7;4476:23;4472:32;4469:52;;;4517:1;4514;4507:12;4469:52;4556:9;4543:23;4575:31;4600:5;4575:31;:::i;:::-;4625:5;4677:2;4662:18;;;;4649:32;;-1:-1:-1;;;4372:315:1:o;4692:977::-;4776:6;4807:2;4850;4838:9;4829:7;4825:23;4821:32;4818:52;;;4866:1;4863;4856:12;4818:52;4906:9;4893:23;4939:18;4931:6;4928:30;4925:50;;;4971:1;4968;4961:12;4925:50;4994:22;;5047:4;5039:13;;5035:27;-1:-1:-1;5025:55:1;;5076:1;5073;5066:12;5025:55;5112:2;5099:16;5135:60;5151:43;5191:2;5151:43;:::i;:::-;5135:60;:::i;:::-;5217:3;5241:2;5236:3;5229:15;5269:2;5264:3;5260:12;5253:19;;5300:2;5296;5292:11;5348:7;5343:2;5337;5334:1;5330:10;5326:2;5322:19;5318:28;5315:41;5312:61;;;5369:1;5366;5359:12;5312:61;5391:1;5382:10;;5401:238;5415:2;5412:1;5409:9;5401:238;;;5486:3;5473:17;5503:31;5528:5;5503:31;:::i;:::-;5547:18;;5433:1;5426:9;;;;;5585:12;;;;5617;;5401:238;;;-1:-1:-1;5658:5:1;4692:977;-1:-1:-1;;;;;;;4692:977:1:o;5674:615::-;5760:6;5768;5821:2;5809:9;5800:7;5796:23;5792:32;5789:52;;;5837:1;5834;5827:12;5789:52;5877:9;5864:23;5906:18;5947:2;5939:6;5936:14;5933:34;;;5963:1;5960;5953:12;5933:34;6001:6;5990:9;5986:22;5976:32;;6046:7;6039:4;6035:2;6031:13;6027:27;6017:55;;6068:1;6065;6058:12;6017:55;6108:2;6095:16;6134:2;6126:6;6123:14;6120:34;;;6150:1;6147;6140:12;6120:34;6203:7;6198:2;6188:6;6185:1;6181:14;6177:2;6173:23;6169:32;6166:45;6163:65;;;6224:1;6221;6214:12;6163:65;6255:2;6247:11;;;;;6277:6;;-1:-1:-1;5674:615:1;;-1:-1:-1;;;;5674:615:1:o;6294:892::-;6389:6;6420:2;6463;6451:9;6442:7;6438:23;6434:32;6431:52;;;6479:1;6476;6469:12;6431:52;6512:9;6506:16;6545:18;6537:6;6534:30;6531:50;;;6577:1;6574;6567:12;6531:50;6600:22;;6653:4;6645:13;;6641:27;-1:-1:-1;6631:55:1;;6682:1;6679;6672:12;6631:55;6711:2;6705:9;6734:60;6750:43;6790:2;6750:43;:::i;6734:60::-;6816:3;6840:2;6835:3;6828:15;6868:2;6863:3;6859:12;6852:19;;6899:2;6895;6891:11;6947:7;6942:2;6936;6933:1;6929:10;6925:2;6921:19;6917:28;6914:41;6911:61;;;6968:1;6965;6958:12;6911:61;6990:1;6981:10;;7000:156;7014:2;7011:1;7008:9;7000:156;;;7071:10;;7059:23;;7032:1;7025:9;;;;;7102:12;;;;7134;;7000:156;;7191:245;7249:6;7302:2;7290:9;7281:7;7277:23;7273:32;7270:52;;;7318:1;7315;7308:12;7270:52;7357:9;7344:23;7376:30;7400:5;7376:30;:::i;7441:249::-;7510:6;7563:2;7551:9;7542:7;7538:23;7534:32;7531:52;;;7579:1;7576;7569:12;7531:52;7611:9;7605:16;7630:30;7654:5;7630:30;:::i;7695:450::-;7764:6;7817:2;7805:9;7796:7;7792:23;7788:32;7785:52;;;7833:1;7830;7823:12;7785:52;7873:9;7860:23;7906:18;7898:6;7895:30;7892:50;;;7938:1;7935;7928:12;7892:50;7961:22;;8014:4;8006:13;;8002:27;-1:-1:-1;7992:55:1;;8043:1;8040;8033:12;7992:55;8066:73;8131:7;8126:2;8113:16;8108:2;8104;8100:11;8066:73;:::i;8150:180::-;8209:6;8262:2;8250:9;8241:7;8237:23;8233:32;8230:52;;;8278:1;8275;8268:12;8230:52;-1:-1:-1;8301:23:1;;8150:180;-1:-1:-1;8150:180:1:o;8335:184::-;8405:6;8458:2;8446:9;8437:7;8433:23;8429:32;8426:52;;;8474:1;8471;8464:12;8426:52;-1:-1:-1;8497:16:1;;8335:184;-1:-1:-1;8335:184:1:o;8524:269::-;8581:6;8634:2;8622:9;8613:7;8609:23;8605:32;8602:52;;;8650:1;8647;8640:12;8602:52;8689:9;8676:23;8739:4;8732:5;8728:16;8721:5;8718:27;8708:55;;8759:1;8756;8749:12;8798:257;8839:3;8877:5;8871:12;8904:6;8899:3;8892:19;8920:63;8976:6;8969:4;8964:3;8960:14;8953:4;8946:5;8942:16;8920:63;:::i;:::-;9037:2;9016:15;-1:-1:-1;;9012:29:1;9003:39;;;;9044:4;8999:50;;8798:257;-1:-1:-1;;8798:257:1:o;9060:1527::-;9284:3;9322:6;9316:13;9348:4;9361:51;9405:6;9400:3;9395:2;9387:6;9383:15;9361:51;:::i;:::-;9475:13;;9434:16;;;;9497:55;9475:13;9434:16;9519:15;;;9497:55;:::i;:::-;9641:13;;9574:20;;;9614:1;;9701;9723:18;;;;9776;;;;9803:93;;9881:4;9871:8;9867:19;9855:31;;9803:93;9944:2;9934:8;9931:16;9911:18;9908:40;9905:167;;;-1:-1:-1;;;9971:33:1;;10027:4;10024:1;10017:15;10057:4;9978:3;10045:17;9905:167;10088:18;10115:110;;;;10239:1;10234:328;;;;10081:481;;10115:110;-1:-1:-1;;10150:24:1;;10136:39;;10195:20;;;;-1:-1:-1;10115:110:1;;10234:328;25876:1;25869:14;;;25913:4;25900:18;;10329:1;10343:169;10357:8;10354:1;10351:15;10343:169;;;10439:14;;10424:13;;;10417:37;10482:16;;;;10374:10;;10343:169;;;10347:3;;10543:8;10536:5;10532:20;10525:27;;10081:481;-1:-1:-1;10578:3:1;;9060:1527;-1:-1:-1;;;;;;;;;;;9060:1527:1:o;10800:488::-;-1:-1:-1;;;;;11069:15:1;;;11051:34;;11121:15;;11116:2;11101:18;;11094:43;11168:2;11153:18;;11146:34;;;11216:3;11211:2;11196:18;;11189:31;;;10994:4;;11237:45;;11262:19;;11254:6;11237:45;:::i;:::-;11229:53;10800:488;-1:-1:-1;;;;;;10800:488:1:o;12423:632::-;12594:2;12646:21;;;12716:13;;12619:18;;;12738:22;;;12565:4;;12594:2;12817:15;;;;12791:2;12776:18;;;12565:4;12860:169;12874:6;12871:1;12868:13;12860:169;;;12935:13;;12923:26;;13004:15;;;;12969:12;;;;12896:1;12889:9;12860:169;;;-1:-1:-1;13046:3:1;;12423:632;-1:-1:-1;;;;;;12423:632:1:o;13687:219::-;13836:2;13825:9;13818:21;13799:4;13856:44;13896:2;13885:9;13881:18;13873:6;13856:44;:::i;14323:414::-;14525:2;14507:21;;;14564:2;14544:18;;;14537:30;14603:34;14598:2;14583:18;;14576:62;-1:-1:-1;;;14669:2:1;14654:18;;14647:48;14727:3;14712:19;;14323:414::o;20931:332::-;21133:2;21115:21;;;21172:1;21152:18;;;21145:29;-1:-1:-1;;;21205:2:1;21190:18;;21183:39;21254:2;21239:18;;20931:332::o;21618:356::-;21820:2;21802:21;;;21839:18;;;21832:30;21898:34;21893:2;21878:18;;21871:62;21965:2;21950:18;;21618:356::o;23963:413::-;24165:2;24147:21;;;24204:2;24184:18;;;24177:30;24243:34;24238:2;24223:18;;24216:62;-1:-1:-1;;;24309:2:1;24294:18;;24287:47;24366:3;24351:19;;23963:413::o;25335:275::-;25406:2;25400:9;25471:2;25452:13;;-1:-1:-1;;25448:27:1;25436:40;;25506:18;25491:34;;25527:22;;;25488:62;25485:88;;;25553:18;;:::i;:::-;25589:2;25582:22;25335:275;;-1:-1:-1;25335:275:1:o;25615:183::-;25675:4;25708:18;25700:6;25697:30;25694:56;;;25730:18;;:::i;:::-;-1:-1:-1;25775:1:1;25771:14;25787:4;25767:25;;25615:183::o;25929:128::-;25969:3;26000:1;25996:6;25993:1;25990:13;25987:39;;;26006:18;;:::i;:::-;-1:-1:-1;26042:9:1;;25929:128::o;26062:120::-;26102:1;26128;26118:35;;26133:18;;:::i;:::-;-1:-1:-1;26167:9:1;;26062:120::o;26187:168::-;26227:7;26293:1;26289;26285:6;26281:14;26278:1;26275:21;26270:1;26263:9;26256:17;26252:45;26249:71;;;26300:18;;:::i;:::-;-1:-1:-1;26340:9:1;;26187:168::o;26360:125::-;26400:4;26428:1;26425;26422:8;26419:34;;;26433:18;;:::i;:::-;-1:-1:-1;26470:9:1;;26360:125::o;26490:258::-;26562:1;26572:113;26586:6;26583:1;26580:13;26572:113;;;26662:11;;;26656:18;26643:11;;;26636:39;26608:2;26601:10;26572:113;;;26703:6;26700:1;26697:13;26694:48;;;-1:-1:-1;;26738:1:1;26720:16;;26713:27;26490:258::o;26753:380::-;26832:1;26828:12;;;;26875;;;26896:61;;26950:4;26942:6;26938:17;26928:27;;26896:61;27003:2;26995:6;26992:14;26972:18;26969:38;26966:161;;;27049:10;27044:3;27040:20;27037:1;27030:31;27084:4;27081:1;27074:15;27112:4;27109:1;27102:15;27138:135;27177:3;-1:-1:-1;;27198:17:1;;27195:43;;;27218:18;;:::i;:::-;-1:-1:-1;27265:1:1;27254:13;;27138:135::o;27278:175::-;27315:3;27359:4;27352:5;27348:16;27388:4;27379:7;27376:17;27373:43;;;27396:18;;:::i;:::-;27445:1;27432:15;;27278:175;-1:-1:-1;;27278:175:1:o;27458:112::-;27490:1;27516;27506:35;;27521:18;;:::i;:::-;-1:-1:-1;27555:9:1;;27458:112::o;27575:127::-;27636:10;27631:3;27627:20;27624:1;27617:31;27667:4;27664:1;27657:15;27691:4;27688:1;27681:15;27707:127;27768:10;27763:3;27759:20;27756:1;27749:31;27799:4;27796:1;27789:15;27823:4;27820:1;27813:15;27839:127;27900:10;27895:3;27891:20;27888:1;27881:31;27931:4;27928:1;27921:15;27955:4;27952:1;27945:15;27971:127;28032:10;28027:3;28023:20;28020:1;28013:31;28063:4;28060:1;28053:15;28087:4;28084:1;28077:15;28103:127;28164:10;28159:3;28155:20;28152:1;28145:31;28195:4;28192:1;28185:15;28219:4;28216:1;28209:15;28235:131;-1:-1:-1;;;;;28310:31:1;;28300:42;;28290:70;;28356:1;28353;28346:12;28371:131;-1:-1:-1;;;;;;28445:32:1;;28435:43;;28425:71;;28492:1;28489;28482:12

Swarm Source

ipfs://a10847e6cf20c66bce0dfc9f136d780180511ecda3b9a86ce938006f46eec852
Loading...
Loading
Loading...
Loading
[ 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.