ETH Price: $3,326.03 (+1.87%)
Gas: 6 Gwei

Ruby Mazur Lips (LIPS)
 

Overview

TokenID

1169

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

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

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

Contract Source Code Verified (Exact Match)

Contract Name:
RubyMazurLips

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-01-05
*/

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

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

/*
 * @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) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}


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

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


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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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


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

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

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


// File: @openzeppelin/contracts/introspection/ERC165.sol

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
abstract contract ERC165 is IERC165 {
    /*
     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
     */
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor () {
        // Derived contracts need only register support for their own interfaces,
        // we register support for ERC165 itself here
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     *
     * Time complexity O(1), guaranteed to always use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal virtual {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}


// File: @openzeppelin/contracts/math/SafeMath.sol

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
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) {
        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) {
        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) {
        // 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) {
        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) {
        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) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @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) {
        require(b <= a, "SafeMath: subtraction overflow");
        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) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @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. 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) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        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) {
        require(b > 0, "SafeMath: modulo by zero");
        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) {
        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.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * 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) {
        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) {
        require(b > 0, errorMessage);
        return a % b;
    }
}


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

/**
 * @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;
        // solhint-disable-next-line no-inline-assembly
        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");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}


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

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

            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            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] = toDeleteIndex + 1; // All indexes are 1-based

            // 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) {
        require(set._values.length > index, "EnumerableSet: index out of bounds");
        return set._values[index];
    }

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

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

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


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

/**
 * @dev Library for managing an enumerable variant of Solidity's
 * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
 * type.
 *
 * Maps have the following properties:
 *
 * - Entries are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Entries are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableMap for EnumerableMap.UintToAddressMap;
 *
 *     // Declare a set state variable
 *     EnumerableMap.UintToAddressMap private myMap;
 * }
 * ```
 *
 * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are
 * supported.
 */
library EnumerableMap {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Map type with
    // bytes32 keys and values.
    // The Map implementation uses private functions, and user-facing
    // implementations (such as Uint256ToAddressMap) are just wrappers around
    // the underlying Map.
    // This means that we can only create new EnumerableMaps for types that fit
    // in bytes32.

    struct MapEntry {
        bytes32 _key;
        bytes32 _value;
    }

    struct Map {
        // Storage of map keys and values
        MapEntry[] _entries;

        // Position of the entry defined by a key in the `entries` array, plus 1
        // because index 0 means a key is not in the map.
        mapping (bytes32 => uint256) _indexes;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {
        // We read and store the key's index to prevent multiple reads from the same storage slot
        uint256 keyIndex = map._indexes[key];

        if (keyIndex == 0) { // Equivalent to !contains(map, key)
            map._entries.push(MapEntry({ _key: key, _value: value }));
            // The entry is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            map._indexes[key] = map._entries.length;
            return true;
        } else {
            map._entries[keyIndex - 1]._value = value;
            return false;
        }
    }

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

        if (keyIndex != 0) { // Equivalent to contains(map, key)
            // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one
            // in the array, and then remove the last entry (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = keyIndex - 1;
            uint256 lastIndex = map._entries.length - 1;

            // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            MapEntry storage lastEntry = map._entries[lastIndex];

            // Move the last entry to the index where the entry to delete is
            map._entries[toDeleteIndex] = lastEntry;
            // Update the index for the moved entry
            map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved entry was stored
            map._entries.pop();

            // Delete the index for the deleted slot
            delete map._indexes[key];

            return true;
        } else {
            return false;
        }
    }

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

    /**
     * @dev Returns the number of key-value pairs in the map. O(1).
     */
    function _length(Map storage map) private view returns (uint256) {
        return map._entries.length;
    }

   /**
    * @dev Returns the key-value pair stored at position `index` in the map. O(1).
    *
    * Note that there are no guarantees on the ordering of entries inside the
    * array, and it may change when more entries are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {
        require(map._entries.length > index, "EnumerableMap: index out of bounds");

        MapEntry storage entry = map._entries[index];
        return (entry._key, entry._value);
    }

    /**
     * @dev Tries to returns the value associated with `key`.  O(1).
     * Does not revert if `key` is not in the map.
     */
    function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {
        uint256 keyIndex = map._indexes[key];
        if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)
        return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based
    }

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function _get(Map storage map, bytes32 key) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    /**
     * @dev Same as {_get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {_tryGet}.
     */
    function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    // UintToAddressMap

    struct UintToAddressMap {
        Map _inner;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {
        return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
    }

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

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

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

   /**
    * @dev Returns the element 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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
        (bytes32 key, bytes32 value) = _at(map._inner, index);
        return (uint256(key), address(uint160(uint256(value))));
    }

    /**
     * @dev Tries to returns the value associated with `key`.  O(1).
     * Does not revert if `key` is not in the map.
     *
     * _Available since v3.4._
     */
    function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
        (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));
        return (success, address(uint160(uint256(value))));
    }

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
        return address(uint160(uint256(_get(map._inner, bytes32(key)))));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {
        return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));
    }
}


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

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

}


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

/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {
    using SafeMath for uint256;
    using Address for address;
    using EnumerableSet for EnumerableSet.UintSet;
    using EnumerableMap for EnumerableMap.UintToAddressMap;
    using Strings for uint256;

    // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

    // Mapping from holder address to their (enumerable) set of owned tokens
    mapping (address => EnumerableSet.UintSet) private _holderTokens;

    // Enumerable mapping from token ids to their owners
    EnumerableMap.UintToAddressMap private _tokenOwners;

    // 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;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Optional mapping for token URIs
    mapping (uint256 => string) private _tokenURIs;

    // Base URI
    string private _baseURI;

    /*
     *     bytes4(keccak256('balanceOf(address)')) == 0x70a08231
     *     bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
     *     bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
     *     bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
     *     bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
     *
     *     => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
     *        0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
     */
    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;

    /*
     *     bytes4(keccak256('name()')) == 0x06fdde03
     *     bytes4(keccak256('symbol()')) == 0x95d89b41
     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
     *
     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
     */
    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;

    /*
     *     bytes4(keccak256('totalSupply()')) == 0x18160ddd
     *     bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
     *     bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
     *
     *     => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
     */
    bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;

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

        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721);
        _registerInterface(_INTERFACE_ID_ERC721_METADATA);
        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
    }

    /**
     * @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 _holderTokens[owner].length();
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token");
    }

    /**
     * @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 _tokenURI = _tokenURIs[tokenId];
        string memory base = baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }
        // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
        return string(abi.encodePacked(base, tokenId.toString()));
    }

    /**
    * @dev Returns the base URI set via {_setBaseURI}. This will be
    * automatically added as a prefix in {tokenURI} to each token's URI, or
    * to the token ID if no specific URI is set for that token ID.
    */
    function baseURI() public view virtual returns (string memory) {
        return _baseURI;
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        return _holderTokens[owner].at(index);
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds
        return _tokenOwners.length();
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        (uint256 tokenId, ) = _tokenOwners.at(index);
        return tokenId;
    }

    /**
     * @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 || ERC721.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 {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(address from, address to, uint256 tokenId) public virtual override {
        //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 _tokenOwners.contains(tokenId);
    }

    /**
     * @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 || ERC721.isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     d*
     * - `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);

        _holderTokens[to].add(tokenId);

        _tokenOwners.set(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); // internal owner

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

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

        // Clear metadata (if any)
        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }

        _holderTokens[owner].remove(tokenId);

        _tokenOwners.remove(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"); // internal owner
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

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

        _holderTokens[from].remove(tokenId);
        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
        require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev Internal function to set the base URI for all token IDs. It is
     * automatically added as a prefix to the value returned in {tokenURI},
     * or to the token ID if {tokenURI} is empty.
     */
    function _setBaseURI(string memory baseURI_) internal virtual {
        _baseURI = baseURI_;
    }

    /**
     * @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()) {
            return true;
        }
        bytes memory returndata = to.functionCall(abi.encodeWithSelector(
            IERC721Receiver(to).onERC721Received.selector,
            _msgSender(),
            from,
            tokenId,
            _data
        ), "ERC721: transfer to non ERC721Receiver implementer");
        bytes4 retval = abi.decode(returndata, (bytes4));
        return (retval == _ERC721_RECEIVED);
    }

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

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


// File: @openzeppelin/contracts/access/Ownable.sol

/**
 * @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 () {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), 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 {
        emit OwnershipTransferred(_owner, address(0));
        _owner = 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");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

// File: contracts/RubyMazurLips.sol

/**
 * @title RubyMazurLips contract
 * @dev Extends ERC721 Non-Fungible Token Standard basic implementation
 */
contract RubyMazurLips is ERC721, Ownable {
    using SafeMath for uint256;
    using Strings for uint256;

    uint256 public MAX_TOKEN_SUPPLY;
    uint256 public maxToMint;
    uint256 maxWhitelistMints;
    uint256 maxTeamReserveMints;
    uint256 maxGiveawayMints;
    uint256 numTeamReserveMinted;
    uint256 numGiveawayMinted;

    bool public saleIsActive;
    bool public whitelistIsActive;

    bytes32[] _whitelistRootHash;
    bytes32[] _giveawayRootHash;
    mapping(address => uint256) public numberOfWhitelistMints;
    mapping(address => uint256) public numberOfGiveawayMints;

    address payoutWallet1;
    address payoutWallet2;
   
    uint256 public whitelistMintPrice;
    uint256 public regularMintPrice;
    uint256 bytPayoutPercentage;

    string private prerevealURI;
    bool public revealIsActive;
    uint256 maxTokenIdRevealed;

    constructor() ERC721("Ruby Mazur Lips", "LIPS") {
        MAX_TOKEN_SUPPLY = 5050;
        prerevealURI = "https://gateway.pinata.cloud/ipfs/QmZG77XuF7Yu8y9cUKrpYxR2yEp4qviu2ND78SnMT7ztJj";
        whitelistMintPrice = 150000000000000000; // 0.15 ETH
        regularMintPrice = 200000000000000000; //0.2 ETH
        maxToMint = 5;
        maxWhitelistMints = 3;
        maxTeamReserveMints = 131;
        maxGiveawayMints = 115;
        saleIsActive = false;
        whitelistIsActive = false;
        revealIsActive = false;
        payoutWallet1 = 0xe5C24ad2bcBBf4b547247417A8a8877dD885D029;// cosmic payout wallet
        payoutWallet2 = 0x80E20FF6568A8C23D971165f99aD61FA19F9E084;// byt payout wallet
        bytPayoutPercentage = 15;
    }

    fallback() external payable {}

    function addToWhitelistRootHash(bytes32 _hash) external onlyOwner{
        _whitelistRootHash.push(_hash);
    }

    function addToGiveawayRootHash(bytes32 _hash) external onlyOwner{
        _giveawayRootHash.push(_hash);
    }

    function setWhitelistMintPrice(uint256 _price) external onlyOwner {
        whitelistMintPrice = _price;
    }
    
    function setRegularMintPrice(uint256 _price) external onlyOwner {
        regularMintPrice = _price;
    }

    function setMaxToMint(uint256 _maxValue) external onlyOwner {
        maxToMint = _maxValue;
    }

    function setMaxTeamReserveMints(uint256 _maxValue) external onlyOwner {
        maxTeamReserveMints = _maxValue;
    }

    function setMaxGiveawayMints(uint256 _maxValue) external onlyOwner {
        maxGiveawayMints = _maxValue;
    }

    function setBaseURI(string memory baseURI) external onlyOwner {
        _setBaseURI(baseURI);
    }

    function setPrerevealURI(string memory prerevealURI_) external onlyOwner {
        prerevealURI = prerevealURI_;
    }

    function setRevealState() external onlyOwner {
        revealIsActive = !revealIsActive;
    }

    function setMaxTokenIdRevealed(uint256 tokenId) external onlyOwner {
        maxTokenIdRevealed = tokenId;
    }

    function setSaleState() external onlyOwner {
        saleIsActive = !saleIsActive;
    }

    function setWhitelistState() external onlyOwner {
        whitelistIsActive = !whitelistIsActive;
    }

    function setPayoutWallet1(address wallet) external onlyOwner {
        payoutWallet1 = wallet;
    }

    function setPayoutWallet2(address wallet) external onlyOwner {
        payoutWallet2 = wallet;
    }

    function whitelistMint(uint256 numberOfTokens, uint256 spotInWhitelist, bytes32[] memory proof) external payable {
        require(whitelistIsActive, "The whitelist is not active yet");
        require(saleIsActive == false, "The whitelist mint has closed");
        require(numberOfTokens <= maxToMint, "Invalid amount to mint per txn");
        require(totalSupply().add(numberOfTokens) <= MAX_TOKEN_SUPPLY, "Purchase would exceed max supply");
        require(whitelistValidated(_msgSender(), 1, spotInWhitelist, proof, _whitelistRootHash), "You're not on the whitelist");
        require((numberOfWhitelistMints[_msgSender()] + numberOfTokens) <= maxWhitelistMints, "This transaction exceeds the max whitelist mints");
        require(whitelistMintPrice.mul(numberOfTokens) <= msg.value, "Ether value set is not correct");

        numberOfWhitelistMints[_msgSender()] += numberOfTokens;

        uint256 tokenID = totalSupply();
        uint256 i;

        for (i = 0; i < numberOfTokens; i++) {
            _safeMint(_msgSender(), tokenID.add(i));
        }
    }

    function giveawayMint(uint256 amount, uint256 spotInWhitelist, bytes32[] memory proof) external {
        require(whitelistIsActive, "Giveaway must be active to mint");
        require(numGiveawayMinted.add(amount) <= maxGiveawayMints, "Mint would exeed max giveaway mints");
        require(totalSupply().add(amount) <= MAX_TOKEN_SUPPLY, "Mint would exceed max supply");
        require(whitelistValidated(_msgSender(), amount, spotInWhitelist, proof, _giveawayRootHash), "You're not on the giveaway list");
        require(numberOfGiveawayMints[_msgSender()] == 0, "This address already received a giveaway mint");

        uint256 tokenID = totalSupply();
        uint256 i;

        numberOfGiveawayMints[_msgSender()] = amount;
        numGiveawayMinted += amount;

        for (i = 0; i < amount; i++) {
            _safeMint(_msgSender(), tokenID.add(i));
        }
    }

    function mint(uint256 numberOfTokens) external payable {
        require(saleIsActive, "Sale must be active to mint");
        require(numberOfTokens <= maxToMint, "Invalid amount to mint per txn");
        require(totalSupply().add(numberOfTokens) <= MAX_TOKEN_SUPPLY, "Purchase would exceed max supply");
        require(regularMintPrice.mul(numberOfTokens) <= msg.value, "Ether value set is not correct");

        uint256 tokenID = totalSupply();
        uint256 i;

        for (i = 0; i < numberOfTokens; i++) {
            _safeMint(_msgSender(), tokenID.add(i));
        }
    }

    function teamReserveMint(uint256 numberOfTokens, address _to) external onlyOwner {
        require(totalSupply().add(numberOfTokens) <= MAX_TOKEN_SUPPLY, "Purchase would exceed max supply");
        require(numTeamReserveMinted.add(numberOfTokens) <= maxTeamReserveMints, "Purchase would exceed max reserved amount");

        numTeamReserveMinted += numberOfTokens;
        uint256 supply = totalSupply();
        uint256 i;

        for (i = 0; i < numberOfTokens; i++) {
            _safeMint(_to, supply.add(i));
        }
     }

    function whitelistValidated(address wallet, uint256 _amount, uint256 index, bytes32[] memory proof, bytes32[] memory _rootHash) internal pure returns (bool) {
        uint256 amount = _amount;

        // Compute the merkle root
        bytes32 node = keccak256(abi.encodePacked(index, wallet, amount));
        uint256 path = index;
        for (uint16 i = 0; i < proof.length; i++) {
            if ((path & 0x01) == 1) {
                node = keccak256(abi.encodePacked(proof[i], node));
            } else {
                node = keccak256(abi.encodePacked(node, proof[i]));
            }
            path /= 2;
        }

        // Check the merkle proof against the root hash array
        for(uint i = 0; i < _rootHash.length; i++)
        {
            if (node == _rootHash[i])
            {
                return true;
            }
        }

        return false;
    }

    function withdraw() external onlyOwner {
        require(payoutWallet1 != address(0), "wallet 1 not set");
        require(payoutWallet2 != address(0), "wallet 2 not set");
        uint256 balance = address(this).balance;
        uint256 walletBalance = balance.mul(100 - bytPayoutPercentage).div(100);
        payable(payoutWallet1).transfer(walletBalance);
        payable(payoutWallet2).transfer(balance.sub(walletBalance));
    }

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        if(revealIsActive && tokenId <= maxTokenIdRevealed) {
            return string(abi.encodePacked(baseURI(), tokenId.toString()));
        } else {
            return prerevealURI;
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"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"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"MAX_TOKEN_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"}],"name":"addToGiveawayRootHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"}],"name":"addToWhitelistRootHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"spotInWhitelist","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"giveawayMint","outputs":[],"stateMutability":"nonpayable","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":"maxToMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numberOfGiveawayMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numberOfWhitelistMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"regularMintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxValue","type":"uint256"}],"name":"setMaxGiveawayMints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxValue","type":"uint256"}],"name":"setMaxTeamReserveMints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxValue","type":"uint256"}],"name":"setMaxToMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"setMaxTokenIdRevealed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"setPayoutWallet1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"setPayoutWallet2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"prerevealURI_","type":"string"}],"name":"setPrerevealURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setRegularMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setRevealState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setWhitelistMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setWhitelistState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"teamReserveMint","outputs":[],"stateMutability":"nonpayable","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":[{"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":"whitelistIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"},{"internalType":"uint256","name":"spotInWhitelist","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"whitelistMintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b50604080518082018252600f81526e52756279204d617a7572204c69707360881b602080830191909152825180840190935260048352634c49505360e01b9083015290620000666301ffc9a760e01b620001d7565b81516200007b9060069060208501906200025b565b508051620000919060079060208401906200025b565b50620000a46380ac58cd60e01b620001d7565b620000b6635b5e139f60e01b620001d7565b620000c863780e9d6360e01b620001d7565b5050600a80546001600160a01b0319163390811790915560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506113ba600b556040805160808101909152605080825262003773602083013980516200014291601c916020909101906200025b565b50670214e8348c4f00006019556702c68af0bb140000601a556005600c556003600d556083600e556073600f9081556012805461ffff19169055601d805460ff19169055601780546001600160a01b031990811673e5c24ad2bcbbf4b547247417a8a8877dd885d02917909155601880549091167380e20ff6568a8c23d971165f99ad61fa19f9e084179055601b556200033e565b6001600160e01b03198082161415620002365760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015260640160405180910390fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b828054620002699062000301565b90600052602060002090601f0160209004810192826200028d5760008555620002d8565b82601f10620002a857805160ff1916838001178555620002d8565b82800160010185558215620002d8579182015b82811115620002d8578251825591602001919060010190620002bb565b50620002e6929150620002ea565b5090565b5b80821115620002e65760008155600101620002eb565b600181811c908216806200031657607f821691505b602082108114156200033857634e487b7160e01b600052602260045260246000fd5b50919050565b613425806200034e6000396000f3fe6080604052600436106102965760003560e01c80636352211e11610166578063a31cf533116100d3578063c87b56dd1161008f578063e985e9c51161006c578063e985e9c51461080c578063eb8d244414610855578063f2e1f5001461086f578063f2fde38b1461088957005b8063c87b56dd146107b6578063e489d510146107d6578063e6ae64e0146107ec57005b8063a31cf5331461070e578063a4c1291c14610723578063a611708e14610743578063b88d4fde14610763578063bcbec39614610783578063c4be5b59146107a357005b8063715018a611610122578063715018a6146106735780638da5cb5b1461068857806391366113146106a657806395d89b41146106c6578063a0712d68146106db578063a22cb465146106ee57005b80636352211e146105d35780636aa1b09e146105f35780636c0360eb146106095780637084b2b71461061e578063708aa3dc1461063e57806370a082311461065357005b80632d33c3ce1161020457806343864b7d116101c057806343864b7d146105065780634f6ccce714610526578063519679d11461054657806355f804b3146105735780635747e8e8146105935780635ea4352f146105b357005b80632d33c3ce1461045b5780632f745c591461047b57806335c6aaf81461049b578063371756bd146104b15780633ccfd60b146104d157806342842e0e146104e657005b8063177397c011610253578063177397c0146103a557806318160ddd146103d25780631df656b0146103e75780631ed40559146104075780631fe70d6f1461041c57806323b872dd1461043b57005b806301ffc9a71461029857806306fdde03146102e7578063078eef2814610309578063081812fc14610329578063095ea7b3146103615780630ba133c514610381575b005b3480156102a457600080fd5b506102d26102b3366004612c9b565b6001600160e01b03191660009081526020819052604090205460ff1690565b60405190151581526020015b60405180910390f35b3480156102f357600080fd5b506102fc6108a9565b6040516102de9190612d10565b34801561031557600080fd5b50610296610324366004612dc2565b61093b565b34801561033557600080fd5b50610349610344366004612e0b565b610985565b6040516001600160a01b0390911681526020016102de565b34801561036d57600080fd5b5061029661037c366004612e3b565b610a0d565b34801561038d57600080fd5b50610397600c5481565b6040519081526020016102de565b3480156103b157600080fd5b506103976103c0366004612e65565b60166020526000908152604090205481565b3480156103de57600080fd5b50610397610b23565b3480156103f357600080fd5b50610296610402366004612e80565b610b34565b34801561041357600080fd5b50610296610c5b565b34801561042857600080fd5b506012546102d290610100900460ff1681565b34801561044757600080fd5b50610296610456366004612eac565b610c99565b34801561046757600080fd5b50610296610476366004612e0b565b610cca565b34801561048757600080fd5b50610397610496366004612e3b565b610d29565b3480156104a757600080fd5b5061039760195481565b3480156104bd57600080fd5b506102966104cc366004612e65565b610d54565b3480156104dd57600080fd5b50610296610da0565b3480156104f257600080fd5b50610296610501366004612eac565b610f08565b34801561051257600080fd5b50610296610521366004612e0b565b610f23565b34801561053257600080fd5b50610397610541366004612e0b565b610f52565b34801561055257600080fd5b50610397610561366004612e65565b60156020526000908152604090205481565b34801561057f57600080fd5b5061029661058e366004612dc2565b610f68565b34801561059f57600080fd5b506102966105ae366004612e65565b610f9e565b3480156105bf57600080fd5b506102966105ce366004612e0b565b610fea565b3480156105df57600080fd5b506103496105ee366004612e0b565b611019565b3480156105ff57600080fd5b50610397601a5481565b34801561061557600080fd5b506102fc611041565b34801561062a57600080fd5b50610296610639366004612e0b565b611050565b34801561064a57600080fd5b5061029661107f565b34801561065f57600080fd5b5061039761066e366004612e65565b6110c6565b34801561067f57600080fd5b50610296611152565b34801561069457600080fd5b50600a546001600160a01b0316610349565b3480156106b257600080fd5b506102966106c1366004612e0b565b6111c6565b3480156106d257600080fd5b506102fc6111f5565b6102966106e9366004612e0b565b611204565b3480156106fa57600080fd5b50610296610709366004612ee8565b61136a565b34801561071a57600080fd5b5061029661142f565b34801561072f57600080fd5b5061029661073e366004612e0b565b61146d565b34801561074f57600080fd5b5061029661075e366004612e0b565b6114cc565b34801561076f57600080fd5b5061029661077e366004612f24565b6114fb565b34801561078f57600080fd5b5061029661079e366004612e0b565b61152d565b6102966107b1366004612fa0565b61155c565b3480156107c257600080fd5b506102fc6107d1366004612e0b565b61186f565b3480156107e257600080fd5b50610397600b5481565b3480156107f857600080fd5b50610296610807366004612fa0565b6119c6565b34801561081857600080fd5b506102d261082736600461305b565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561086157600080fd5b506012546102d29060ff1681565b34801561087b57600080fd5b50601d546102d29060ff1681565b34801561089557600080fd5b506102966108a4366004612e65565b611c60565b6060600680546108b890613085565b80601f01602080910402602001604051908101604052809291908181526020018280546108e490613085565b80156109315780601f1061090657610100808354040283529160200191610931565b820191906000526020600020905b81548152906001019060200180831161091457829003601f168201915b5050505050905090565b600a546001600160a01b0316331461096e5760405162461bcd60e51b8152600401610965906130c0565b60405180910390fd5b805161098190601c906020840190612bec565b5050565b600061099082611d4b565b6109f15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610965565b506000908152600460205260409020546001600160a01b031690565b6000610a1882611019565b9050806001600160a01b0316836001600160a01b03161415610a865760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610965565b336001600160a01b0382161480610aa25750610aa28133610827565b610b145760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610965565b610b1e8383611d58565b505050565b6000610b2f6002611dc6565b905090565b600a546001600160a01b03163314610b5e5760405162461bcd60e51b8152600401610965906130c0565b600b54610b7383610b6d610b23565b90611dd0565b1115610b915760405162461bcd60e51b8152600401610965906130f5565b600e54601054610ba19084611dd0565b1115610c015760405162461bcd60e51b815260206004820152602960248201527f507572636861736520776f756c6420657863656564206d617820726573657276604482015268195908185b5bdd5b9d60ba1b6064820152608401610965565b8160106000828254610c139190613140565b9091555060009050610c23610b23565b905060005b83811015610c5557610c4383610c3e8484611dd0565b611e2f565b80610c4d81613158565b915050610c28565b50505050565b600a546001600160a01b03163314610c855760405162461bcd60e51b8152600401610965906130c0565b6012805460ff19811660ff90911615179055565b610ca33382611e49565b610cbf5760405162461bcd60e51b815260040161096590613173565b610b1e838383611f33565b600a546001600160a01b03163314610cf45760405162461bcd60e51b8152600401610965906130c0565b601480546001810182556000919091527fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec0155565b6001600160a01b0382166000908152600160205260408120610d4b90836120b4565b90505b92915050565b600a546001600160a01b03163314610d7e5760405162461bcd60e51b8152600401610965906130c0565b601880546001600160a01b0319166001600160a01b0392909216919091179055565b600a546001600160a01b03163314610dca5760405162461bcd60e51b8152600401610965906130c0565b6017546001600160a01b0316610e155760405162461bcd60e51b815260206004820152601060248201526f1dd85b1b195d080c481b9bdd081cd95d60821b6044820152606401610965565b6018546001600160a01b0316610e605760405162461bcd60e51b815260206004820152601060248201526f1dd85b1b195d080c881b9bdd081cd95d60821b6044820152606401610965565b60004790506000610e8b6064610e85601b546064610e7e91906131c4565b85906120c0565b9061213f565b6017546040519192506001600160a01b03169082156108fc029083906000818181858888f19350505050158015610ec6573d6000803e3d6000fd5b506018546001600160a01b03166108fc610ee0848461219a565b6040518115909202916000818181858888f19350505050158015610b1e573d6000803e3d6000fd5b610b1e838383604051806020016040528060008152506114fb565b600a546001600160a01b03163314610f4d5760405162461bcd60e51b8152600401610965906130c0565b600f55565b600080610f606002846121f6565b509392505050565b600a546001600160a01b03163314610f925760405162461bcd60e51b8152600401610965906130c0565b610f9b81612212565b50565b600a546001600160a01b03163314610fc85760405162461bcd60e51b8152600401610965906130c0565b601780546001600160a01b0319166001600160a01b0392909216919091179055565b600a546001600160a01b031633146110145760405162461bcd60e51b8152600401610965906130c0565b600e55565b6000610d4e826040518060600160405280602981526020016133c76029913960029190612225565b6060600980546108b890613085565b600a546001600160a01b0316331461107a5760405162461bcd60e51b8152600401610965906130c0565b600c55565b600a546001600160a01b031633146110a95760405162461bcd60e51b8152600401610965906130c0565b6012805461ff001981166101009182900460ff1615909102179055565b60006001600160a01b0382166111315760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610965565b6001600160a01b0382166000908152600160205260409020610d4e90611dc6565b600a546001600160a01b0316331461117c5760405162461bcd60e51b8152600401610965906130c0565b600a546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600a80546001600160a01b0319169055565b600a546001600160a01b031633146111f05760405162461bcd60e51b8152600401610965906130c0565b601e55565b6060600780546108b890613085565b60125460ff166112565760405162461bcd60e51b815260206004820152601b60248201527f53616c65206d7573742062652061637469766520746f206d696e7400000000006044820152606401610965565b600c548111156112a85760405162461bcd60e51b815260206004820152601e60248201527f496e76616c696420616d6f756e7420746f206d696e74207065722074786e00006044820152606401610965565b600b546112b782610b6d610b23565b11156112d55760405162461bcd60e51b8152600401610965906130f5565b601a5434906112e490836120c0565b11156113325760405162461bcd60e51b815260206004820152601e60248201527f45746865722076616c756520736574206973206e6f7420636f727265637400006044820152606401610965565b600061133c610b23565b905060005b82811015610b1e57611358335b610c3e8484611dd0565b8061136281613158565b915050611341565b6001600160a01b0382163314156113c35760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610965565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600a546001600160a01b031633146114595760405162461bcd60e51b8152600401610965906130c0565b601d805460ff19811660ff90911615179055565b600a546001600160a01b031633146114975760405162461bcd60e51b8152600401610965906130c0565b601380546001810182556000919091527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900155565b600a546001600160a01b031633146114f65760405162461bcd60e51b8152600401610965906130c0565b601955565b6115053383611e49565b6115215760405162461bcd60e51b815260040161096590613173565b610c558484848461223c565b600a546001600160a01b031633146115575760405162461bcd60e51b8152600401610965906130c0565b601a55565b601254610100900460ff166115b35760405162461bcd60e51b815260206004820152601f60248201527f5468652077686974656c697374206973206e6f742061637469766520796574006044820152606401610965565b60125460ff16156116065760405162461bcd60e51b815260206004820152601d60248201527f5468652077686974656c697374206d696e742068617320636c6f7365640000006044820152606401610965565b600c548311156116585760405162461bcd60e51b815260206004820152601e60248201527f496e76616c696420616d6f756e7420746f206d696e74207065722074786e00006044820152606401610965565b600b5461166784610b6d610b23565b11156116855760405162461bcd60e51b8152600401610965906130f5565b6116e3336001848460138054806020026020016040519081016040528092919081815260200182805480156116d957602002820191906000526020600020905b8154815260200190600101908083116116c5575b505050505061226f565b61172f5760405162461bcd60e51b815260206004820152601b60248201527f596f75277265206e6f74206f6e207468652077686974656c69737400000000006044820152606401610965565b600d543360009081526015602052604090205461174d908590613140565b11156117b45760405162461bcd60e51b815260206004820152603060248201527f54686973207472616e73616374696f6e206578636565647320746865206d617860448201526f2077686974656c697374206d696e747360801b6064820152608401610965565b60195434906117c390856120c0565b11156118115760405162461bcd60e51b815260206004820152601e60248201527f45746865722076616c756520736574206973206e6f7420636f727265637400006044820152606401610965565b3360009081526015602052604081208054859290611830908490613140565b9091555060009050611840610b23565b905060005b84811015611868576118563361134e565b8061186081613158565b915050611845565b5050505050565b606061187a82611d4b565b6118de5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610965565b601d5460ff1680156118f25750601e548211155b1561192f576118ff611041565b611908836123f9565b6040516020016119199291906131db565b6040516020818303038152906040529050919050565b601c805461193c90613085565b80601f016020809104026020016040519081016040528092919081815260200182805461196890613085565b80156119b55780601f1061198a576101008083540402835291602001916119b5565b820191906000526020600020905b81548152906001019060200180831161199857829003601f168201915b50505050509050919050565b919050565b601254610100900460ff16611a1d5760405162461bcd60e51b815260206004820152601f60248201527f4769766561776179206d7573742062652061637469766520746f206d696e74006044820152606401610965565b600f54601154611a2d9085611dd0565b1115611a875760405162461bcd60e51b815260206004820152602360248201527f4d696e7420776f756c64206578656564206d6178206769766561776179206d696044820152626e747360e81b6064820152608401610965565b600b54611a9684610b6d610b23565b1115611ae45760405162461bcd60e51b815260206004820152601c60248201527f4d696e7420776f756c6420657863656564206d617820737570706c79000000006044820152606401610965565b611b3f3384848460148054806020026020016040519081016040528092919081815260200182805480156116d957602002820191906000526020600020908154815260200190600101908083116116c557505050505061226f565b611b8b5760405162461bcd60e51b815260206004820152601f60248201527f596f75277265206e6f74206f6e20746865206769766561776179206c697374006044820152606401610965565b3360009081526016602052604090205415611bfe5760405162461bcd60e51b815260206004820152602d60248201527f54686973206164647265737320616c726561647920726563656976656420612060448201526c19da5d99585dd85e481b5a5b9d609a1b6064820152608401610965565b6000611c08610b23565b3360009081526016602052604081208690556011805492935090918691908390611c33908490613140565b9091555060009150505b8481101561186857611c4e3361134e565b80611c5881613158565b915050611c3d565b600a546001600160a01b03163314611c8a5760405162461bcd60e51b8152600401610965906130c0565b6001600160a01b038116611cef5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610965565b600a546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610d4e600283612510565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611d8d82611019565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610d4e825490565b600080611ddd8385613140565b905083811015610d4b5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610965565b610981828260405180602001604052806000815250612528565b6000611e5482611d4b565b611eb55760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610965565b6000611ec083611019565b9050806001600160a01b0316846001600160a01b03161480611efb5750836001600160a01b0316611ef084610985565b6001600160a01b0316145b80611f2b57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611f4682611019565b6001600160a01b031614611fae5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610965565b6001600160a01b0382166120105760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610965565b61201b600082611d58565b6001600160a01b038316600090815260016020526040902061203d908261255b565b506001600160a01b03821660009081526001602052604090206120609082612567565b5061206d60028284612573565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000610d4b8383612589565b6000826120cf57506000610d4e565b60006120db838561320a565b9050826120e8858361323f565b14610d4b5760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610965565b60008082116121905760405162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f0000000000006044820152606401610965565b610d4b828461323f565b6000828211156121ec5760405162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006044820152606401610965565b610d4b82846131c4565b6000808080612205868661260f565b9097909650945050505050565b8051610981906009906020840190612bec565b60006122328484846126ac565b90505b9392505050565b612247848484611f33565b61225384848484612715565b610c555760405162461bcd60e51b815260040161096590613253565b604080516020808201869052606088901b6bffffffffffffffffffffffff19168284015260548083018890528351808403909101815260749092019092528051910120600090859085835b86518161ffff16101561239a57816001166001141561232957868161ffff16815181106122e9576122e96132a5565b60200260200101518360405160200161230c929190918252602082015260400190565b60405160208183030381529060405280519060200120925061237b565b82878261ffff1681518110612340576123406132a5565b6020026020010151604051602001612362929190918252602082015260400190565b6040516020818303038152906040528051906020012092505b61238660028361323f565b915080612392816132bb565b9150506122ba565b5060005b85518110156123e7578581815181106123b9576123b96132a5565b60200260200101518314156123d55760019450505050506123f0565b806123df81613158565b91505061239e565b50600093505050505b95945050505050565b60608161241d5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612447578061243181613158565b91506124409050600a8361323f565b9150612421565b60008167ffffffffffffffff81111561246257612462612d23565b6040519080825280601f01601f19166020018201604052801561248c576020820181803683370190505b509050600061249c6001846131c4565b90508593505b8315612507576124b3600a856132dd565b6124be906030613140565b60f81b82826124cc816132f1565b9350815181106124de576124de6132a5565b60200101906001600160f81b031916908160001a905350612500600a8561323f565b93506124a2565b50949350505050565b60008181526001830160205260408120541515610d4b565b61253283836127e6565b61253f6000848484612715565b610b1e5760405162461bcd60e51b815260040161096590613253565b6000610d4b83836128fe565b6000610d4b83836129f1565b600061223284846001600160a01b038516612a40565b815460009082106125e75760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610965565b8260000182815481106125fc576125fc6132a5565b9060005260206000200154905092915050565b81546000908190831061266f5760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610965565b6000846000018481548110612686576126866132a5565b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816126dc5760405162461bcd60e51b81526004016109659190612d10565b50846126e96001836131c4565b815481106126f9576126f96132a5565b9060005260206000209060020201600101549150509392505050565b60006001600160a01b0384163b61272e57506001611f2b565b60006127af630a85bd0160e11b338887876040516024016127529493929190613308565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001613395603291396001600160a01b0388169190612ae1565b90506000818060200190518101906127c79190613345565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b6001600160a01b03821661283c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610965565b61284581611d4b565b156128925760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610965565b6001600160a01b03821660009081526001602052604090206128b49082612567565b506128c160028284612573565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600081815260018301602052604081205480156129e75760006129226001836131c4565b8554909150600090612936906001906131c4565b9050600086600001828154811061294f5761294f6132a5565b9060005260206000200154905080876000018481548110612972576129726132a5565b600091825260209091200155612989836001613140565b600082815260018901602052604090205586548790806129ab576129ab613362565b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610d4e565b6000915050610d4e565b6000818152600183016020526040812054612a3857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d4e565b506000610d4e565b600082815260018401602052604081205480612aa5575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055612235565b8285612ab26001846131c4565b81548110612ac257612ac26132a5565b9060005260206000209060020201600101819055506000915050612235565b6060612232848460008585843b612b3a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610965565b600080866001600160a01b03168587604051612b569190613378565b60006040518083038185875af1925050503d8060008114612b93576040519150601f19603f3d011682016040523d82523d6000602084013e612b98565b606091505b5091509150612ba8828286612bb3565b979650505050505050565b60608315612bc2575081612235565b825115612bd25782518084602001fd5b8160405162461bcd60e51b81526004016109659190612d10565b828054612bf890613085565b90600052602060002090601f016020900481019282612c1a5760008555612c60565b82601f10612c3357805160ff1916838001178555612c60565b82800160010185558215612c60579182015b82811115612c60578251825591602001919060010190612c45565b50612c6c929150612c70565b5090565b5b80821115612c6c5760008155600101612c71565b6001600160e01b031981168114610f9b57600080fd5b600060208284031215612cad57600080fd5b8135610d4b81612c85565b60005b83811015612cd3578181015183820152602001612cbb565b83811115610c555750506000910152565b60008151808452612cfc816020860160208601612cb8565b601f01601f19169290920160200192915050565b602081526000610d4b6020830184612ce4565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612d6257612d62612d23565b604052919050565b600067ffffffffffffffff831115612d8457612d84612d23565b612d97601f8401601f1916602001612d39565b9050828152838383011115612dab57600080fd5b828260208301376000602084830101529392505050565b600060208284031215612dd457600080fd5b813567ffffffffffffffff811115612deb57600080fd5b8201601f81018413612dfc57600080fd5b611f2b84823560208401612d6a565b600060208284031215612e1d57600080fd5b5035919050565b80356001600160a01b03811681146119c157600080fd5b60008060408385031215612e4e57600080fd5b612e5783612e24565b946020939093013593505050565b600060208284031215612e7757600080fd5b610d4b82612e24565b60008060408385031215612e9357600080fd5b82359150612ea360208401612e24565b90509250929050565b600080600060608486031215612ec157600080fd5b612eca84612e24565b9250612ed860208501612e24565b9150604084013590509250925092565b60008060408385031215612efb57600080fd5b612f0483612e24565b915060208301358015158114612f1957600080fd5b809150509250929050565b60008060008060808587031215612f3a57600080fd5b612f4385612e24565b9350612f5160208601612e24565b925060408501359150606085013567ffffffffffffffff811115612f7457600080fd5b8501601f81018713612f8557600080fd5b612f9487823560208401612d6a565b91505092959194509250565b600080600060608486031215612fb557600080fd5b833592506020808501359250604085013567ffffffffffffffff80821115612fdc57600080fd5b818701915087601f830112612ff057600080fd5b81358181111561300257613002612d23565b8060051b9150613013848301612d39565b818152918301840191848101908a84111561302d57600080fd5b938501935b8385101561304b57843582529385019390850190613032565b8096505050505050509250925092565b6000806040838503121561306e57600080fd5b61307783612e24565b9150612ea360208401612e24565b600181811c9082168061309957607f821691505b602082108114156130ba57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252818101527f507572636861736520776f756c6420657863656564206d617820737570706c79604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082198211156131535761315361312a565b500190565b600060001982141561316c5761316c61312a565b5060010190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6000828210156131d6576131d661312a565b500390565b600083516131ed818460208801612cb8565b835190830190613201818360208801612cb8565b01949350505050565b60008160001904831182151516156132245761322461312a565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261324e5761324e613229565b500490565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b600061ffff808316818114156132d3576132d361312a565b6001019392505050565b6000826132ec576132ec613229565b500690565b6000816133005761330061312a565b506000190190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061333b90830184612ce4565b9695505050505050565b60006020828403121561335757600080fd5b8151610d4b81612c85565b634e487b7160e01b600052603160045260246000fd5b6000825161338a818460208701612cb8565b919091019291505056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220e340b08780287010d454baa490881cb3874d9b4297a264b989a90d15aefcc08e64736f6c634300080a003368747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066732f516d5a47373758754637597538793963554b7270597852327945703471766975324e443738536e4d54377a744a6a

Deployed Bytecode

0x6080604052600436106102965760003560e01c80636352211e11610166578063a31cf533116100d3578063c87b56dd1161008f578063e985e9c51161006c578063e985e9c51461080c578063eb8d244414610855578063f2e1f5001461086f578063f2fde38b1461088957005b8063c87b56dd146107b6578063e489d510146107d6578063e6ae64e0146107ec57005b8063a31cf5331461070e578063a4c1291c14610723578063a611708e14610743578063b88d4fde14610763578063bcbec39614610783578063c4be5b59146107a357005b8063715018a611610122578063715018a6146106735780638da5cb5b1461068857806391366113146106a657806395d89b41146106c6578063a0712d68146106db578063a22cb465146106ee57005b80636352211e146105d35780636aa1b09e146105f35780636c0360eb146106095780637084b2b71461061e578063708aa3dc1461063e57806370a082311461065357005b80632d33c3ce1161020457806343864b7d116101c057806343864b7d146105065780634f6ccce714610526578063519679d11461054657806355f804b3146105735780635747e8e8146105935780635ea4352f146105b357005b80632d33c3ce1461045b5780632f745c591461047b57806335c6aaf81461049b578063371756bd146104b15780633ccfd60b146104d157806342842e0e146104e657005b8063177397c011610253578063177397c0146103a557806318160ddd146103d25780631df656b0146103e75780631ed40559146104075780631fe70d6f1461041c57806323b872dd1461043b57005b806301ffc9a71461029857806306fdde03146102e7578063078eef2814610309578063081812fc14610329578063095ea7b3146103615780630ba133c514610381575b005b3480156102a457600080fd5b506102d26102b3366004612c9b565b6001600160e01b03191660009081526020819052604090205460ff1690565b60405190151581526020015b60405180910390f35b3480156102f357600080fd5b506102fc6108a9565b6040516102de9190612d10565b34801561031557600080fd5b50610296610324366004612dc2565b61093b565b34801561033557600080fd5b50610349610344366004612e0b565b610985565b6040516001600160a01b0390911681526020016102de565b34801561036d57600080fd5b5061029661037c366004612e3b565b610a0d565b34801561038d57600080fd5b50610397600c5481565b6040519081526020016102de565b3480156103b157600080fd5b506103976103c0366004612e65565b60166020526000908152604090205481565b3480156103de57600080fd5b50610397610b23565b3480156103f357600080fd5b50610296610402366004612e80565b610b34565b34801561041357600080fd5b50610296610c5b565b34801561042857600080fd5b506012546102d290610100900460ff1681565b34801561044757600080fd5b50610296610456366004612eac565b610c99565b34801561046757600080fd5b50610296610476366004612e0b565b610cca565b34801561048757600080fd5b50610397610496366004612e3b565b610d29565b3480156104a757600080fd5b5061039760195481565b3480156104bd57600080fd5b506102966104cc366004612e65565b610d54565b3480156104dd57600080fd5b50610296610da0565b3480156104f257600080fd5b50610296610501366004612eac565b610f08565b34801561051257600080fd5b50610296610521366004612e0b565b610f23565b34801561053257600080fd5b50610397610541366004612e0b565b610f52565b34801561055257600080fd5b50610397610561366004612e65565b60156020526000908152604090205481565b34801561057f57600080fd5b5061029661058e366004612dc2565b610f68565b34801561059f57600080fd5b506102966105ae366004612e65565b610f9e565b3480156105bf57600080fd5b506102966105ce366004612e0b565b610fea565b3480156105df57600080fd5b506103496105ee366004612e0b565b611019565b3480156105ff57600080fd5b50610397601a5481565b34801561061557600080fd5b506102fc611041565b34801561062a57600080fd5b50610296610639366004612e0b565b611050565b34801561064a57600080fd5b5061029661107f565b34801561065f57600080fd5b5061039761066e366004612e65565b6110c6565b34801561067f57600080fd5b50610296611152565b34801561069457600080fd5b50600a546001600160a01b0316610349565b3480156106b257600080fd5b506102966106c1366004612e0b565b6111c6565b3480156106d257600080fd5b506102fc6111f5565b6102966106e9366004612e0b565b611204565b3480156106fa57600080fd5b50610296610709366004612ee8565b61136a565b34801561071a57600080fd5b5061029661142f565b34801561072f57600080fd5b5061029661073e366004612e0b565b61146d565b34801561074f57600080fd5b5061029661075e366004612e0b565b6114cc565b34801561076f57600080fd5b5061029661077e366004612f24565b6114fb565b34801561078f57600080fd5b5061029661079e366004612e0b565b61152d565b6102966107b1366004612fa0565b61155c565b3480156107c257600080fd5b506102fc6107d1366004612e0b565b61186f565b3480156107e257600080fd5b50610397600b5481565b3480156107f857600080fd5b50610296610807366004612fa0565b6119c6565b34801561081857600080fd5b506102d261082736600461305b565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561086157600080fd5b506012546102d29060ff1681565b34801561087b57600080fd5b50601d546102d29060ff1681565b34801561089557600080fd5b506102966108a4366004612e65565b611c60565b6060600680546108b890613085565b80601f01602080910402602001604051908101604052809291908181526020018280546108e490613085565b80156109315780601f1061090657610100808354040283529160200191610931565b820191906000526020600020905b81548152906001019060200180831161091457829003601f168201915b5050505050905090565b600a546001600160a01b0316331461096e5760405162461bcd60e51b8152600401610965906130c0565b60405180910390fd5b805161098190601c906020840190612bec565b5050565b600061099082611d4b565b6109f15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610965565b506000908152600460205260409020546001600160a01b031690565b6000610a1882611019565b9050806001600160a01b0316836001600160a01b03161415610a865760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610965565b336001600160a01b0382161480610aa25750610aa28133610827565b610b145760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610965565b610b1e8383611d58565b505050565b6000610b2f6002611dc6565b905090565b600a546001600160a01b03163314610b5e5760405162461bcd60e51b8152600401610965906130c0565b600b54610b7383610b6d610b23565b90611dd0565b1115610b915760405162461bcd60e51b8152600401610965906130f5565b600e54601054610ba19084611dd0565b1115610c015760405162461bcd60e51b815260206004820152602960248201527f507572636861736520776f756c6420657863656564206d617820726573657276604482015268195908185b5bdd5b9d60ba1b6064820152608401610965565b8160106000828254610c139190613140565b9091555060009050610c23610b23565b905060005b83811015610c5557610c4383610c3e8484611dd0565b611e2f565b80610c4d81613158565b915050610c28565b50505050565b600a546001600160a01b03163314610c855760405162461bcd60e51b8152600401610965906130c0565b6012805460ff19811660ff90911615179055565b610ca33382611e49565b610cbf5760405162461bcd60e51b815260040161096590613173565b610b1e838383611f33565b600a546001600160a01b03163314610cf45760405162461bcd60e51b8152600401610965906130c0565b601480546001810182556000919091527fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec0155565b6001600160a01b0382166000908152600160205260408120610d4b90836120b4565b90505b92915050565b600a546001600160a01b03163314610d7e5760405162461bcd60e51b8152600401610965906130c0565b601880546001600160a01b0319166001600160a01b0392909216919091179055565b600a546001600160a01b03163314610dca5760405162461bcd60e51b8152600401610965906130c0565b6017546001600160a01b0316610e155760405162461bcd60e51b815260206004820152601060248201526f1dd85b1b195d080c481b9bdd081cd95d60821b6044820152606401610965565b6018546001600160a01b0316610e605760405162461bcd60e51b815260206004820152601060248201526f1dd85b1b195d080c881b9bdd081cd95d60821b6044820152606401610965565b60004790506000610e8b6064610e85601b546064610e7e91906131c4565b85906120c0565b9061213f565b6017546040519192506001600160a01b03169082156108fc029083906000818181858888f19350505050158015610ec6573d6000803e3d6000fd5b506018546001600160a01b03166108fc610ee0848461219a565b6040518115909202916000818181858888f19350505050158015610b1e573d6000803e3d6000fd5b610b1e838383604051806020016040528060008152506114fb565b600a546001600160a01b03163314610f4d5760405162461bcd60e51b8152600401610965906130c0565b600f55565b600080610f606002846121f6565b509392505050565b600a546001600160a01b03163314610f925760405162461bcd60e51b8152600401610965906130c0565b610f9b81612212565b50565b600a546001600160a01b03163314610fc85760405162461bcd60e51b8152600401610965906130c0565b601780546001600160a01b0319166001600160a01b0392909216919091179055565b600a546001600160a01b031633146110145760405162461bcd60e51b8152600401610965906130c0565b600e55565b6000610d4e826040518060600160405280602981526020016133c76029913960029190612225565b6060600980546108b890613085565b600a546001600160a01b0316331461107a5760405162461bcd60e51b8152600401610965906130c0565b600c55565b600a546001600160a01b031633146110a95760405162461bcd60e51b8152600401610965906130c0565b6012805461ff001981166101009182900460ff1615909102179055565b60006001600160a01b0382166111315760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610965565b6001600160a01b0382166000908152600160205260409020610d4e90611dc6565b600a546001600160a01b0316331461117c5760405162461bcd60e51b8152600401610965906130c0565b600a546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600a80546001600160a01b0319169055565b600a546001600160a01b031633146111f05760405162461bcd60e51b8152600401610965906130c0565b601e55565b6060600780546108b890613085565b60125460ff166112565760405162461bcd60e51b815260206004820152601b60248201527f53616c65206d7573742062652061637469766520746f206d696e7400000000006044820152606401610965565b600c548111156112a85760405162461bcd60e51b815260206004820152601e60248201527f496e76616c696420616d6f756e7420746f206d696e74207065722074786e00006044820152606401610965565b600b546112b782610b6d610b23565b11156112d55760405162461bcd60e51b8152600401610965906130f5565b601a5434906112e490836120c0565b11156113325760405162461bcd60e51b815260206004820152601e60248201527f45746865722076616c756520736574206973206e6f7420636f727265637400006044820152606401610965565b600061133c610b23565b905060005b82811015610b1e57611358335b610c3e8484611dd0565b8061136281613158565b915050611341565b6001600160a01b0382163314156113c35760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610965565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600a546001600160a01b031633146114595760405162461bcd60e51b8152600401610965906130c0565b601d805460ff19811660ff90911615179055565b600a546001600160a01b031633146114975760405162461bcd60e51b8152600401610965906130c0565b601380546001810182556000919091527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900155565b600a546001600160a01b031633146114f65760405162461bcd60e51b8152600401610965906130c0565b601955565b6115053383611e49565b6115215760405162461bcd60e51b815260040161096590613173565b610c558484848461223c565b600a546001600160a01b031633146115575760405162461bcd60e51b8152600401610965906130c0565b601a55565b601254610100900460ff166115b35760405162461bcd60e51b815260206004820152601f60248201527f5468652077686974656c697374206973206e6f742061637469766520796574006044820152606401610965565b60125460ff16156116065760405162461bcd60e51b815260206004820152601d60248201527f5468652077686974656c697374206d696e742068617320636c6f7365640000006044820152606401610965565b600c548311156116585760405162461bcd60e51b815260206004820152601e60248201527f496e76616c696420616d6f756e7420746f206d696e74207065722074786e00006044820152606401610965565b600b5461166784610b6d610b23565b11156116855760405162461bcd60e51b8152600401610965906130f5565b6116e3336001848460138054806020026020016040519081016040528092919081815260200182805480156116d957602002820191906000526020600020905b8154815260200190600101908083116116c5575b505050505061226f565b61172f5760405162461bcd60e51b815260206004820152601b60248201527f596f75277265206e6f74206f6e207468652077686974656c69737400000000006044820152606401610965565b600d543360009081526015602052604090205461174d908590613140565b11156117b45760405162461bcd60e51b815260206004820152603060248201527f54686973207472616e73616374696f6e206578636565647320746865206d617860448201526f2077686974656c697374206d696e747360801b6064820152608401610965565b60195434906117c390856120c0565b11156118115760405162461bcd60e51b815260206004820152601e60248201527f45746865722076616c756520736574206973206e6f7420636f727265637400006044820152606401610965565b3360009081526015602052604081208054859290611830908490613140565b9091555060009050611840610b23565b905060005b84811015611868576118563361134e565b8061186081613158565b915050611845565b5050505050565b606061187a82611d4b565b6118de5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610965565b601d5460ff1680156118f25750601e548211155b1561192f576118ff611041565b611908836123f9565b6040516020016119199291906131db565b6040516020818303038152906040529050919050565b601c805461193c90613085565b80601f016020809104026020016040519081016040528092919081815260200182805461196890613085565b80156119b55780601f1061198a576101008083540402835291602001916119b5565b820191906000526020600020905b81548152906001019060200180831161199857829003601f168201915b50505050509050919050565b919050565b601254610100900460ff16611a1d5760405162461bcd60e51b815260206004820152601f60248201527f4769766561776179206d7573742062652061637469766520746f206d696e74006044820152606401610965565b600f54601154611a2d9085611dd0565b1115611a875760405162461bcd60e51b815260206004820152602360248201527f4d696e7420776f756c64206578656564206d6178206769766561776179206d696044820152626e747360e81b6064820152608401610965565b600b54611a9684610b6d610b23565b1115611ae45760405162461bcd60e51b815260206004820152601c60248201527f4d696e7420776f756c6420657863656564206d617820737570706c79000000006044820152606401610965565b611b3f3384848460148054806020026020016040519081016040528092919081815260200182805480156116d957602002820191906000526020600020908154815260200190600101908083116116c557505050505061226f565b611b8b5760405162461bcd60e51b815260206004820152601f60248201527f596f75277265206e6f74206f6e20746865206769766561776179206c697374006044820152606401610965565b3360009081526016602052604090205415611bfe5760405162461bcd60e51b815260206004820152602d60248201527f54686973206164647265737320616c726561647920726563656976656420612060448201526c19da5d99585dd85e481b5a5b9d609a1b6064820152608401610965565b6000611c08610b23565b3360009081526016602052604081208690556011805492935090918691908390611c33908490613140565b9091555060009150505b8481101561186857611c4e3361134e565b80611c5881613158565b915050611c3d565b600a546001600160a01b03163314611c8a5760405162461bcd60e51b8152600401610965906130c0565b6001600160a01b038116611cef5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610965565b600a546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610d4e600283612510565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611d8d82611019565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610d4e825490565b600080611ddd8385613140565b905083811015610d4b5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610965565b610981828260405180602001604052806000815250612528565b6000611e5482611d4b565b611eb55760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610965565b6000611ec083611019565b9050806001600160a01b0316846001600160a01b03161480611efb5750836001600160a01b0316611ef084610985565b6001600160a01b0316145b80611f2b57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611f4682611019565b6001600160a01b031614611fae5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610965565b6001600160a01b0382166120105760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610965565b61201b600082611d58565b6001600160a01b038316600090815260016020526040902061203d908261255b565b506001600160a01b03821660009081526001602052604090206120609082612567565b5061206d60028284612573565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000610d4b8383612589565b6000826120cf57506000610d4e565b60006120db838561320a565b9050826120e8858361323f565b14610d4b5760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610965565b60008082116121905760405162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f0000000000006044820152606401610965565b610d4b828461323f565b6000828211156121ec5760405162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006044820152606401610965565b610d4b82846131c4565b6000808080612205868661260f565b9097909650945050505050565b8051610981906009906020840190612bec565b60006122328484846126ac565b90505b9392505050565b612247848484611f33565b61225384848484612715565b610c555760405162461bcd60e51b815260040161096590613253565b604080516020808201869052606088901b6bffffffffffffffffffffffff19168284015260548083018890528351808403909101815260749092019092528051910120600090859085835b86518161ffff16101561239a57816001166001141561232957868161ffff16815181106122e9576122e96132a5565b60200260200101518360405160200161230c929190918252602082015260400190565b60405160208183030381529060405280519060200120925061237b565b82878261ffff1681518110612340576123406132a5565b6020026020010151604051602001612362929190918252602082015260400190565b6040516020818303038152906040528051906020012092505b61238660028361323f565b915080612392816132bb565b9150506122ba565b5060005b85518110156123e7578581815181106123b9576123b96132a5565b60200260200101518314156123d55760019450505050506123f0565b806123df81613158565b91505061239e565b50600093505050505b95945050505050565b60608161241d5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612447578061243181613158565b91506124409050600a8361323f565b9150612421565b60008167ffffffffffffffff81111561246257612462612d23565b6040519080825280601f01601f19166020018201604052801561248c576020820181803683370190505b509050600061249c6001846131c4565b90508593505b8315612507576124b3600a856132dd565b6124be906030613140565b60f81b82826124cc816132f1565b9350815181106124de576124de6132a5565b60200101906001600160f81b031916908160001a905350612500600a8561323f565b93506124a2565b50949350505050565b60008181526001830160205260408120541515610d4b565b61253283836127e6565b61253f6000848484612715565b610b1e5760405162461bcd60e51b815260040161096590613253565b6000610d4b83836128fe565b6000610d4b83836129f1565b600061223284846001600160a01b038516612a40565b815460009082106125e75760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610965565b8260000182815481106125fc576125fc6132a5565b9060005260206000200154905092915050565b81546000908190831061266f5760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610965565b6000846000018481548110612686576126866132a5565b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816126dc5760405162461bcd60e51b81526004016109659190612d10565b50846126e96001836131c4565b815481106126f9576126f96132a5565b9060005260206000209060020201600101549150509392505050565b60006001600160a01b0384163b61272e57506001611f2b565b60006127af630a85bd0160e11b338887876040516024016127529493929190613308565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001613395603291396001600160a01b0388169190612ae1565b90506000818060200190518101906127c79190613345565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b6001600160a01b03821661283c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610965565b61284581611d4b565b156128925760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610965565b6001600160a01b03821660009081526001602052604090206128b49082612567565b506128c160028284612573565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600081815260018301602052604081205480156129e75760006129226001836131c4565b8554909150600090612936906001906131c4565b9050600086600001828154811061294f5761294f6132a5565b9060005260206000200154905080876000018481548110612972576129726132a5565b600091825260209091200155612989836001613140565b600082815260018901602052604090205586548790806129ab576129ab613362565b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610d4e565b6000915050610d4e565b6000818152600183016020526040812054612a3857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d4e565b506000610d4e565b600082815260018401602052604081205480612aa5575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055612235565b8285612ab26001846131c4565b81548110612ac257612ac26132a5565b9060005260206000209060020201600101819055506000915050612235565b6060612232848460008585843b612b3a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610965565b600080866001600160a01b03168587604051612b569190613378565b60006040518083038185875af1925050503d8060008114612b93576040519150601f19603f3d011682016040523d82523d6000602084013e612b98565b606091505b5091509150612ba8828286612bb3565b979650505050505050565b60608315612bc2575081612235565b825115612bd25782518084602001fd5b8160405162461bcd60e51b81526004016109659190612d10565b828054612bf890613085565b90600052602060002090601f016020900481019282612c1a5760008555612c60565b82601f10612c3357805160ff1916838001178555612c60565b82800160010185558215612c60579182015b82811115612c60578251825591602001919060010190612c45565b50612c6c929150612c70565b5090565b5b80821115612c6c5760008155600101612c71565b6001600160e01b031981168114610f9b57600080fd5b600060208284031215612cad57600080fd5b8135610d4b81612c85565b60005b83811015612cd3578181015183820152602001612cbb565b83811115610c555750506000910152565b60008151808452612cfc816020860160208601612cb8565b601f01601f19169290920160200192915050565b602081526000610d4b6020830184612ce4565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612d6257612d62612d23565b604052919050565b600067ffffffffffffffff831115612d8457612d84612d23565b612d97601f8401601f1916602001612d39565b9050828152838383011115612dab57600080fd5b828260208301376000602084830101529392505050565b600060208284031215612dd457600080fd5b813567ffffffffffffffff811115612deb57600080fd5b8201601f81018413612dfc57600080fd5b611f2b84823560208401612d6a565b600060208284031215612e1d57600080fd5b5035919050565b80356001600160a01b03811681146119c157600080fd5b60008060408385031215612e4e57600080fd5b612e5783612e24565b946020939093013593505050565b600060208284031215612e7757600080fd5b610d4b82612e24565b60008060408385031215612e9357600080fd5b82359150612ea360208401612e24565b90509250929050565b600080600060608486031215612ec157600080fd5b612eca84612e24565b9250612ed860208501612e24565b9150604084013590509250925092565b60008060408385031215612efb57600080fd5b612f0483612e24565b915060208301358015158114612f1957600080fd5b809150509250929050565b60008060008060808587031215612f3a57600080fd5b612f4385612e24565b9350612f5160208601612e24565b925060408501359150606085013567ffffffffffffffff811115612f7457600080fd5b8501601f81018713612f8557600080fd5b612f9487823560208401612d6a565b91505092959194509250565b600080600060608486031215612fb557600080fd5b833592506020808501359250604085013567ffffffffffffffff80821115612fdc57600080fd5b818701915087601f830112612ff057600080fd5b81358181111561300257613002612d23565b8060051b9150613013848301612d39565b818152918301840191848101908a84111561302d57600080fd5b938501935b8385101561304b57843582529385019390850190613032565b8096505050505050509250925092565b6000806040838503121561306e57600080fd5b61307783612e24565b9150612ea360208401612e24565b600181811c9082168061309957607f821691505b602082108114156130ba57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252818101527f507572636861736520776f756c6420657863656564206d617820737570706c79604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082198211156131535761315361312a565b500190565b600060001982141561316c5761316c61312a565b5060010190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6000828210156131d6576131d661312a565b500390565b600083516131ed818460208801612cb8565b835190830190613201818360208801612cb8565b01949350505050565b60008160001904831182151516156132245761322461312a565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261324e5761324e613229565b500490565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b600061ffff808316818114156132d3576132d361312a565b6001019392505050565b6000826132ec576132ec613229565b500690565b6000816133005761330061312a565b506000190190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061333b90830184612ce4565b9695505050505050565b60006020828403121561335757600080fd5b8151610d4b81612c85565b634e487b7160e01b600052603160045260246000fd5b6000825161338a818460208701612cb8565b919091019291505056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220e340b08780287010d454baa490881cb3874d9b4297a264b989a90d15aefcc08e64736f6c634300080a0033

Deployed Bytecode Sourcemap

66401:8345:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9972:150;;;;;;;;;;-1:-1:-1;9972:150:0;;;;;:::i;:::-;-1:-1:-1;;;;;;10081:33:0;10057:4;10081:33;;;;;;;;;;;;;;9972:150;;;;565:14:1;;558:22;540:41;;528:2;513:18;9972:150:0;;;;;;;;51025:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;69050:120::-;;;;;;;;;;-1:-1:-1;69050:120:0;;;;;:::i;:::-;;:::i;53811:221::-;;;;;;;;;;-1:-1:-1;53811:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2972:32:1;;;2954:51;;2942:2;2927:18;53811:221:0;2808:203:1;53341:404:0;;;;;;;;;;-1:-1:-1;53341:404:0;;;;;:::i;:::-;;:::i;66555:24::-;;;;;;;;;;;;;;;;;;;3599:25:1;;;3587:2;3572:18;66555:24:0;3453:177:1;66954:56:0;;;;;;;;;;-1:-1:-1;66954:56:0;;;;;:::i;:::-;;;;;;;;;;;;;;52819:211;;;;;;;;;;;;;:::i;72437:544::-;;;;;;;;;;-1:-1:-1;72437:544:0;;;;;:::i;:::-;;:::i;69404:90::-;;;;;;;;;;;;;:::i;66783:29::-;;;;;;;;;;-1:-1:-1;66783:29:0;;;;;;;;;;;54701:305;;;;;;;;;;-1:-1:-1;54701:305:0;;;;;:::i;:::-;;:::i;68223:112::-;;;;;;;;;;-1:-1:-1;68223:112:0;;;;;:::i;:::-;;:::i;52581:162::-;;;;;;;;;;-1:-1:-1;52581:162:0;;;;;:::i;:::-;;:::i;67080:33::-;;;;;;;;;;;;;;;;69725:102;;;;;;;;;;-1:-1:-1;69725:102:0;;;;;:::i;:::-;;:::i;73907:440::-;;;;;;;;;;;;;:::i;55077:151::-;;;;;;;;;;-1:-1:-1;55077:151:0;;;;;:::i;:::-;;:::i;68819:114::-;;;;;;;;;;-1:-1:-1;68819:114:0;;;;;:::i;:::-;;:::i;53107:172::-;;;;;;;;;;-1:-1:-1;53107:172:0;;;;;:::i;:::-;;:::i;66890:57::-;;;;;;;;;;-1:-1:-1;66890:57:0;;;;;:::i;:::-;;;;;;;;;;;;;;68941:101;;;;;;;;;;-1:-1:-1;68941:101:0;;;;;:::i;:::-;;:::i;69615:102::-;;;;;;;;;;-1:-1:-1;69615:102:0;;;;;:::i;:::-;;:::i;68691:120::-;;;;;;;;;;-1:-1:-1;68691:120:0;;;;;:::i;:::-;;:::i;50781:177::-;;;;;;;;;;-1:-1:-1;50781:177:0;;;;;:::i;:::-;;:::i;67120:31::-;;;;;;;;;;;;;;;;52400:97;;;;;;;;;;;;;:::i;68583:100::-;;;;;;;;;;-1:-1:-1;68583:100:0;;;;;:::i;:::-;;:::i;69502:105::-;;;;;;;;;;;;;:::i;50498:221::-;;;;;;;;;;-1:-1:-1;50498:221:0;;;;;:::i;:::-;;:::i;65690:148::-;;;;;;;;;;;;;:::i;65039:87::-;;;;;;;;;;-1:-1:-1;65112:6:0;;-1:-1:-1;;;;;65112:6:0;65039:87;;69282:114;;;;;;;;;;-1:-1:-1;69282:114:0;;;;;:::i;:::-;;:::i;51194:104::-;;;;;;;;;;;;;:::i;71831:598::-;;;;;;:::i;:::-;;:::i;54104:295::-;;;;;;;;;;-1:-1:-1;54104:295:0;;;;;:::i;:::-;;:::i;69178:96::-;;;;;;;;;;;;;:::i;68101:114::-;;;;;;;;;;-1:-1:-1;68101:114:0;;;;;:::i;:::-;;:::i;68343:112::-;;;;;;;;;;-1:-1:-1;68343:112:0;;;;;:::i;:::-;;:::i;55299:285::-;;;;;;;;;;-1:-1:-1;55299:285:0;;;;;:::i;:::-;;:::i;68467:108::-;;;;;;;;;;-1:-1:-1;68467:108:0;;;;;:::i;:::-;;:::i;69835:1086::-;;;;;;:::i;:::-;;:::i;74355:388::-;;;;;;;;;;-1:-1:-1;74355:388:0;;;;;:::i;:::-;;:::i;66517:31::-;;;;;;;;;;;;;;;;70929:894;;;;;;;;;;-1:-1:-1;70929:894:0;;;;;:::i;:::-;;:::i;54470:164::-;;;;;;;;;;-1:-1:-1;54470:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;54591:25:0;;;54567:4;54591:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;54470:164;66752:24;;;;;;;;;;-1:-1:-1;66752:24:0;;;;;;;;67228:26;;;;;;;;;;-1:-1:-1;67228:26:0;;;;;;;;65993:244;;;;;;;;;;-1:-1:-1;65993:244:0;;;;;:::i;:::-;;:::i;51025:100::-;51079:13;51112:5;51105:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51025:100;:::o;69050:120::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;;;;;;;;;69134:28;;::::1;::::0;:12:::1;::::0;:28:::1;::::0;::::1;::::0;::::1;:::i;:::-;;69050:120:::0;:::o;53811:221::-;53887:7;53915:16;53923:7;53915;:16::i;:::-;53907:73;;;;-1:-1:-1;;;53907:73:0;;7927:2:1;53907:73:0;;;7909:21:1;7966:2;7946:18;;;7939:30;8005:34;7985:18;;;7978:62;-1:-1:-1;;;8056:18:1;;;8049:42;8108:19;;53907:73:0;7725:408:1;53907:73:0;-1:-1:-1;54000:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;54000:24:0;;53811:221::o;53341:404::-;53422:13;53438:23;53453:7;53438:14;:23::i;:::-;53422:39;;53486:5;-1:-1:-1;;;;;53480:11:0;:2;-1:-1:-1;;;;;53480:11:0;;;53472:57;;;;-1:-1:-1;;;53472:57:0;;8340:2:1;53472:57:0;;;8322:21:1;8379:2;8359:18;;;8352:30;8418:34;8398:18;;;8391:62;-1:-1:-1;;;8469:18:1;;;8462:31;8510:19;;53472:57:0;8138:397:1;53472:57:0;733:10;-1:-1:-1;;;;;53550:21:0;;;;:69;;-1:-1:-1;53575:44:0;53599:5;733:10;54470:164;:::i;53575:44::-;53542:161;;;;-1:-1:-1;;;53542:161:0;;8742:2:1;53542:161:0;;;8724:21:1;8781:2;8761:18;;;8754:30;8820:34;8800:18;;;8793:62;8891:26;8871:18;;;8864:54;8935:19;;53542:161:0;8540:420:1;53542:161:0;53716:21;53725:2;53729:7;53716:8;:21::i;:::-;53411:334;53341:404;;:::o;52819:211::-;52880:7;53001:21;:12;:19;:21::i;:::-;52994:28;;52819:211;:::o;72437:544::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;72574:16:::1;;72537:33;72555:14;72537:13;:11;:13::i;:::-;:17:::0;::::1;:33::i;:::-;:53;;72529:98;;;;-1:-1:-1::0;;;72529:98:0::1;;;;;;;:::i;:::-;72690:19;::::0;72646:20:::1;::::0;:40:::1;::::0;72671:14;72646:24:::1;:40::i;:::-;:63;;72638:117;;;::::0;-1:-1:-1;;;72638:117:0;;9528:2:1;72638:117:0::1;::::0;::::1;9510:21:1::0;9567:2;9547:18;;;9540:30;9606:34;9586:18;;;9579:62;-1:-1:-1;;;9657:18:1;;;9650:39;9706:19;;72638:117:0::1;9326:405:1::0;72638:117:0::1;72792:14;72768:20;;:38;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;72817:14:0::1;::::0;-1:-1:-1;72834:13:0::1;:11;:13::i;:::-;72817:30;;72858:9;72880:93;72896:14;72892:1;:18;72880:93;;;72932:29;72942:3:::0;72947:13:::1;:6:::0;72958:1;72947:10:::1;:13::i;:::-;72932:9;:29::i;:::-;72912:3:::0;::::1;::::0;::::1;:::i;:::-;;;;72880:93;;;72518:463;;72437:544:::0;;:::o;69404:90::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;69474:12:::1;::::0;;-1:-1:-1;;69458:28:0;::::1;69474:12;::::0;;::::1;69473:13;69458:28;::::0;;69404:90::o;54701:305::-;54862:41;733:10;54895:7;54862:18;:41::i;:::-;54854:103;;;;-1:-1:-1;;;54854:103:0;;;;;;;:::i;:::-;54970:28;54980:4;54986:2;54990:7;54970:9;:28::i;68223:112::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;68298:17:::1;:29:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;68298:29:0;;;;;::::1;::::0;68223:112::o;52581:162::-;-1:-1:-1;;;;;52705:20:0;;52678:7;52705:20;;;:13;:20;;;;;:30;;52729:5;52705:23;:30::i;:::-;52698:37;;52581:162;;;;;:::o;69725:102::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;69797:13:::1;:22:::0;;-1:-1:-1;;;;;;69797:22:0::1;-1:-1:-1::0;;;;;69797:22:0;;;::::1;::::0;;;::::1;::::0;;69725:102::o;73907:440::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;73965:13:::1;::::0;-1:-1:-1;;;;;73965:13:0::1;73957:56;;;::::0;-1:-1:-1;;;73957:56:0;;10761:2:1;73957:56:0::1;::::0;::::1;10743:21:1::0;10800:2;10780:18;;;10773:30;-1:-1:-1;;;10819:18:1;;;10812:46;10875:18;;73957:56:0::1;10559:340:1::0;73957:56:0::1;74032:13;::::0;-1:-1:-1;;;;;74032:13:0::1;74024:56;;;::::0;-1:-1:-1;;;74024:56:0;;11106:2:1;74024:56:0::1;::::0;::::1;11088:21:1::0;11145:2;11125:18;;;11118:30;-1:-1:-1;;;11164:18:1;;;11157:46;11220:18;;74024:56:0::1;10904:340:1::0;74024:56:0::1;74091:15;74109:21;74091:39;;74141:21;74165:47;74208:3;74165:38;74183:19;;74177:3;:25;;;;:::i;:::-;74165:7:::0;;:11:::1;:38::i;:::-;:42:::0;::::1;:47::i;:::-;74231:13;::::0;74223:46:::1;::::0;74141:71;;-1:-1:-1;;;;;;74231:13:0::1;::::0;74223:46;::::1;;;::::0;74141:71;;74231:13:::1;74223:46:::0;74231:13;74223:46;74141:71;74231:13;74223:46;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;74288:13:0::1;::::0;-1:-1:-1;;;;;74288:13:0::1;74280:59;74312:26;:7:::0;74324:13;74312:11:::1;:26::i;:::-;74280:59;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;55077:151:::0;55181:39;55198:4;55204:2;55208:7;55181:39;;;;;;;;;;;;:16;:39::i;68819:114::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;68897:16:::1;:28:::0;68819:114::o;53107:172::-;53182:7;;53224:22;:12;53240:5;53224:15;:22::i;:::-;-1:-1:-1;53202:44:0;53107:172;-1:-1:-1;;;53107:172:0:o;68941:101::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;69014:20:::1;69026:7;69014:11;:20::i;:::-;68941:101:::0;:::o;69615:102::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;69687:13:::1;:22:::0;;-1:-1:-1;;;;;;69687:22:0::1;-1:-1:-1::0;;;;;69687:22:0;;;::::1;::::0;;;::::1;::::0;;69615:102::o;68691:120::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;68772:19:::1;:31:::0;68691:120::o;50781:177::-;50853:7;50880:70;50897:7;50880:70;;;;;;;;;;;;;;;;;:12;;:70;:16;:70::i;52400:97::-;52448:13;52481:8;52474:15;;;;;:::i;68583:100::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;68654:9:::1;:21:::0;68583:100::o;69502:105::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;69582:17:::1;::::0;;-1:-1:-1;;69561:38:0;::::1;69582:17;::::0;;;::::1;;;69581:18;69561:38:::0;;::::1;;::::0;;69502:105::o;50498:221::-;50570:7;-1:-1:-1;;;;;50598:19:0;;50590:74;;;;-1:-1:-1;;;50590:74:0;;11581:2:1;50590:74:0;;;11563:21:1;11620:2;11600:18;;;11593:30;11659:34;11639:18;;;11632:62;-1:-1:-1;;;11710:18:1;;;11703:40;11760:19;;50590:74:0;11379:406:1;50590:74:0;-1:-1:-1;;;;;50682:20:0;;;;;;:13;:20;;;;;:29;;:27;:29::i;65690:148::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;65781:6:::1;::::0;65760:40:::1;::::0;65797:1:::1;::::0;-1:-1:-1;;;;;65781:6:0::1;::::0;65760:40:::1;::::0;65797:1;;65760:40:::1;65811:6;:19:::0;;-1:-1:-1;;;;;;65811:19:0::1;::::0;;65690:148::o;69282:114::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;69360:18:::1;:28:::0;69282:114::o;51194:104::-;51250:13;51283:7;51276:14;;;;;:::i;71831:598::-;71905:12;;;;71897:52;;;;-1:-1:-1;;;71897:52:0;;11992:2:1;71897:52:0;;;11974:21:1;12031:2;12011:18;;;12004:30;12070:29;12050:18;;;12043:57;12117:18;;71897:52:0;11790:351:1;71897:52:0;71986:9;;71968:14;:27;;71960:70;;;;-1:-1:-1;;;71960:70:0;;12348:2:1;71960:70:0;;;12330:21:1;12387:2;12367:18;;;12360:30;12426:32;12406:18;;;12399:60;12476:18;;71960:70:0;12146:354:1;71960:70:0;72086:16;;72049:33;72067:14;72049:13;:11;:13::i;:33::-;:53;;72041:98;;;;-1:-1:-1;;;72041:98:0;;;;;;;:::i;:::-;72158:16;;72198:9;;72158:36;;72179:14;72158:20;:36::i;:::-;:49;;72150:92;;;;-1:-1:-1;;;72150:92:0;;12707:2:1;72150:92:0;;;12689:21:1;12746:2;12726:18;;;12719:30;12785:32;12765:18;;;12758:60;12835:18;;72150:92:0;12505:354:1;72150:92:0;72255:15;72273:13;:11;:13::i;:::-;72255:31;;72297:9;72319:103;72335:14;72331:1;:18;72319:103;;;72371:39;733:10;72381:12;72395:14;:7;72407:1;72395:11;:14::i;72371:39::-;72351:3;;;;:::i;:::-;;;;72319:103;;54104:295;-1:-1:-1;;;;;54207:24:0;;733:10;54207:24;;54199:62;;;;-1:-1:-1;;;54199:62:0;;13066:2:1;54199:62:0;;;13048:21:1;13105:2;13085:18;;;13078:30;13144:27;13124:18;;;13117:55;13189:18;;54199:62:0;12864:349:1;54199:62:0;733:10;54274:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;54274:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;54274:53:0;;;;;;;;;;54343:48;;540:41:1;;;54274:42:0;;733:10;54343:48;;513:18:1;54343:48:0;;;;;;;54104:295;;:::o;69178:96::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;69252:14:::1;::::0;;-1:-1:-1;;69234:32:0;::::1;69252:14;::::0;;::::1;69251:15;69234:32;::::0;;69178:96::o;68101:114::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;68177:18:::1;:30:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;68177:30:0;;;;;::::1;::::0;68101:114::o;68343:112::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;68420:18:::1;:27:::0;68343:112::o;55299:285::-;55431:41;733:10;55464:7;55431:18;:41::i;:::-;55423:103;;;;-1:-1:-1;;;55423:103:0;;;;;;;:::i;:::-;55537:39;55551:4;55557:2;55561:7;55570:5;55537:13;:39::i;68467:108::-;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;68542:16:::1;:25:::0;68467:108::o;69835:1086::-;69967:17;;;;;;;69959:61;;;;-1:-1:-1;;;69959:61:0;;13420:2:1;69959:61:0;;;13402:21:1;13459:2;13439:18;;;13432:30;13498:33;13478:18;;;13471:61;13549:18;;69959:61:0;13218:355:1;69959:61:0;70039:12;;;;:21;70031:63;;;;-1:-1:-1;;;70031:63:0;;13780:2:1;70031:63:0;;;13762:21:1;13819:2;13799:18;;;13792:30;13858:31;13838:18;;;13831:59;13907:18;;70031:63:0;13578:353:1;70031:63:0;70131:9;;70113:14;:27;;70105:70;;;;-1:-1:-1;;;70105:70:0;;12348:2:1;70105:70:0;;;12330:21:1;12387:2;12367:18;;;12360:30;12426:32;12406:18;;;12399:60;12476:18;;70105:70:0;12146:354:1;70105:70:0;70231:16;;70194:33;70212:14;70194:13;:11;:13::i;:33::-;:53;;70186:98;;;;-1:-1:-1;;;70186:98:0;;;;;;;:::i;:::-;70303:79;733:10;70336:1;70339:15;70356:5;70363:18;70303:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:18;:79::i;:::-;70295:119;;;;-1:-1:-1;;;70295:119:0;;14138:2:1;70295:119:0;;;14120:21:1;14177:2;14157:18;;;14150:30;14216:29;14196:18;;;14189:57;14263:18;;70295:119:0;13936:351:1;70295:119:0;70492:17;;733:10;70434:36;;;;:22;:36;;;;;;:53;;70473:14;;70434:53;:::i;:::-;70433:76;;70425:137;;;;-1:-1:-1;;;70425:137:0;;14494:2:1;70425:137:0;;;14476:21:1;14533:2;14513:18;;;14506:30;14572:34;14552:18;;;14545:62;-1:-1:-1;;;14623:18:1;;;14616:46;14679:19;;70425:137:0;14292:412:1;70425:137:0;70581:18;;70623:9;;70581:38;;70604:14;70581:22;:38::i;:::-;:51;;70573:94;;;;-1:-1:-1;;;70573:94:0;;12707:2:1;70573:94:0;;;12689:21:1;12746:2;12726:18;;;12719:30;12785:32;12765:18;;;12758:60;12835:18;;70573:94:0;12505:354:1;70573:94:0;733:10;70680:36;;;;:22;:36;;;;;:54;;70720:14;;70680:36;:54;;70720:14;;70680:54;:::i;:::-;;;;-1:-1:-1;70747:15:0;;-1:-1:-1;70765:13:0;:11;:13::i;:::-;70747:31;;70789:9;70811:103;70827:14;70823:1;:18;70811:103;;;70863:39;733:10;70873:12;653:98;70863:39;70843:3;;;;:::i;:::-;;;;70811:103;;;69948:973;;69835:1086;;;:::o;74355:388::-;74428:13;74462:16;74470:7;74462;:16::i;:::-;74454:76;;;;-1:-1:-1;;;74454:76:0;;14911:2:1;74454:76:0;;;14893:21:1;14950:2;14930:18;;;14923:30;14989:34;14969:18;;;14962:62;-1:-1:-1;;;15040:18:1;;;15033:45;15095:19;;74454:76:0;14709:411:1;74454:76:0;74546:14;;;;:47;;;;;74575:18;;74564:7;:29;;74546:47;74543:193;;;74641:9;:7;:9::i;:::-;74652:18;:7;:16;:18::i;:::-;74624:47;;;;;;;;;:::i;:::-;;;;;;;;;;;;;74610:62;;74355:388;;;:::o;74543:193::-;74712:12;74705:19;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74355:388;;;:::o;74543:193::-;74355:388;;;:::o;70929:894::-;71044:17;;;;;;;71036:61;;;;-1:-1:-1;;;71036:61:0;;15802:2:1;71036:61:0;;;15784:21:1;15841:2;15821:18;;;15814:30;15880:33;15860:18;;;15853:61;15931:18;;71036:61:0;15600:355:1;71036:61:0;71149:16;;71116:17;;:29;;71138:6;71116:21;:29::i;:::-;:49;;71108:97;;;;-1:-1:-1;;;71108:97:0;;16162:2:1;71108:97:0;;;16144:21:1;16201:2;16181:18;;;16174:30;16240:34;16220:18;;;16213:62;-1:-1:-1;;;16291:18:1;;;16284:33;16334:19;;71108:97:0;15960:399:1;71108:97:0;71253:16;;71224:25;71242:6;71224:13;:11;:13::i;:25::-;:45;;71216:86;;;;-1:-1:-1;;;71216:86:0;;16566:2:1;71216:86:0;;;16548:21:1;16605:2;16585:18;;;16578:30;16644;16624:18;;;16617:58;16692:18;;71216:86:0;16364:352:1;71216:86:0;71321:83;733:10;71354:6;71362:15;71379:5;71386:17;71321:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:18;:83::i;:::-;71313:127;;;;-1:-1:-1;;;71313:127:0;;16923:2:1;71313:127:0;;;16905:21:1;16962:2;16942:18;;;16935:30;17001:33;16981:18;;;16974:61;17052:18;;71313:127:0;16721:355:1;71313:127:0;733:10;71459:35;;;;:21;:35;;;;;;:40;71451:98;;;;-1:-1:-1;;;71451:98:0;;17283:2:1;71451:98:0;;;17265:21:1;17322:2;17302:18;;;17295:30;17361:34;17341:18;;;17334:62;-1:-1:-1;;;17412:18:1;;;17405:43;17465:19;;71451:98:0;17081:409:1;71451:98:0;71562:15;71580:13;:11;:13::i;:::-;733:10;71604:9;71626:35;;;:21;:35;;;;;:44;;;71681:17;:27;;71562:31;;-1:-1:-1;71604:9:0;;71664:6;;71681:17;71604:9;;71681:27;;71664:6;;71681:27;:::i;:::-;;;;-1:-1:-1;71730:1:0;;-1:-1:-1;;71721:95:0;71737:6;71733:1;:10;71721:95;;;71765:39;733:10;71775:12;653:98;71765:39;71745:3;;;;:::i;:::-;;;;71721:95;;65993:244;65112:6;;-1:-1:-1;;;;;65112:6:0;733:10;65259:23;65251:68;;;;-1:-1:-1;;;65251:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;66082:22:0;::::1;66074:73;;;::::0;-1:-1:-1;;;66074:73:0;;17697:2:1;66074:73:0::1;::::0;::::1;17679:21:1::0;17736:2;17716:18;;;17709:30;17775:34;17755:18;;;17748:62;-1:-1:-1;;;17826:18:1;;;17819:36;17872:19;;66074:73:0::1;17495:402:1::0;66074:73:0::1;66184:6;::::0;66163:38:::1;::::0;-1:-1:-1;;;;;66163:38:0;;::::1;::::0;66184:6:::1;::::0;66163:38:::1;::::0;66184:6:::1;::::0;66163:38:::1;66212:6;:17:::0;;-1:-1:-1;;;;;;66212:17:0::1;-1:-1:-1::0;;;;;66212:17:0;;;::::1;::::0;;;::::1;::::0;;65993:244::o;57051:127::-;57116:4;57140:30;:12;57162:7;57140:21;:30::i;63069:192::-;63144:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;63144:29:0;-1:-1:-1;;;;;63144:29:0;;;;;;;;:24;;63198:23;63144:24;63198:14;:23::i;:::-;-1:-1:-1;;;;;63189:46:0;;;;;;;;;;;63069:192;;:::o;43865:123::-;43934:7;43961:19;43969:3;40527:19;;40444:110;13497:179;13555:7;;13587:5;13591:1;13587;:5;:::i;:::-;13575:17;;13616:1;13611;:6;;13603:46;;;;-1:-1:-1;;;13603:46:0;;18104:2:1;13603:46:0;;;18086:21:1;18143:2;18123:18;;;18116:30;18182:29;18162:18;;;18155:57;18229:18;;13603:46:0;17902:351:1;58043:110:0;58119:26;58129:2;58133:7;58119:26;;;;;;;;;;;;:9;:26::i;57345:355::-;57438:4;57463:16;57471:7;57463;:16::i;:::-;57455:73;;;;-1:-1:-1;;;57455:73:0;;18460:2:1;57455:73:0;;;18442:21:1;18499:2;18479:18;;;18472:30;18538:34;18518:18;;;18511:62;-1:-1:-1;;;18589:18:1;;;18582:42;18641:19;;57455:73:0;18258:408:1;57455:73:0;57539:13;57555:23;57570:7;57555:14;:23::i;:::-;57539:39;;57608:5;-1:-1:-1;;;;;57597:16:0;:7;-1:-1:-1;;;;;57597:16:0;;:51;;;;57641:7;-1:-1:-1;;;;;57617:31:0;:20;57629:7;57617:11;:20::i;:::-;-1:-1:-1;;;;;57617:31:0;;57597:51;:94;;;-1:-1:-1;;;;;;54591:25:0;;;54567:4;54591:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;57652:39;57589:103;57345:355;-1:-1:-1;;;;57345:355:0:o;60481:599::-;60606:4;-1:-1:-1;;;;;60579:31:0;:23;60594:7;60579:14;:23::i;:::-;-1:-1:-1;;;;;60579:31:0;;60571:85;;;;-1:-1:-1;;;60571:85:0;;18873:2:1;60571:85:0;;;18855:21:1;18912:2;18892:18;;;18885:30;18951:34;18931:18;;;18924:62;-1:-1:-1;;;19002:18:1;;;18995:39;19051:19;;60571:85:0;18671:405:1;60571:85:0;-1:-1:-1;;;;;60693:16:0;;60685:65;;;;-1:-1:-1;;;60685:65:0;;19283:2:1;60685:65:0;;;19265:21:1;19322:2;19302:18;;;19295:30;19361:34;19341:18;;;19334:62;-1:-1:-1;;;19412:18:1;;;19405:34;19456:19;;60685:65:0;19081:400:1;60685:65:0;60867:29;60884:1;60888:7;60867:8;:29::i;:::-;-1:-1:-1;;;;;60909:19:0;;;;;;:13;:19;;;;;:35;;60936:7;60909:26;:35::i;:::-;-1:-1:-1;;;;;;60955:17:0;;;;;;:13;:17;;;;;:30;;60977:7;60955:21;:30::i;:::-;-1:-1:-1;60998:29:0;:12;61015:7;61024:2;60998:16;:29::i;:::-;;61064:7;61060:2;-1:-1:-1;;;;;61045:27:0;61054:4;-1:-1:-1;;;;;61045:27:0;;;;;;;;;;;60481:599;;;:::o;35693:137::-;35764:7;35799:22;35803:3;35815:5;35799:3;:22::i;14376:220::-;14434:7;14458:6;14454:20;;-1:-1:-1;14473:1:0;14466:8;;14454:20;14485:9;14497:5;14501:1;14497;:5;:::i;:::-;14485:17;-1:-1:-1;14530:1:0;14521:5;14525:1;14485:17;14521:5;:::i;:::-;:10;14513:56;;;;-1:-1:-1;;;14513:56:0;;20118:2:1;14513:56:0;;;20100:21:1;20157:2;20137:18;;;20130:30;20196:34;20176:18;;;20169:62;-1:-1:-1;;;20247:18:1;;;20240:31;20288:19;;14513:56:0;19916:397:1;15074:153:0;15132:7;15164:1;15160;:5;15152:44;;;;-1:-1:-1;;;15152:44:0;;20520:2:1;15152:44:0;;;20502:21:1;20559:2;20539:18;;;20532:30;20598:28;20578:18;;;20571:56;20644:18;;15152:44:0;20318:350:1;15152:44:0;15214:5;15218:1;15214;:5;:::i;13959:158::-;14017:7;14050:1;14045;:6;;14037:49;;;;-1:-1:-1;;;14037:49:0;;20875:2:1;14037:49:0;;;20857:21:1;20914:2;20894:18;;;20887:30;20953:32;20933:18;;;20926:60;21003:18;;14037:49:0;20673:354:1;14037:49:0;14104:5;14108:1;14104;:5;:::i;44327:236::-;44407:7;;;;44467:22;44471:3;44483:5;44467:3;:22::i;:::-;44436:53;;;;-1:-1:-1;44327:236:0;-1:-1:-1;;;;;44327:236:0:o;61681:100::-;61754:19;;;;:8;;:19;;;;;:::i;45613:213::-;45720:7;45771:44;45776:3;45796;45802:12;45771:4;:44::i;:::-;45763:53;-1:-1:-1;45613:213:0;;;;;;:::o;56466:272::-;56580:28;56590:4;56596:2;56600:7;56580:9;:28::i;:::-;56627:48;56650:4;56656:2;56660:7;56669:5;56627:22;:48::i;:::-;56619:111;;;;-1:-1:-1;;;56619:111:0;;;;;;;:::i;72989:910::-;73255:39;;;;;;;21636:19:1;;;21693:2;21689:15;;;-1:-1:-1;;21685:53:1;21671:12;;;21664:75;21755:12;;;;21748:28;;;73255:39:0;;;;;;;;;;21792:12:1;;;;73255:39:0;;;73245:50;;;;;-1:-1:-1;;21748:28:1;;21636:19;-1:-1:-1;73337:292:0;73360:5;:12;73356:1;:16;;;73337:292;;;73399:4;73406;73399:11;73415:1;73398:18;73394:200;;;73471:5;73477:1;73471:8;;;;;;;;;;:::i;:::-;;;;;;;73481:4;73454:32;;;;;;;;22104:19:1;;;22148:2;22139:12;;22132:28;22185:2;22176:12;;21947:247;73454:32:0;;;;;;;;;;;;;73444:43;;;;;;73437:50;;73394:200;;;73562:4;73568:5;73574:1;73568:8;;;;;;;;;;:::i;:::-;;;;;;;73545:32;;;;;;;;22104:19:1;;;22148:2;22139:12;;22132:28;22185:2;22176:12;;21947:247;73545:32:0;;;;;;;;;;;;;73535:43;;;;;;73528:50;;73394:200;73608:9;73616:1;73608:9;;:::i;:::-;;-1:-1:-1;73374:3:0;;;;:::i;:::-;;;;73337:292;;;;73708:6;73704:163;73724:9;:16;73720:1;:20;73704:163;;;73783:9;73793:1;73783:12;;;;;;;;:::i;:::-;;;;;;;73775:4;:20;73771:85;;;73836:4;73829:11;;;;;;;;73771:85;73742:3;;;;:::i;:::-;;;;73704:163;;;;73886:5;73879:12;;;;;72989:910;;;;;;;;:::o;46040:746::-;46096:13;46317:10;46313:53;;-1:-1:-1;;46344:10:0;;;;;;;;;;;;-1:-1:-1;;;46344:10:0;;;;;46040:746::o;46313:53::-;46391:5;46376:12;46432:78;46439:9;;46432:78;;46465:8;;;;:::i;:::-;;-1:-1:-1;46488:10:0;;-1:-1:-1;46496:2:0;46488:10;;:::i;:::-;;;46432:78;;;46520:19;46552:6;46542:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46542:17:0;-1:-1:-1;46520:39:0;-1:-1:-1;46570:13:0;46586:10;46595:1;46586:6;:10;:::i;:::-;46570:26;;46614:5;46607:12;;46630:117;46637:9;;46630:117;;46699:9;46706:2;46699:4;:9;:::i;:::-;46694:14;;:2;:14;:::i;:::-;46681:29;;46663:6;46670:7;;;;:::i;:::-;;;46663:15;;;;;;;;:::i;:::-;;;;:47;-1:-1:-1;;;;;46663:47:0;;;;;;;;-1:-1:-1;46725:10:0;46733:2;46725:10;;:::i;:::-;;;46630:117;;;-1:-1:-1;46771:6:0;46040:746;-1:-1:-1;;;;46040:746:0:o;43626:151::-;43710:4;40319:17;;;:12;;;:17;;;;;;:22;;43734:35;40224:125;58380:250;58476:18;58482:2;58486:7;58476:5;:18::i;:::-;58513:54;58544:1;58548:2;58552:7;58561:5;58513:22;:54::i;:::-;58505:117;;;;-1:-1:-1;;;58505:117:0;;;;;;;:::i;34780:137::-;34850:4;34874:35;34882:3;34902:5;34874:7;:35::i;34473:131::-;34540:4;34564:32;34569:3;34589:5;34564:4;:32::i;43049:185::-;43138:4;43162:64;43167:3;43187;-1:-1:-1;;;;;43201:23:0;;43162:4;:64::i;30733:204::-;30828:18;;30800:7;;30828:26;-1:-1:-1;30820:73:0;;;;-1:-1:-1;;;30820:73:0;;22861:2:1;30820:73:0;;;22843:21:1;22900:2;22880:18;;;22873:30;22939:34;22919:18;;;22912:62;-1:-1:-1;;;22990:18:1;;;22983:32;23032:19;;30820:73:0;22659:398:1;30820:73:0;30911:3;:11;;30923:5;30911:18;;;;;;;;:::i;:::-;;;;;;;;;30904:25;;30733:204;;;;:::o;40909:279::-;41013:19;;40976:7;;;;41013:27;-1:-1:-1;41005:74:0;;;;-1:-1:-1;;;41005:74:0;;23264:2:1;41005:74:0;;;23246:21:1;23303:2;23283:18;;;23276:30;23342:34;23322:18;;;23315:62;-1:-1:-1;;;23393:18:1;;;23386:32;23435:19;;41005:74:0;23062:398:1;41005:74:0;41092:22;41117:3;:12;;41130:5;41117:19;;;;;;;;:::i;:::-;;;;;;;;;;;41092:44;;41155:5;:10;;;41167:5;:12;;;41147:33;;;;;40909:279;;;;;:::o;42406:319::-;42500:7;42539:17;;;:12;;;:17;;;;;;42590:12;42575:13;42567:36;;;;-1:-1:-1;;;42567:36:0;;;;;;;;:::i;:::-;-1:-1:-1;42657:3:0;42670:12;42681:1;42670:8;:12;:::i;:::-;42657:26;;;;;;;;:::i;:::-;;;;;;;;;;;:33;;;42650:40;;;42406:319;;;;;:::o;62346:604::-;62467:4;-1:-1:-1;;;;;62494:13:0;;19268:20;62489:60;;-1:-1:-1;62533:4:0;62526:11;;62489:60;62559:23;62585:252;-1:-1:-1;;;733:10:0;62725:4;62744:7;62766:5;62601:181;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;62601:181:0;;;;;;;-1:-1:-1;;;;;62601:181:0;;;;;;;;;;;62585:252;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;62585:15:0;;;:252;:15;:252::i;:::-;62559:278;;62848:13;62875:10;62864:32;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;62915:26:0;-1:-1:-1;;;62915:26:0;;-1:-1:-1;;;62346:604:0;;;;;;:::o;58966:404::-;-1:-1:-1;;;;;59046:16:0;;59038:61;;;;-1:-1:-1;;;59038:61:0;;24415:2:1;59038:61:0;;;24397:21:1;;;24434:18;;;24427:30;24493:34;24473:18;;;24466:62;24545:18;;59038:61:0;24213:356:1;59038:61:0;59119:16;59127:7;59119;:16::i;:::-;59118:17;59110:58;;;;-1:-1:-1;;;59110:58:0;;24776:2:1;59110:58:0;;;24758:21:1;24815:2;24795:18;;;24788:30;24854;24834:18;;;24827:58;24902:18;;59110:58:0;24574:352:1;59110:58:0;-1:-1:-1;;;;;59239:17:0;;;;;;:13;:17;;;;;:30;;59261:7;59239:21;:30::i;:::-;-1:-1:-1;59282:29:0;:12;59299:7;59308:2;59282:16;:29::i;:::-;-1:-1:-1;59329:33:0;;59354:7;;-1:-1:-1;;;;;59329:33:0;;;59346:1;;59329:33;;59346:1;;59329:33;58966:404;;:::o;28435:1544::-;28501:4;28640:19;;;:12;;;:19;;;;;;28676:15;;28672:1300;;29038:21;29062:14;29075:1;29062:10;:14;:::i;:::-;29111:18;;29038:38;;-1:-1:-1;29091:17:0;;29111:22;;29132:1;;29111:22;:::i;:::-;29091:42;;29378:17;29398:3;:11;;29410:9;29398:22;;;;;;;;:::i;:::-;;;;;;;;;29378:42;;29544:9;29515:3;:11;;29527:13;29515:26;;;;;;;;:::i;:::-;;;;;;;;;;:38;29647:17;:13;29663:1;29647:17;:::i;:::-;29621:23;;;;:12;;;:23;;;;;:43;29773:17;;29621:3;;29773:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;29868:3;:12;;:19;29881:5;29868:19;;;;;;;;;;;29861:26;;;29911:4;29904:11;;;;;;;;28672:1300;29955:5;29948:12;;;;;27845:414;27908:4;40319:17;;;:12;;;:17;;;;;;27925:327;;-1:-1:-1;27968:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;28151:18;;28129:19;;;:12;;;:19;;;;;;:40;;;;28184:11;;27925:327;-1:-1:-1;28235:5:0;28228:12;;37724:692;37800:4;37935:17;;;:12;;;:17;;;;;;37969:13;37965:444;;-1:-1:-1;;38054:38:0;;;;;;;;;;;;;;;;;;38036:57;;;;;;;;:12;:57;;;;;;;;;;;;;;;;;;;;;;;;38251:19;;38231:17;;;:12;;;:17;;;;;;;:39;38285:11;;37965:444;38365:5;38329:3;38342:12;38353:1;38342:8;:12;:::i;:::-;38329:26;;;;;;;;:::i;:::-;;;;;;;;;;;:33;;:41;;;;38392:5;38385:12;;;;;21819:195;21922:12;21954:52;21976:6;21984:4;21990:1;21993:12;21922;19268:20;;23115:60;;;;-1:-1:-1;;;23115:60:0;;25672:2:1;23115:60:0;;;25654:21:1;25711:2;25691:18;;;25684:30;25750:31;25730:18;;;25723:59;25799:18;;23115:60:0;25470:353:1;23115:60:0;23249:12;23263:23;23290:6;-1:-1:-1;;;;;23290:11:0;23310:5;23318:4;23290:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23248:75;;;;23341:52;23359:7;23368:10;23380:12;23341:17;:52::i;:::-;23334:59;22871:530;-1:-1:-1;;;;;;;22871:530:0:o;25411:742::-;25526:12;25555:7;25551:595;;;-1:-1:-1;25586:10:0;25579:17;;25551:595;25700:17;;:21;25696:439;;25963:10;25957:17;26024:15;26011:10;26007:2;26003:19;25996:44;25696:439;26106:12;26099:20;;-1:-1:-1;;;26099:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:::-;897:3;935:5;929:12;962:6;957:3;950:19;978:63;1034:6;1027:4;1022:3;1018:14;1011:4;1004:5;1000:16;978:63;:::i;:::-;1095:2;1074:15;-1:-1:-1;;1070:29:1;1061:39;;;;1102:4;1057:50;;855:258;-1:-1:-1;;855:258:1:o;1118:220::-;1267:2;1256:9;1249:21;1230:4;1287:45;1328:2;1317:9;1313:18;1305:6;1287:45;:::i;1343:127::-;1404:10;1399:3;1395:20;1392:1;1385:31;1435:4;1432:1;1425:15;1459:4;1456:1;1449:15;1475:275;1546:2;1540:9;1611:2;1592:13;;-1:-1:-1;;1588:27:1;1576:40;;1646:18;1631:34;;1667:22;;;1628:62;1625:88;;;1693:18;;:::i;:::-;1729:2;1722:22;1475:275;;-1:-1:-1;1475:275:1:o;1755:407::-;1820:5;1854:18;1846:6;1843:30;1840:56;;;1876:18;;:::i;:::-;1914:57;1959:2;1938:15;;-1:-1:-1;;1934:29:1;1965:4;1930:40;1914:57;:::i;:::-;1905:66;;1994:6;1987:5;1980:21;2034:3;2025:6;2020:3;2016:16;2013:25;2010:45;;;2051:1;2048;2041:12;2010:45;2100:6;2095:3;2088:4;2081:5;2077:16;2064:43;2154:1;2147:4;2138:6;2131:5;2127:18;2123:29;2116:40;1755:407;;;;;:::o;2167:451::-;2236:6;2289:2;2277:9;2268:7;2264:23;2260:32;2257:52;;;2305:1;2302;2295:12;2257:52;2345:9;2332:23;2378:18;2370:6;2367:30;2364:50;;;2410:1;2407;2400:12;2364:50;2433:22;;2486:4;2478:13;;2474:27;-1:-1:-1;2464:55:1;;2515:1;2512;2505:12;2464:55;2538:74;2604:7;2599:2;2586:16;2581:2;2577;2573:11;2538:74;:::i;2623:180::-;2682:6;2735:2;2723:9;2714:7;2710:23;2706:32;2703:52;;;2751:1;2748;2741:12;2703:52;-1:-1:-1;2774:23:1;;2623:180;-1:-1:-1;2623:180:1:o;3016:173::-;3084:20;;-1:-1:-1;;;;;3133:31:1;;3123:42;;3113:70;;3179:1;3176;3169:12;3194:254;3262:6;3270;3323:2;3311:9;3302:7;3298:23;3294:32;3291:52;;;3339:1;3336;3329:12;3291:52;3362:29;3381:9;3362:29;:::i;:::-;3352:39;3438:2;3423:18;;;;3410:32;;-1:-1:-1;;;3194:254:1:o;3635:186::-;3694:6;3747:2;3735:9;3726:7;3722:23;3718:32;3715:52;;;3763:1;3760;3753:12;3715:52;3786:29;3805:9;3786:29;:::i;3826:254::-;3894:6;3902;3955:2;3943:9;3934:7;3930:23;3926:32;3923:52;;;3971:1;3968;3961:12;3923:52;4007:9;3994:23;3984:33;;4036:38;4070:2;4059:9;4055:18;4036:38;:::i;:::-;4026:48;;3826:254;;;;;:::o;4085:328::-;4162:6;4170;4178;4231:2;4219:9;4210:7;4206:23;4202:32;4199:52;;;4247:1;4244;4237:12;4199:52;4270:29;4289:9;4270:29;:::i;:::-;4260:39;;4318:38;4352:2;4341:9;4337:18;4318:38;:::i;:::-;4308:48;;4403:2;4392:9;4388:18;4375:32;4365:42;;4085:328;;;;;:::o;4603:347::-;4668:6;4676;4729:2;4717:9;4708:7;4704:23;4700:32;4697:52;;;4745:1;4742;4735:12;4697:52;4768:29;4787:9;4768:29;:::i;:::-;4758:39;;4847:2;4836:9;4832:18;4819:32;4894:5;4887:13;4880:21;4873:5;4870:32;4860:60;;4916:1;4913;4906:12;4860:60;4939:5;4929:15;;;4603:347;;;;;:::o;4955:667::-;5050:6;5058;5066;5074;5127:3;5115:9;5106:7;5102:23;5098:33;5095:53;;;5144:1;5141;5134:12;5095:53;5167:29;5186:9;5167:29;:::i;:::-;5157:39;;5215:38;5249:2;5238:9;5234:18;5215:38;:::i;:::-;5205:48;;5300:2;5289:9;5285:18;5272:32;5262:42;;5355:2;5344:9;5340:18;5327:32;5382:18;5374:6;5371:30;5368:50;;;5414:1;5411;5404:12;5368:50;5437:22;;5490:4;5482:13;;5478:27;-1:-1:-1;5468:55:1;;5519:1;5516;5509:12;5468:55;5542:74;5608:7;5603:2;5590:16;5585:2;5581;5577:11;5542:74;:::i;:::-;5532:84;;;4955:667;;;;;;;:::o;5627:1082::-;5729:6;5737;5745;5798:2;5786:9;5777:7;5773:23;5769:32;5766:52;;;5814:1;5811;5804:12;5766:52;5850:9;5837:23;5827:33;;5879:2;5928;5917:9;5913:18;5900:32;5890:42;;5983:2;5972:9;5968:18;5955:32;6006:18;6047:2;6039:6;6036:14;6033:34;;;6063:1;6060;6053:12;6033:34;6101:6;6090:9;6086:22;6076:32;;6146:7;6139:4;6135:2;6131:13;6127:27;6117:55;;6168:1;6165;6158:12;6117:55;6204:2;6191:16;6226:2;6222;6219:10;6216:36;;;6232:18;;:::i;:::-;6278:2;6275:1;6271:10;6261:20;;6301:28;6325:2;6321;6317:11;6301:28;:::i;:::-;6363:15;;;6433:11;;;6429:20;;;6394:12;;;;6461:19;;;6458:39;;;6493:1;6490;6483:12;6458:39;6517:11;;;;6537:142;6553:6;6548:3;6545:15;6537:142;;;6619:17;;6607:30;;6570:12;;;;6657;;;;6537:142;;;6698:5;6688:15;;;;;;;;5627:1082;;;;;:::o;6714:260::-;6782:6;6790;6843:2;6831:9;6822:7;6818:23;6814:32;6811:52;;;6859:1;6856;6849:12;6811:52;6882:29;6901:9;6882:29;:::i;:::-;6872:39;;6930:38;6964:2;6953:9;6949:18;6930:38;:::i;6979:380::-;7058:1;7054:12;;;;7101;;;7122:61;;7176:4;7168:6;7164:17;7154:27;;7122:61;7229:2;7221:6;7218:14;7198:18;7195:38;7192:161;;;7275:10;7270:3;7266:20;7263:1;7256:31;7310:4;7307:1;7300:15;7338:4;7335:1;7328:15;7192:161;;6979:380;;;:::o;7364:356::-;7566:2;7548:21;;;7585:18;;;7578:30;7644:34;7639:2;7624:18;;7617:62;7711:2;7696:18;;7364:356::o;8965:::-;9167:2;9149:21;;;9186:18;;;9179:30;9245:34;9240:2;9225:18;;9218:62;9312:2;9297:18;;8965:356::o;9736:127::-;9797:10;9792:3;9788:20;9785:1;9778:31;9828:4;9825:1;9818:15;9852:4;9849:1;9842:15;9868:128;9908:3;9939:1;9935:6;9932:1;9929:13;9926:39;;;9945:18;;:::i;:::-;-1:-1:-1;9981:9:1;;9868:128::o;10001:135::-;10040:3;-1:-1:-1;;10061:17:1;;10058:43;;;10081:18;;:::i;:::-;-1:-1:-1;10128:1:1;10117:13;;10001:135::o;10141:413::-;10343:2;10325:21;;;10382:2;10362:18;;;10355:30;10421:34;10416:2;10401:18;;10394:62;-1:-1:-1;;;10487:2:1;10472:18;;10465:47;10544:3;10529:19;;10141:413::o;11249:125::-;11289:4;11317:1;11314;11311:8;11308:34;;;11322:18;;:::i;:::-;-1:-1:-1;11359:9:1;;11249:125::o;15125:470::-;15304:3;15342:6;15336:13;15358:53;15404:6;15399:3;15392:4;15384:6;15380:17;15358:53;:::i;:::-;15474:13;;15433:16;;;;15496:57;15474:13;15433:16;15530:4;15518:17;;15496:57;:::i;:::-;15569:20;;15125:470;-1:-1:-1;;;;15125:470:1:o;19486:168::-;19526:7;19592:1;19588;19584:6;19580:14;19577:1;19574:21;19569:1;19562:9;19555:17;19551:45;19548:71;;;19599:18;;:::i;:::-;-1:-1:-1;19639:9:1;;19486:168::o;19659:127::-;19720:10;19715:3;19711:20;19708:1;19701:31;19751:4;19748:1;19741:15;19775:4;19772:1;19765:15;19791:120;19831:1;19857;19847:35;;19862:18;;:::i;:::-;-1:-1:-1;19896:9:1;;19791:120::o;21032:414::-;21234:2;21216:21;;;21273:2;21253:18;;;21246:30;21312:34;21307:2;21292:18;;21285:62;-1:-1:-1;;;21378:2:1;21363:18;;21356:48;21436:3;21421:19;;21032:414::o;21815:127::-;21876:10;21871:3;21867:20;21864:1;21857:31;21907:4;21904:1;21897:15;21931:4;21928:1;21921:15;22199:197;22237:3;22265:6;22306:2;22299:5;22295:14;22333:2;22324:7;22321:15;22318:41;;;22339:18;;:::i;:::-;22388:1;22375:15;;22199:197;-1:-1:-1;;;22199:197:1:o;22401:112::-;22433:1;22459;22449:35;;22464:18;;:::i;:::-;-1:-1:-1;22498:9:1;;22401:112::o;22518:136::-;22557:3;22585:5;22575:39;;22594:18;;:::i;:::-;-1:-1:-1;;;22630:18:1;;22518:136::o;23465:489::-;-1:-1:-1;;;;;23734:15:1;;;23716:34;;23786:15;;23781:2;23766:18;;23759:43;23833:2;23818:18;;23811:34;;;23881:3;23876:2;23861:18;;23854:31;;;23659:4;;23902:46;;23928:19;;23920:6;23902:46;:::i;:::-;23894:54;23465:489;-1:-1:-1;;;;;;23465:489:1:o;23959:249::-;24028:6;24081:2;24069:9;24060:7;24056:23;24052:32;24049:52;;;24097:1;24094;24087:12;24049:52;24129:9;24123:16;24148:30;24172:5;24148:30;:::i;24931:127::-;24992:10;24987:3;24983:20;24980:1;24973:31;25023:4;25020:1;25013:15;25047:4;25044:1;25037:15;25828:274;25957:3;25995:6;25989:13;26011:53;26057:6;26052:3;26045:4;26037:6;26033:17;26011:53;:::i;:::-;26080:16;;;;;25828:274;-1:-1:-1;;25828:274:1:o

Swarm Source

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