ETH Price: $3,714.29 (+4.76%)

Token

ERC-20: Rainbow Nova (RNBW)
 

Overview

Max Total Supply

134 RNBW

Holders

131

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
youlovetoseeit.eth
Balance
1 RNBW
0x7c1348c2df1b801a756e23693ee5e619e4d4a709
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:
RainbowNova

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

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

// Rainbow Nova, generative art stored on Ethereum Blockchain


// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/Strings.sol



pragma solidity ^0.8.0;

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

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

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

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

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

}

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/EnumerableMap.sol




pragma solidity ^0.8.0;

/**
 * @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: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/EnumerableSet.sol




pragma solidity ^0.8.0;

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

    struct Set {
        // Storage of set values
        bytes32[] _values;

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

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

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

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

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

            // 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: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/Address.sol




pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // 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: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/introspection/ERC165.sol


pragma solidity ^0.8.0;

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

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol


pragma solidity ^0.8.0;


/**
 * @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 {
    /**
     * @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(type(IERC165).interfaceId);
    }

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




pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

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

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

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


pragma solidity ^0.8.0;

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

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC721/IERC721Enumerable.sol




pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

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

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

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC721/IERC721Metadata.sol




pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {

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

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

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

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/introspection/IERC165.sol



// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/Context.sol




pragma solidity ^0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN 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: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol




pragma solidity ^0.8.0;











/**
 * @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 Address for address;
    using EnumerableSet for EnumerableSet.UintSet;
    using EnumerableMap for EnumerableMap.UintToAddressMap;
    using Strings for uint256;
    
    // 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;

    /**
     * @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(type(IERC721).interfaceId);
        _registerInterface(type(IERC721Metadata).interfaceId);
        _registerInterface(type(IERC721Enumerable).interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _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()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver(to).onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    // solhint-disable-next-line no-inline-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    function _approve(address to, uint256 tokenId) private {
        _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: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/access/Ownable.sol




pragma solidity ^0.8.0;

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

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



    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () {
        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: https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/math/SafeMath.sol




pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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






pragma solidity ^0.8.0;


// SPDX-License-Identifier: UNLICENSED

contract RainbowNova is ERC721, Ownable {
    using SafeMath for uint256;
    using Strings for uint256;
    bool public hasSaleStarted = false;
    string public METADATA_PROVENANCE_HASH = "";
    string public GENERATOR_ADDRESS = "https://chainrings.art/generator2/";
    string public IPFS_GENERATOR_ADDRESS = "";
    string public script = "";
    mapping(address => bool) public addresses;
    mapping(uint => address) public creators;
    
    constructor() ERC721("Rainbow Nova","RNBW")  {
        setBaseURI("");
        script = 'class Random{constructor(e){this.seed=e}random_dec(){return this.seed^=this.seed<<13,this.seed^=this.seed>>17,this.seed^=this.seed<<5,(this.seed<0?1+~this.seed:this.seed)%1e3/1e3}random_between(e,a){return e+(a-e)*this.random_dec()}random_int(e,a){return Math.floor(this.random_between(e,a+1))}random_choice(e){return e[Math.floor(this.random_between(0,.99*e.length))]}}let WH=Math.min(window.innerWidth,window.innerHeight),WIDTH=WH,HEIGHT=WH,seed=parseInt(window.tokenHash.slice(0,16),16),rng=new Random(seed),palettes=["c41e3d-7d1128-ff2c55-3c0919-e2294f","ba7ba1-c28cae-d0aba0-dec4a1-edcf8e","0c0a3e-7b1e7a-b33f62-f9564f-f3c677","0267c1-0075c4-efa00b-d65108-591f0a","f4e409-eeba0b-c36f09-a63c06-710000","63bc46-51a443-3f9140-2c803d-167039","68c8c7-55abaa-419594-2c8280-11706e","6a88c5-586ea7-475991-36457e-27316d","b8b8d1-5b5f97-ffc145-fffffb-ff6b6c","0d1b1e-7798ab-c3dbc5-e8dcb9-f2cee6","ef798a-f7a9a8-7d82b8-613f75-e5c3d1","fee38b-dab69e-85d1d4-90aec7-9e69ac","0a369d-4472ca-5e7ce2-92b4f4-cfdee7","545f66-829399-d0f4ea-e8fcc2-b1cc74","231f20-bb4430-7ebdc2-f3dfa2-efe6dd","9b5de5-f15bb5-fee440-00bbf9-00f5d4","bce7fd-c492b1-af3b6e-424651-21fa90","e4572e-29335c-f3a712-a8c686-669bbc","1be7ff-6eeb83-e4ff1a-e8aa14-ff5714","acadbc-9b9ece-6665dd-473bf0-000500","2a2b2a-706c61-f8f4e3-e5446d-ff8966","c6d4ff-7a82ab-307473-12664f-2dc2bd","861388-e15a97-eeabc4-c799a6-4b2840"].map(e=>e.split("-").map(e=>"#"+e)),palette=rng.random_choice(palettes),W_=WIDTH,colors=[],rows=rng.random_int(12,32),cols=rows,ratioR=parseInt(W_/rows/2),ratioC=ratioR,glitchAmount=.4,shapes=[],shapeColors=[],pframe=0,cubeChance=rng.random_between(0,1),tanorsin=rng.random_between(0,1);function setup(){pixelDensity(1),rectMode(CENTER),noiseSeed(seed),colorMode(HSL),frameRate(30),canva$=createCanvas(WIDTH,HEIGHT,WEBGL),glitch=new Glitch,glitch.pixelate(glitchAmount),noStroke();for(let e=0;e<rows;e++)for(let e=0;e<cols;e++)shapes.push(rng.random_between(0,1)),colors.push(rng.random_choice(palette));perspective(PI/3,width/height,.1,5e3)}let lastStroke,lastScale=0,currentScale=0,paletteWOPalette=palette.slice(0,3);function draw(){if(orbitControl(),!mouseIsPressed)if(tanorsin>.8){let e=map(tan(frameCount/100),-1,1,0,100);camera(0,e,300,0,0,0,0,1,0)}else{let e=map(sin(frameCount/100),-1,1,0,100);camera(0,e,300,0,0,0,0,1,0)}for(let e=0;e<rows;e++){push(),translate(0,0,25),currentScale<lastScale?fill(palette[0]):(currentScale=sin(radians(frameCount))/8,scale(currentScale),rotateX(radians(-frameCount)),rotateY(radians(frameCount)),rotateZ(radians(frameCount)),frameCount%10==0?(lastStroke=rng.random_choice(paletteWOPalette),stroke(lastStroke)):(lastStroke||(lastStroke=rng.random_choice(paletteWOPalette)),stroke(lastStroke)),fill(palette[4]),cubeChance>.9?(strokeWeight(1),box(W_/1.5)):(strokeWeight(1),sphere(W_/1.5))),lastScale=parseFloat(currentScale),pop();for(let a=0;a<cols;a++){let t=shapes[e*a];push(),rotateZ(frameCount*a/255),translate(-W_/2+ratioR*e+radians(frameCount/5),-W_/2+ratioC*a+radians(frameCount/5)),scale(sin(2*radians(frameCount/5))),fill(colors[e*a]),t>.25?box(ratioR):t>.1?cone(ratioR,1.5*ratioR):sphere(ratioR),pop()}}mouseIsPressed?(stroke(0),strokeWeight(pframe/10),pframe++):(strokeWeight(pframe>0?pframe/5:1),pframe>0?pframe--:noStroke())}';
    }
    
    function tokensOfOwner(address _owner) external view returns(uint256[] memory ) {
        uint256 tokenCount = balanceOf(_owner);
        if (tokenCount == 0) {
            // Return an empty array
            return new uint256[](0);
        } else {
            uint256[] memory result = new uint256[](tokenCount);
            uint256 index;
            for (index = 0; index < tokenCount; index++) {
                result[index] = tokenOfOwnerByIndex(_owner, index);
            }
            return result;
        }
    }
    
    function claim() external {
            require(addresses[msg.sender], "cannot claim");
            addresses[msg.sender] = false;
            
            uint mintIndex = totalSupply();
            creators[mintIndex] = msg.sender;
            _safeMint(msg.sender, mintIndex);
    }
    
    bool isOver = false;
    
    function setAddresses(address[] memory a) external onlyOwner {
        require(!isOver, "over");
        for(uint i = 0; i< a.length; i++) {
            addresses[a[i]] = true;
        }
    }
    
    function over() external onlyOwner {
        isOver = true;
    }

    
    // ONLYOWNER FUNCTIONS
    function setProvenanceHash(string memory _hash) public onlyOwner {
        METADATA_PROVENANCE_HASH = _hash;
    }
    
    function setGeneratorIPFSHash(string memory _hash) public onlyOwner {
        IPFS_GENERATOR_ADDRESS = _hash;
    }
    
    function setGeneratorAddress(string memory text) public onlyOwner {
        GENERATOR_ADDRESS = text;
    }
    
    function setBaseURI(string memory baseURI) public onlyOwner {
        _setBaseURI(baseURI);
    }
 
    
    function startDrop() public onlyOwner {
        hasSaleStarted = true;
    }
    
    function pauseDrop() public onlyOwner {
        hasSaleStarted = false;
    }
    
    function withdrawAll() public payable onlyOwner {
        require(payable(msg.sender).send(address(this).balance));
    }
    
    function tokenHash(uint256 tokenId) public view returns(bytes32){
        require(_exists(tokenId), "DOES NOT EXIST");
        return bytes32(keccak256(abi.encodePacked(address(this), creators[tokenId], tokenId)));
    }
    
    function generatorAddress(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "DOES NOT EXIST");
        return string(abi.encodePacked(GENERATOR_ADDRESS, tokenId.toString()));
    }
    
    function IPFSgeneratorAddress(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "DOES NOT EXIST");
        return string(abi.encodePacked(IPFS_GENERATOR_ADDRESS, tokenId.toString()));
    }
}

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"},{"inputs":[],"name":"GENERATOR_ADDRESS","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IPFS_GENERATOR_ADDRESS","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"IPFSgeneratorAddress","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"METADATA_PROVENANCE_HASH","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addresses","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"creators","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"generatorAddress","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":[],"name":"hasSaleStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"over","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseDrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"script","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"a","type":"address[]"}],"name":"setAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"text","type":"string"}],"name":"setGeneratorAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_hash","type":"string"}],"name":"setGeneratorIPFSHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_hash","type":"string"}],"name":"setProvenanceHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startDrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":[{"internalType":"address","name":"_owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"payable","type":"function"}]

600a805460ff60a01b1916905560a06040819052600060808190526200002891600b9162000311565b5060405180606001604052806022815260200162002bd06022913980516200005991600c9160209091019062000311565b506040805160208101918290526000908190526200007a91600d9162000311565b506040805160208101918290526000908190526200009b91600e9162000311565b506011805460ff19169055348015620000b357600080fd5b506040518060400160405280600c81526020016b5261696e626f77204e6f766160a01b81525060405180604001604052806004815260200163524e425760e01b8152506200010e6301ffc9a760e01b6200020960201b60201c565b81516200012390600690602085019062000311565b5080516200013990600790602084019062000311565b506200014c6380ac58cd60e01b62000209565b6200015e635b5e139f60e01b62000209565b6200017063780e9d6360e01b62000209565b5050600a80546001600160a01b0319163390811790915560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350604080516020810190915260008152620001cf906200028e565b60405180610ce00160405280610cb4815260200162002bf2610cb4913980516200020291600e9160209091019062000311565b50620003f4565b6001600160e01b03198082161415620002695760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e746572666163652069640000000060448201526064015b60405180910390fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b600a546001600160a01b03163314620002ea5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000260565b620002f581620002f8565b50565b80516200030d90600990602084019062000311565b5050565b8280546200031f90620003b7565b90600052602060002090601f0160209004810192826200034357600085556200038e565b82601f106200035e57805160ff19168380011785556200038e565b828001600101855582156200038e579182015b828111156200038e57825182559160200191906001019062000371565b506200039c929150620003a0565b5090565b5b808211156200039c5760008155600101620003a1565b600181811c90821680620003cc57607f821691505b60208210811415620003ee57634e487b7160e01b600052602260045260246000fd5b50919050565b6127cc80620004046000396000f3fe6080604052600436106102465760003560e01c8063715018a611610139578063a22cb465116100b6578063c87b56dd1161007a578063c87b56dd1461069a578063cd53d08e146106ba578063e985e9c5146106f0578063ebe9eb9f14610739578063f0c9dc601461074e578063f2fde38b1461076357600080fd5b8063a22cb465146105fa578063a38643971461061a578063a8f14af61461063a578063b88d4fde1461065a578063b95717211461067a57600080fd5b8063853828b6116100fd578063853828b61461057f578063891cc177146105875780638da5cb5b146105a757806395d89b41146105c55780639758e904146105da57600080fd5b8063715018a6146104e3578063753853c1146104f85780637eaef50c1461050d57806382d38954146105225780638462151c1461055257600080fd5b80632f745c59116101c757806355f804b31161018b57806355f804b31461044e5780636352211e1461046e57806363d969411461048e5780636c0360eb146104ae57806370a08231146104c357600080fd5b80632f745c59146103c457806334d84c7b146103e457806342842e0e146103f95780634e71d92d146104195780634f6ccce71461042e57600080fd5b806318160ddd1161020e57806318160ddd146103365780631c8b232d1461035957806323b872dd1461037a5780632808c92c1461039a5780632ee2ac36146103af57600080fd5b806301ffc9a71461024b57806306fdde031461029a578063081812fc146102bc578063095ea7b3146102f45780631096952314610316575b600080fd5b34801561025757600080fd5b50610285610266366004612297565b6001600160e01b03191660009081526020819052604090205460ff1690565b60405190151581526020015b60405180910390f35b3480156102a657600080fd5b506102af610783565b60405161029191906124d2565b3480156102c857600080fd5b506102dc6102d736600461231a565b610815565b6040516001600160a01b039091168152602001610291565b34801561030057600080fd5b5061031461030f3660046121b9565b6108a2565b005b34801561032257600080fd5b506103146103313660046122d1565b6109b8565b34801561034257600080fd5b5061034b6109f9565b604051908152602001610291565b34801561036557600080fd5b50600a5461028590600160a01b900460ff1681565b34801561038657600080fd5b506103146103953660046120c5565b610a0a565b3480156103a657600080fd5b50610314610a3b565b3480156103bb57600080fd5b506102af610a74565b3480156103d057600080fd5b5061034b6103df3660046121b9565b610b02565b3480156103f057600080fd5b50610314610b2d565b34801561040557600080fd5b506103146104143660046120c5565b610b6c565b34801561042557600080fd5b50610314610b87565b34801561043a57600080fd5b5061034b61044936600461231a565b610c25565b34801561045a57600080fd5b506103146104693660046122d1565b610c3b565b34801561047a57600080fd5b506102dc61048936600461231a565b610c6e565b34801561049a57600080fd5b506102af6104a936600461231a565b610c96565b3480156104ba57600080fd5b506102af610cef565b3480156104cf57600080fd5b5061034b6104de366004612077565b610cfe565b3480156104ef57600080fd5b50610314610d8a565b34801561050457600080fd5b506102af610dfe565b34801561051957600080fd5b50610314610e0b565b34801561052e57600080fd5b5061028561053d366004612077565b600f6020526000908152604090205460ff1681565b34801561055e57600080fd5b5061057261056d366004612077565b610e44565b604051610291919061248e565b610314610eff565b34801561059357600080fd5b506103146105a23660046122d1565b610f4f565b3480156105b357600080fd5b50600a546001600160a01b03166102dc565b3480156105d157600080fd5b506102af610f8c565b3480156105e657600080fd5b506102af6105f536600461231a565b610f9b565b34801561060657600080fd5b5061031461061536600461217d565b610fcd565b34801561062657600080fd5b5061034b61063536600461231a565b611092565b34801561064657600080fd5b506103146106553660046122d1565b611116565b34801561066657600080fd5b50610314610675366004612101565b611153565b34801561068657600080fd5b506103146106953660046121e3565b61118b565b3480156106a657600080fd5b506102af6106b536600461231a565b611259565b3480156106c657600080fd5b506102dc6106d536600461231a565b6010602052600090815260409020546001600160a01b031681565b3480156106fc57600080fd5b5061028561070b366004612092565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561074557600080fd5b506102af6113cb565b34801561075a57600080fd5b506102af6113d8565b34801561076f57600080fd5b5061031461077e366004612077565b6113e5565b60606006805461079290612685565b80601f01602080910402602001604051908101604052809291908181526020018280546107be90612685565b801561080b5780601f106107e05761010080835404028352916020019161080b565b820191906000526020600020905b8154815290600101906020018083116107ee57829003601f168201915b5050505050905090565b6000610820826114d0565b6108865760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006108ad82610c6e565b9050806001600160a01b0316836001600160a01b0316141561091b5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161087d565b336001600160a01b03821614806109375750610937813361070b565b6109a95760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161087d565b6109b383836114dd565b505050565b600a546001600160a01b031633146109e25760405162461bcd60e51b815260040161087d90612537565b80516109f590600b906020840190611f6a565b5050565b6000610a05600261154b565b905090565b610a143382611555565b610a305760405162461bcd60e51b815260040161087d9061256c565b6109b383838361163f565b600a546001600160a01b03163314610a655760405162461bcd60e51b815260040161087d90612537565b600a805460ff60a01b19169055565b600c8054610a8190612685565b80601f0160208091040260200160405190810160405280929190818152602001828054610aad90612685565b8015610afa5780601f10610acf57610100808354040283529160200191610afa565b820191906000526020600020905b815481529060010190602001808311610add57829003601f168201915b505050505081565b6001600160a01b0382166000908152600160205260408120610b2490836117c0565b90505b92915050565b600a546001600160a01b03163314610b575760405162461bcd60e51b815260040161087d90612537565b600a805460ff60a01b1916600160a01b179055565b6109b383838360405180602001604052806000815250611153565b336000908152600f602052604090205460ff16610bd55760405162461bcd60e51b815260206004820152600c60248201526b63616e6e6f7420636c61696d60a01b604482015260640161087d565b336000908152600f60205260408120805460ff19169055610bf46109f9565b600081815260106020526040902080546001600160a01b03191633908117909155909150610c2290826117cc565b50565b600080610c336002846117e6565b509392505050565b600a546001600160a01b03163314610c655760405162461bcd60e51b815260040161087d90612537565b610c2281611802565b6000610b278260405180606001604052806029815260200161276e6029913960029190611815565b6060610ca1826114d0565b610cbd5760405162461bcd60e51b815260040161087d906125bd565b600c610cc88361182c565b604051602001610cd99291906123aa565b6040516020818303038152906040529050919050565b60606009805461079290612685565b60006001600160a01b038216610d695760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161087d565b6001600160a01b0382166000908152600160205260409020610b279061154b565b600a546001600160a01b03163314610db45760405162461bcd60e51b815260040161087d90612537565b600a546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600a80546001600160a01b0319169055565b600d8054610a8190612685565b600a546001600160a01b03163314610e355760405162461bcd60e51b815260040161087d90612537565b6011805460ff19166001179055565b60606000610e5183610cfe565b905080610e6e576040805160008082526020820190925290610c33565b60008167ffffffffffffffff811115610e8957610e89612741565b604051908082528060200260200182016040528015610eb2578160200160208202803683370190505b50905060005b82811015610c3357610eca8582610b02565b828281518110610edc57610edc61272b565b602090810291909101015280610ef1816126ba565b915050610eb8565b50919050565b600a546001600160a01b03163314610f295760405162461bcd60e51b815260040161087d90612537565b60405133904780156108fc02916000818181858888f19350505050610f4d57600080fd5b565b600a546001600160a01b03163314610f795760405162461bcd60e51b815260040161087d90612537565b80516109f590600d906020840190611f6a565b60606007805461079290612685565b6060610fa6826114d0565b610fc25760405162461bcd60e51b815260040161087d906125bd565b600d610cc88361182c565b6001600160a01b0382163314156110265760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161087d565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600061109d826114d0565b6110b95760405162461bcd60e51b815260040161087d906125bd565b506000818152601060209081526040918290205482516bffffffffffffffffffffffff1930606090811b8216838601529290921b909116603482015260488082019490945282518082039094018452606801909152815191012090565b600a546001600160a01b031633146111405760405162461bcd60e51b815260040161087d90612537565b80516109f590600c906020840190611f6a565b61115d3383611555565b6111795760405162461bcd60e51b815260040161087d9061256c565b6111858484848461192a565b50505050565b600a546001600160a01b031633146111b55760405162461bcd60e51b815260040161087d90612537565b60115460ff16156111f15760405162461bcd60e51b815260040161087d9060208082526004908201526337bb32b960e11b604082015260600190565b60005b81518110156109f5576001600f60008484815181106112155761121561272b565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580611251816126ba565b9150506111f4565b6060611264826114d0565b6112c85760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b606482015260840161087d565b600082815260086020526040812080546112e190612685565b80601f016020809104026020016040519081016040528092919081815260200182805461130d90612685565b801561135a5780601f1061132f5761010080835404028352916020019161135a565b820191906000526020600020905b81548152906001019060200180831161133d57829003601f168201915b50505050509050600061136b610cef565b905080516000141561137e575092915050565b8151156113b057808260405160200161139892919061237b565b60405160208183030381529060405292505050919050565b806113ba8561182c565b60405160200161139892919061237b565b600e8054610a8190612685565b600b8054610a8190612685565b600a546001600160a01b0316331461140f5760405162461bcd60e51b815260040161087d90612537565b6001600160a01b0381166114745760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161087d565b600a546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610b2760028361195d565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061151282610c6e565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610b27825490565b6000611560826114d0565b6115c15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161087d565b60006115cc83610c6e565b9050806001600160a01b0316846001600160a01b031614806116075750836001600160a01b03166115fc84610815565b6001600160a01b0316145b8061163757506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661165282610c6e565b6001600160a01b0316146116ba5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161087d565b6001600160a01b03821661171c5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161087d565b6117276000826114dd565b6001600160a01b03831660009081526001602052604090206117499082611975565b506001600160a01b038216600090815260016020526040902061176c9082611981565b506117796002828461198d565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000610b2483836119a3565b6109f5828260405180602001604052806000815250611a29565b60008080806117f58686611a5c565b9097909650945050505050565b80516109f5906009906020840190611f6a565b6000611822848484611af9565b90505b9392505050565b6060816118505750506040805180820190915260018152600360fc1b602082015290565b8160005b811561187a5780611864816126ba565b91506118739050600a8361262e565b9150611854565b60008167ffffffffffffffff81111561189557611895612741565b6040519080825280601f01601f1916602001820160405280156118bf576020820181803683370190505b5090505b8415611637576118d4600183612642565b91506118e1600a866126d5565b6118ec906030612616565b60f81b8183815181106119015761190161272b565b60200101906001600160f81b031916908160001a905350611923600a8661262e565b94506118c3565b61193584848461163f565b61194184848484611b62565b6111855760405162461bcd60e51b815260040161087d906124e5565b60008181526001830160205260408120541515610b24565b6000610b248383611c6f565b6000610b248383611d62565b600061182284846001600160a01b038516611db1565b81546000908210611a015760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b606482015260840161087d565b826000018281548110611a1657611a1661272b565b9060005260206000200154905092915050565b611a338383611e52565b611a406000848484611b62565b6109b35760405162461bcd60e51b815260040161087d906124e5565b815460009081908310611abc5760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604482015261647360f01b606482015260840161087d565b6000846000018481548110611ad357611ad361272b565b906000526020600020906002020190508060000154816001015492509250509250929050565b60008281526001840160205260408120548281611b295760405162461bcd60e51b815260040161087d91906124d2565b5084611b36600183612642565b81548110611b4657611b4661272b565b9060005260206000209060020201600101549150509392505050565b60006001600160a01b0384163b15611c6457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611ba6903390899088908890600401612451565b602060405180830381600087803b158015611bc057600080fd5b505af1925050508015611bf0575060408051601f3d908101601f19168201909252611bed918101906122b4565b60015b611c4a573d808015611c1e576040519150601f19603f3d011682016040523d82523d6000602084013e611c23565b606091505b508051611c425760405162461bcd60e51b815260040161087d906124e5565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611637565b506001949350505050565b60008181526001830160205260408120548015611d58576000611c93600183612642565b8554909150600090611ca790600190612642565b90506000866000018281548110611cc057611cc061272b565b9060005260206000200154905080876000018481548110611ce357611ce361272b565b600091825260209091200155611cfa836001612616565b60008281526001890160205260409020558654879080611d1c57611d1c612715565b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610b27565b6000915050610b27565b6000818152600183016020526040812054611da957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610b27565b506000610b27565b600082815260018401602052604081205480611e16575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055611825565b8285611e23600184612642565b81548110611e3357611e3361272b565b9060005260206000209060020201600101819055506000915050611825565b6001600160a01b038216611ea85760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161087d565b611eb1816114d0565b15611efe5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161087d565b6001600160a01b0382166000908152600160205260409020611f209082611981565b50611f2d6002828461198d565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b828054611f7690612685565b90600052602060002090601f016020900481019282611f985760008555611fde565b82601f10611fb157805160ff1916838001178555611fde565b82800160010185558215611fde579182015b82811115611fde578251825591602001919060010190611fc3565b50611fea929150611fee565b5090565b5b80821115611fea5760008155600101611fef565b600067ffffffffffffffff83111561201d5761201d612741565b612030601f8401601f19166020016125e5565b905082815283838301111561204457600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b038116811461207257600080fd5b919050565b60006020828403121561208957600080fd5b610b248261205b565b600080604083850312156120a557600080fd5b6120ae8361205b565b91506120bc6020840161205b565b90509250929050565b6000806000606084860312156120da57600080fd5b6120e38461205b565b92506120f16020850161205b565b9150604084013590509250925092565b6000806000806080858703121561211757600080fd5b6121208561205b565b935061212e6020860161205b565b925060408501359150606085013567ffffffffffffffff81111561215157600080fd5b8501601f8101871361216257600080fd5b61217187823560208401612003565b91505092959194509250565b6000806040838503121561219057600080fd5b6121998361205b565b9150602083013580151581146121ae57600080fd5b809150509250929050565b600080604083850312156121cc57600080fd5b6121d58361205b565b946020939093013593505050565b600060208083850312156121f657600080fd5b823567ffffffffffffffff8082111561220e57600080fd5b818501915085601f83011261222257600080fd5b81358181111561223457612234612741565b8060051b91506122458483016125e5565b8181528481019084860184860187018a101561226057600080fd5b600095505b8386101561228a576122768161205b565b835260019590950194918601918601612265565b5098975050505050505050565b6000602082840312156122a957600080fd5b813561182581612757565b6000602082840312156122c657600080fd5b815161182581612757565b6000602082840312156122e357600080fd5b813567ffffffffffffffff8111156122fa57600080fd5b8201601f8101841361230b57600080fd5b61163784823560208401612003565b60006020828403121561232c57600080fd5b5035919050565b6000815180845261234b816020860160208601612659565b601f01601f19169290920160200192915050565b60008151612371818560208601612659565b9290920192915050565b6000835161238d818460208801612659565b8351908301906123a1818360208801612659565b01949350505050565b600080845481600182811c9150808316806123c657607f831692505b60208084108214156123e657634e487b7160e01b86526022600452602486fd5b8180156123fa576001811461240b57612438565b60ff19861689528489019650612438565b60008b81526020902060005b868110156124305781548b820152908501908301612417565b505084890196505b505050505050612448818561235f565b95945050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061248490830184612333565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156124c6578351835292840192918401916001016124aa565b50909695505050505050565b602081526000610b246020830184612333565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252600e908201526d1113d154c81393d50811561254d560921b604082015260600190565b604051601f8201601f1916810167ffffffffffffffff8111828210171561260e5761260e612741565b604052919050565b60008219821115612629576126296126e9565b500190565b60008261263d5761263d6126ff565b500490565b600082821015612654576126546126e9565b500390565b60005b8381101561267457818101518382015260200161265c565b838111156111855750506000910152565b600181811c9082168061269957607f821691505b60208210811415610ef957634e487b7160e01b600052602260045260246000fd5b60006000198214156126ce576126ce6126e9565b5060010190565b6000826126e4576126e46126ff565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610c2257600080fdfe4552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea264697066735822122038cb190f2d1f50aa2e181a49379fa19d040c142a914f85b8d390658918ea792964736f6c6343000807003368747470733a2f2f636861696e72696e67732e6172742f67656e657261746f72322f636c6173732052616e646f6d7b636f6e7374727563746f722865297b746869732e736565643d657d72616e646f6d5f64656328297b72657475726e20746869732e736565645e3d746869732e736565643c3c31332c746869732e736565645e3d746869732e736565643e3e31372c746869732e736565645e3d746869732e736565643c3c352c28746869732e736565643c303f312b7e746869732e736565643a746869732e7365656429253165332f3165337d72616e646f6d5f6265747765656e28652c61297b72657475726e20652b28612d65292a746869732e72616e646f6d5f64656328297d72616e646f6d5f696e7428652c61297b72657475726e204d6174682e666c6f6f7228746869732e72616e646f6d5f6265747765656e28652c612b3129297d72616e646f6d5f63686f6963652865297b72657475726e20655b4d6174682e666c6f6f7228746869732e72616e646f6d5f6265747765656e28302c2e39392a652e6c656e67746829295d7d7d6c65742057483d4d6174682e6d696e2877696e646f772e696e6e657257696474682c77696e646f772e696e6e6572486569676874292c57494454483d57482c4845494748543d57482c736565643d7061727365496e742877696e646f772e746f6b656e486173682e736c69636528302c3136292c3136292c726e673d6e65772052616e646f6d2873656564292c70616c65747465733d5b226334316533642d3764313132382d6666326335352d3363303931392d653232393466222c226261376261312d6332386361652d6430616261302d6465633461312d656463663865222c223063306133652d3762316537612d6233336636322d6639353634662d663363363737222c223032363763312d3030373563342d6566613030622d6436353130382d353931663061222c226634653430392d6565626130622d6333366630392d6136336330362d373130303030222c223633626334362d3531613434332d3366393134302d3263383033642d313637303339222c223638633863372d3535616261612d3431393539342d3263383238302d313137303665222c223661383863352d3538366561372d3437353939312d3336343537652d323733313664222c226238623864312d3562356639372d6666633134352d6666666666622d666636623663222c223064316231652d3737393861622d6333646263352d6538646362392d663263656536222c226566373938612d6637613961382d3764383262382d3631336637352d653563336431222c226665653338622d6461623639652d3835643164342d3930616563372d396536396163222c223061333639642d3434373263612d3565376365322d3932623466342d636664656537222c223534356636362d3832393339392d6430663465612d6538666363322d623163633734222c223233316632302d6262343433302d3765626463322d6633646661322d656665366464222c223962356465352d6631356262352d6665653434302d3030626266392d303066356434222c226263653766642d6334393262312d6166336236652d3432343635312d323166613930222c226534353732652d3239333335632d6633613731322d6138633638362d363639626263222c223162653766662d3665656238332d6534666631612d6538616131342d666635373134222c226163616462632d3962396563652d3636363564642d3437336266302d303030353030222c223261326232612d3730366336312d6638663465332d6535343436642d666638393636222c226336643466662d3761383261622d3330373437332d3132363634662d326463326264222c223836313338382d6531356139372d6565616263342d6337393961362d346232383430225d2e6d617028653d3e652e73706c697428222d22292e6d617028653d3e2223222b6529292c70616c657474653d726e672e72616e646f6d5f63686f6963652870616c6574746573292c575f3d57494454482c636f6c6f72733d5b5d2c726f77733d726e672e72616e646f6d5f696e742831322c3332292c636f6c733d726f77732c726174696f523d7061727365496e7428575f2f726f77732f32292c726174696f433d726174696f522c676c69746368416d6f756e743d2e342c7368617065733d5b5d2c7368617065436f6c6f72733d5b5d2c706672616d653d302c637562654368616e63653d726e672e72616e646f6d5f6265747765656e28302c31292c74616e6f7273696e3d726e672e72616e646f6d5f6265747765656e28302c31293b66756e6374696f6e20736574757028297b706978656c44656e736974792831292c726563744d6f64652843454e544552292c6e6f697365536565642873656564292c636f6c6f724d6f64652848534c292c6672616d6552617465283330292c63616e7661243d63726561746543616e7661732857494454482c4845494748542c574542474c292c676c697463683d6e657720476c697463682c676c697463682e706978656c61746528676c69746368416d6f756e74292c6e6f5374726f6b6528293b666f72286c657420653d303b653c726f77733b652b2b29666f72286c657420653d303b653c636f6c733b652b2b297368617065732e7075736828726e672e72616e646f6d5f6265747765656e28302c3129292c636f6c6f72732e7075736828726e672e72616e646f6d5f63686f6963652870616c6574746529293b70657273706563746976652850492f332c77696474682f6865696768742c2e312c356533297d6c6574206c6173745374726f6b652c6c6173745363616c653d302c63757272656e745363616c653d302c70616c65747465574f50616c657474653d70616c657474652e736c69636528302c33293b66756e6374696f6e206472617728297b6966286f72626974436f6e74726f6c28292c216d6f7573654973507265737365642969662874616e6f7273696e3e2e38297b6c657420653d6d61702874616e286672616d65436f756e742f313030292c2d312c312c302c313030293b63616d65726128302c652c3330302c302c302c302c302c312c30297d656c73657b6c657420653d6d61702873696e286672616d65436f756e742f313030292c2d312c312c302c313030293b63616d65726128302c652c3330302c302c302c302c302c312c30297d666f72286c657420653d303b653c726f77733b652b2b297b7075736828292c7472616e736c61746528302c302c3235292c63757272656e745363616c653c6c6173745363616c653f66696c6c2870616c657474655b305d293a2863757272656e745363616c653d73696e2872616469616e73286672616d65436f756e7429292f382c7363616c652863757272656e745363616c65292c726f74617465582872616469616e73282d6672616d65436f756e7429292c726f74617465592872616469616e73286672616d65436f756e7429292c726f746174655a2872616469616e73286672616d65436f756e7429292c6672616d65436f756e742531303d3d303f286c6173745374726f6b653d726e672e72616e646f6d5f63686f6963652870616c65747465574f50616c65747465292c7374726f6b65286c6173745374726f6b6529293a286c6173745374726f6b657c7c286c6173745374726f6b653d726e672e72616e646f6d5f63686f6963652870616c65747465574f50616c6574746529292c7374726f6b65286c6173745374726f6b6529292c66696c6c2870616c657474655b345d292c637562654368616e63653e2e393f287374726f6b655765696768742831292c626f7828575f2f312e3529293a287374726f6b655765696768742831292c73706865726528575f2f312e352929292c6c6173745363616c653d7061727365466c6f61742863757272656e745363616c65292c706f7028293b666f72286c657420613d303b613c636f6c733b612b2b297b6c657420743d7368617065735b652a615d3b7075736828292c726f746174655a286672616d65436f756e742a612f323535292c7472616e736c617465282d575f2f322b726174696f522a652b72616469616e73286672616d65436f756e742f35292c2d575f2f322b726174696f432a612b72616469616e73286672616d65436f756e742f3529292c7363616c652873696e28322a72616469616e73286672616d65436f756e742f352929292c66696c6c28636f6c6f72735b652a615d292c743e2e32353f626f7828726174696f52293a743e2e313f636f6e6528726174696f522c312e352a726174696f52293a73706865726528726174696f52292c706f7028297d7d6d6f7573654973507265737365643f287374726f6b652830292c7374726f6b6557656967687428706672616d652f3130292c706672616d652b2b293a287374726f6b6557656967687428706672616d653e303f706672616d652f353a31292c706672616d653e303f706672616d652d2d3a6e6f5374726f6b652829297d

Deployed Bytecode

0x6080604052600436106102465760003560e01c8063715018a611610139578063a22cb465116100b6578063c87b56dd1161007a578063c87b56dd1461069a578063cd53d08e146106ba578063e985e9c5146106f0578063ebe9eb9f14610739578063f0c9dc601461074e578063f2fde38b1461076357600080fd5b8063a22cb465146105fa578063a38643971461061a578063a8f14af61461063a578063b88d4fde1461065a578063b95717211461067a57600080fd5b8063853828b6116100fd578063853828b61461057f578063891cc177146105875780638da5cb5b146105a757806395d89b41146105c55780639758e904146105da57600080fd5b8063715018a6146104e3578063753853c1146104f85780637eaef50c1461050d57806382d38954146105225780638462151c1461055257600080fd5b80632f745c59116101c757806355f804b31161018b57806355f804b31461044e5780636352211e1461046e57806363d969411461048e5780636c0360eb146104ae57806370a08231146104c357600080fd5b80632f745c59146103c457806334d84c7b146103e457806342842e0e146103f95780634e71d92d146104195780634f6ccce71461042e57600080fd5b806318160ddd1161020e57806318160ddd146103365780631c8b232d1461035957806323b872dd1461037a5780632808c92c1461039a5780632ee2ac36146103af57600080fd5b806301ffc9a71461024b57806306fdde031461029a578063081812fc146102bc578063095ea7b3146102f45780631096952314610316575b600080fd5b34801561025757600080fd5b50610285610266366004612297565b6001600160e01b03191660009081526020819052604090205460ff1690565b60405190151581526020015b60405180910390f35b3480156102a657600080fd5b506102af610783565b60405161029191906124d2565b3480156102c857600080fd5b506102dc6102d736600461231a565b610815565b6040516001600160a01b039091168152602001610291565b34801561030057600080fd5b5061031461030f3660046121b9565b6108a2565b005b34801561032257600080fd5b506103146103313660046122d1565b6109b8565b34801561034257600080fd5b5061034b6109f9565b604051908152602001610291565b34801561036557600080fd5b50600a5461028590600160a01b900460ff1681565b34801561038657600080fd5b506103146103953660046120c5565b610a0a565b3480156103a657600080fd5b50610314610a3b565b3480156103bb57600080fd5b506102af610a74565b3480156103d057600080fd5b5061034b6103df3660046121b9565b610b02565b3480156103f057600080fd5b50610314610b2d565b34801561040557600080fd5b506103146104143660046120c5565b610b6c565b34801561042557600080fd5b50610314610b87565b34801561043a57600080fd5b5061034b61044936600461231a565b610c25565b34801561045a57600080fd5b506103146104693660046122d1565b610c3b565b34801561047a57600080fd5b506102dc61048936600461231a565b610c6e565b34801561049a57600080fd5b506102af6104a936600461231a565b610c96565b3480156104ba57600080fd5b506102af610cef565b3480156104cf57600080fd5b5061034b6104de366004612077565b610cfe565b3480156104ef57600080fd5b50610314610d8a565b34801561050457600080fd5b506102af610dfe565b34801561051957600080fd5b50610314610e0b565b34801561052e57600080fd5b5061028561053d366004612077565b600f6020526000908152604090205460ff1681565b34801561055e57600080fd5b5061057261056d366004612077565b610e44565b604051610291919061248e565b610314610eff565b34801561059357600080fd5b506103146105a23660046122d1565b610f4f565b3480156105b357600080fd5b50600a546001600160a01b03166102dc565b3480156105d157600080fd5b506102af610f8c565b3480156105e657600080fd5b506102af6105f536600461231a565b610f9b565b34801561060657600080fd5b5061031461061536600461217d565b610fcd565b34801561062657600080fd5b5061034b61063536600461231a565b611092565b34801561064657600080fd5b506103146106553660046122d1565b611116565b34801561066657600080fd5b50610314610675366004612101565b611153565b34801561068657600080fd5b506103146106953660046121e3565b61118b565b3480156106a657600080fd5b506102af6106b536600461231a565b611259565b3480156106c657600080fd5b506102dc6106d536600461231a565b6010602052600090815260409020546001600160a01b031681565b3480156106fc57600080fd5b5061028561070b366004612092565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561074557600080fd5b506102af6113cb565b34801561075a57600080fd5b506102af6113d8565b34801561076f57600080fd5b5061031461077e366004612077565b6113e5565b60606006805461079290612685565b80601f01602080910402602001604051908101604052809291908181526020018280546107be90612685565b801561080b5780601f106107e05761010080835404028352916020019161080b565b820191906000526020600020905b8154815290600101906020018083116107ee57829003601f168201915b5050505050905090565b6000610820826114d0565b6108865760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006108ad82610c6e565b9050806001600160a01b0316836001600160a01b0316141561091b5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161087d565b336001600160a01b03821614806109375750610937813361070b565b6109a95760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161087d565b6109b383836114dd565b505050565b600a546001600160a01b031633146109e25760405162461bcd60e51b815260040161087d90612537565b80516109f590600b906020840190611f6a565b5050565b6000610a05600261154b565b905090565b610a143382611555565b610a305760405162461bcd60e51b815260040161087d9061256c565b6109b383838361163f565b600a546001600160a01b03163314610a655760405162461bcd60e51b815260040161087d90612537565b600a805460ff60a01b19169055565b600c8054610a8190612685565b80601f0160208091040260200160405190810160405280929190818152602001828054610aad90612685565b8015610afa5780601f10610acf57610100808354040283529160200191610afa565b820191906000526020600020905b815481529060010190602001808311610add57829003601f168201915b505050505081565b6001600160a01b0382166000908152600160205260408120610b2490836117c0565b90505b92915050565b600a546001600160a01b03163314610b575760405162461bcd60e51b815260040161087d90612537565b600a805460ff60a01b1916600160a01b179055565b6109b383838360405180602001604052806000815250611153565b336000908152600f602052604090205460ff16610bd55760405162461bcd60e51b815260206004820152600c60248201526b63616e6e6f7420636c61696d60a01b604482015260640161087d565b336000908152600f60205260408120805460ff19169055610bf46109f9565b600081815260106020526040902080546001600160a01b03191633908117909155909150610c2290826117cc565b50565b600080610c336002846117e6565b509392505050565b600a546001600160a01b03163314610c655760405162461bcd60e51b815260040161087d90612537565b610c2281611802565b6000610b278260405180606001604052806029815260200161276e6029913960029190611815565b6060610ca1826114d0565b610cbd5760405162461bcd60e51b815260040161087d906125bd565b600c610cc88361182c565b604051602001610cd99291906123aa565b6040516020818303038152906040529050919050565b60606009805461079290612685565b60006001600160a01b038216610d695760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161087d565b6001600160a01b0382166000908152600160205260409020610b279061154b565b600a546001600160a01b03163314610db45760405162461bcd60e51b815260040161087d90612537565b600a546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600a80546001600160a01b0319169055565b600d8054610a8190612685565b600a546001600160a01b03163314610e355760405162461bcd60e51b815260040161087d90612537565b6011805460ff19166001179055565b60606000610e5183610cfe565b905080610e6e576040805160008082526020820190925290610c33565b60008167ffffffffffffffff811115610e8957610e89612741565b604051908082528060200260200182016040528015610eb2578160200160208202803683370190505b50905060005b82811015610c3357610eca8582610b02565b828281518110610edc57610edc61272b565b602090810291909101015280610ef1816126ba565b915050610eb8565b50919050565b600a546001600160a01b03163314610f295760405162461bcd60e51b815260040161087d90612537565b60405133904780156108fc02916000818181858888f19350505050610f4d57600080fd5b565b600a546001600160a01b03163314610f795760405162461bcd60e51b815260040161087d90612537565b80516109f590600d906020840190611f6a565b60606007805461079290612685565b6060610fa6826114d0565b610fc25760405162461bcd60e51b815260040161087d906125bd565b600d610cc88361182c565b6001600160a01b0382163314156110265760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161087d565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600061109d826114d0565b6110b95760405162461bcd60e51b815260040161087d906125bd565b506000818152601060209081526040918290205482516bffffffffffffffffffffffff1930606090811b8216838601529290921b909116603482015260488082019490945282518082039094018452606801909152815191012090565b600a546001600160a01b031633146111405760405162461bcd60e51b815260040161087d90612537565b80516109f590600c906020840190611f6a565b61115d3383611555565b6111795760405162461bcd60e51b815260040161087d9061256c565b6111858484848461192a565b50505050565b600a546001600160a01b031633146111b55760405162461bcd60e51b815260040161087d90612537565b60115460ff16156111f15760405162461bcd60e51b815260040161087d9060208082526004908201526337bb32b960e11b604082015260600190565b60005b81518110156109f5576001600f60008484815181106112155761121561272b565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580611251816126ba565b9150506111f4565b6060611264826114d0565b6112c85760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b606482015260840161087d565b600082815260086020526040812080546112e190612685565b80601f016020809104026020016040519081016040528092919081815260200182805461130d90612685565b801561135a5780601f1061132f5761010080835404028352916020019161135a565b820191906000526020600020905b81548152906001019060200180831161133d57829003601f168201915b50505050509050600061136b610cef565b905080516000141561137e575092915050565b8151156113b057808260405160200161139892919061237b565b60405160208183030381529060405292505050919050565b806113ba8561182c565b60405160200161139892919061237b565b600e8054610a8190612685565b600b8054610a8190612685565b600a546001600160a01b0316331461140f5760405162461bcd60e51b815260040161087d90612537565b6001600160a01b0381166114745760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161087d565b600a546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610b2760028361195d565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061151282610c6e565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610b27825490565b6000611560826114d0565b6115c15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161087d565b60006115cc83610c6e565b9050806001600160a01b0316846001600160a01b031614806116075750836001600160a01b03166115fc84610815565b6001600160a01b0316145b8061163757506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661165282610c6e565b6001600160a01b0316146116ba5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161087d565b6001600160a01b03821661171c5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161087d565b6117276000826114dd565b6001600160a01b03831660009081526001602052604090206117499082611975565b506001600160a01b038216600090815260016020526040902061176c9082611981565b506117796002828461198d565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000610b2483836119a3565b6109f5828260405180602001604052806000815250611a29565b60008080806117f58686611a5c565b9097909650945050505050565b80516109f5906009906020840190611f6a565b6000611822848484611af9565b90505b9392505050565b6060816118505750506040805180820190915260018152600360fc1b602082015290565b8160005b811561187a5780611864816126ba565b91506118739050600a8361262e565b9150611854565b60008167ffffffffffffffff81111561189557611895612741565b6040519080825280601f01601f1916602001820160405280156118bf576020820181803683370190505b5090505b8415611637576118d4600183612642565b91506118e1600a866126d5565b6118ec906030612616565b60f81b8183815181106119015761190161272b565b60200101906001600160f81b031916908160001a905350611923600a8661262e565b94506118c3565b61193584848461163f565b61194184848484611b62565b6111855760405162461bcd60e51b815260040161087d906124e5565b60008181526001830160205260408120541515610b24565b6000610b248383611c6f565b6000610b248383611d62565b600061182284846001600160a01b038516611db1565b81546000908210611a015760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b606482015260840161087d565b826000018281548110611a1657611a1661272b565b9060005260206000200154905092915050565b611a338383611e52565b611a406000848484611b62565b6109b35760405162461bcd60e51b815260040161087d906124e5565b815460009081908310611abc5760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604482015261647360f01b606482015260840161087d565b6000846000018481548110611ad357611ad361272b565b906000526020600020906002020190508060000154816001015492509250509250929050565b60008281526001840160205260408120548281611b295760405162461bcd60e51b815260040161087d91906124d2565b5084611b36600183612642565b81548110611b4657611b4661272b565b9060005260206000209060020201600101549150509392505050565b60006001600160a01b0384163b15611c6457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611ba6903390899088908890600401612451565b602060405180830381600087803b158015611bc057600080fd5b505af1925050508015611bf0575060408051601f3d908101601f19168201909252611bed918101906122b4565b60015b611c4a573d808015611c1e576040519150601f19603f3d011682016040523d82523d6000602084013e611c23565b606091505b508051611c425760405162461bcd60e51b815260040161087d906124e5565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611637565b506001949350505050565b60008181526001830160205260408120548015611d58576000611c93600183612642565b8554909150600090611ca790600190612642565b90506000866000018281548110611cc057611cc061272b565b9060005260206000200154905080876000018481548110611ce357611ce361272b565b600091825260209091200155611cfa836001612616565b60008281526001890160205260409020558654879080611d1c57611d1c612715565b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610b27565b6000915050610b27565b6000818152600183016020526040812054611da957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610b27565b506000610b27565b600082815260018401602052604081205480611e16575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055611825565b8285611e23600184612642565b81548110611e3357611e3361272b565b9060005260206000209060020201600101819055506000915050611825565b6001600160a01b038216611ea85760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161087d565b611eb1816114d0565b15611efe5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161087d565b6001600160a01b0382166000908152600160205260409020611f209082611981565b50611f2d6002828461198d565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b828054611f7690612685565b90600052602060002090601f016020900481019282611f985760008555611fde565b82601f10611fb157805160ff1916838001178555611fde565b82800160010185558215611fde579182015b82811115611fde578251825591602001919060010190611fc3565b50611fea929150611fee565b5090565b5b80821115611fea5760008155600101611fef565b600067ffffffffffffffff83111561201d5761201d612741565b612030601f8401601f19166020016125e5565b905082815283838301111561204457600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b038116811461207257600080fd5b919050565b60006020828403121561208957600080fd5b610b248261205b565b600080604083850312156120a557600080fd5b6120ae8361205b565b91506120bc6020840161205b565b90509250929050565b6000806000606084860312156120da57600080fd5b6120e38461205b565b92506120f16020850161205b565b9150604084013590509250925092565b6000806000806080858703121561211757600080fd5b6121208561205b565b935061212e6020860161205b565b925060408501359150606085013567ffffffffffffffff81111561215157600080fd5b8501601f8101871361216257600080fd5b61217187823560208401612003565b91505092959194509250565b6000806040838503121561219057600080fd5b6121998361205b565b9150602083013580151581146121ae57600080fd5b809150509250929050565b600080604083850312156121cc57600080fd5b6121d58361205b565b946020939093013593505050565b600060208083850312156121f657600080fd5b823567ffffffffffffffff8082111561220e57600080fd5b818501915085601f83011261222257600080fd5b81358181111561223457612234612741565b8060051b91506122458483016125e5565b8181528481019084860184860187018a101561226057600080fd5b600095505b8386101561228a576122768161205b565b835260019590950194918601918601612265565b5098975050505050505050565b6000602082840312156122a957600080fd5b813561182581612757565b6000602082840312156122c657600080fd5b815161182581612757565b6000602082840312156122e357600080fd5b813567ffffffffffffffff8111156122fa57600080fd5b8201601f8101841361230b57600080fd5b61163784823560208401612003565b60006020828403121561232c57600080fd5b5035919050565b6000815180845261234b816020860160208601612659565b601f01601f19169290920160200192915050565b60008151612371818560208601612659565b9290920192915050565b6000835161238d818460208801612659565b8351908301906123a1818360208801612659565b01949350505050565b600080845481600182811c9150808316806123c657607f831692505b60208084108214156123e657634e487b7160e01b86526022600452602486fd5b8180156123fa576001811461240b57612438565b60ff19861689528489019650612438565b60008b81526020902060005b868110156124305781548b820152908501908301612417565b505084890196505b505050505050612448818561235f565b95945050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061248490830184612333565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156124c6578351835292840192918401916001016124aa565b50909695505050505050565b602081526000610b246020830184612333565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252600e908201526d1113d154c81393d50811561254d560921b604082015260600190565b604051601f8201601f1916810167ffffffffffffffff8111828210171561260e5761260e612741565b604052919050565b60008219821115612629576126296126e9565b500190565b60008261263d5761263d6126ff565b500490565b600082821015612654576126546126e9565b500390565b60005b8381101561267457818101518382015260200161265c565b838111156111855750506000910152565b600181811c9082168061269957607f821691505b60208210811415610ef957634e487b7160e01b600052602260045260246000fd5b60006000198214156126ce576126ce6126e9565b5060010190565b6000826126e4576126e46126ff565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610c2257600080fdfe4552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea264697066735822122038cb190f2d1f50aa2e181a49379fa19d040c142a914f85b8d390658918ea792964736f6c63430008070033

Deployed Bytecode Sourcemap

66147:6542:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31813:150;;;;;;;;;;-1:-1:-1;31813:150:0;;;;;:::i;:::-;-1:-1:-1;;;;;;31922:33:0;31898:4;31922:33;;;;;;;;;;;;;;31813:150;;;;8798:14:1;;8791:22;8773:41;;8761:2;8746:18;31813:150:0;;;;;;;;43526:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;46312:221::-;;;;;;;;;;-1:-1:-1;46312:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;7459:32:1;;;7441:51;;7429:2;7414:18;46312:221:0;7295:203:1;45842:404:0;;;;;;;;;;-1:-1:-1;45842:404:0;;;;;:::i;:::-;;:::i;:::-;;71178:116;;;;;;;;;;-1:-1:-1;71178:116:0;;;;;:::i;:::-;;:::i;45320:211::-;;;;;;;;;;;;;:::i;:::-;;;8971:25:1;;;8959:2;8944:18;45320:211:0;8825:177:1;66259:34:0;;;;;;;;;;-1:-1:-1;66259:34:0;;;;-1:-1:-1;;;66259:34:0;;;;;;47202:305;;;;;;;;;;-1:-1:-1;47202:305:0;;;;;:::i;:::-;;:::i;71760:79::-;;;;;;;;;;;;;:::i;66350:70::-;;;;;;;;;;;;;:::i;45082:162::-;;;;;;;;;;-1:-1:-1;45082:162:0;;;;;:::i;:::-;;:::i;71670:78::-;;;;;;;;;;;;;:::i;47578:151::-;;;;;;;;;;-1:-1:-1;47578:151:0;;;;;:::i;:::-;;:::i;70524:292::-;;;;;;;;;;;;;:::i;45608:172::-;;;;;;;;;;-1:-1:-1;45608:172:0;;;;;:::i;:::-;;:::i;71556:99::-;;;;;;;;;;-1:-1:-1;71556:99:0;;;;;:::i;:::-;;:::i;43282:177::-;;;;;;;;;;-1:-1:-1;43282:177:0;;;;;:::i;:::-;;:::i;72221:222::-;;;;;;;;;;-1:-1:-1;72221:222:0;;;;;:::i;:::-;;:::i;44901:97::-;;;;;;;;;;;;;:::i;42972:221::-;;;;;;;;;;-1:-1:-1;42972:221:0;;;;;:::i;:::-;;:::i;58387:148::-;;;;;;;;;;;;;:::i;66427:41::-;;;;;;;;;;;;;:::i;71069:67::-;;;;;;;;;;;;;:::i;66507:41::-;;;;;;;;;;-1:-1:-1;66507:41:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;69972:540;;;;;;;;;;-1:-1:-1;69972:540:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;71851:123::-;;;:::i;71306:117::-;;;;;;;;;;-1:-1:-1;71306:117:0;;;;;:::i;:::-;;:::i;57736:87::-;;;;;;;;;;-1:-1:-1;57809:6:0;;-1:-1:-1;;;;;57809:6:0;57736:87;;43695:104;;;;;;;;;;;;;:::i;72455:231::-;;;;;;;;;;-1:-1:-1;72455:231:0;;;;;:::i;:::-;;:::i;46605:295::-;;;;;;;;;;-1:-1:-1;46605:295:0;;;;;:::i;:::-;;:::i;71986:223::-;;;;;;;;;;-1:-1:-1;71986:223:0;;;;;:::i;:::-;;:::i;71435:109::-;;;;;;;;;;-1:-1:-1;71435:109:0;;;;;:::i;:::-;;:::i;47800:285::-;;;;;;;;;;-1:-1:-1;47800:285:0;;;;;:::i;:::-;;:::i;70860:197::-;;;;;;;;;;-1:-1:-1;70860:197:0;;;;;:::i;:::-;;:::i;43870:792::-;;;;;;;;;;-1:-1:-1;43870:792:0;;;;;:::i;:::-;;:::i;66555:40::-;;;;;;;;;;-1:-1:-1;66555:40:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;66555:40:0;;;46971:164;;;;;;;;;;-1:-1:-1;46971:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;47092:25:0;;;47068:4;47092:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;46971:164;66475:25;;;;;;;;;;;;;:::i;66300:43::-;;;;;;;;;;;;;:::i;58690:244::-;;;;;;;;;;-1:-1:-1;58690:244:0;;;;;:::i;:::-;;:::i;43526:100::-;43580:13;43613:5;43606:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43526:100;:::o;46312:221::-;46388:7;46416:16;46424:7;46416;:16::i;:::-;46408:73;;;;-1:-1:-1;;;46408:73:0;;14123:2:1;46408:73:0;;;14105:21:1;14162:2;14142:18;;;14135:30;14201:34;14181:18;;;14174:62;-1:-1:-1;;;14252:18:1;;;14245:42;14304:19;;46408:73:0;;;;;;;;;-1:-1:-1;46501:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;46501:24:0;;46312:221::o;45842:404::-;45923:13;45939:23;45954:7;45939:14;:23::i;:::-;45923:39;;45987:5;-1:-1:-1;;;;;45981:11:0;:2;-1:-1:-1;;;;;45981:11:0;;;45973:57;;;;-1:-1:-1;;;45973:57:0;;16064:2:1;45973:57:0;;;16046:21:1;16103:2;16083:18;;;16076:30;16142:34;16122:18;;;16115:62;-1:-1:-1;;;16193:18:1;;;16186:31;16234:19;;45973:57:0;15862:397:1;45973:57:0;40824:10;-1:-1:-1;;;;;46051:21:0;;;;:69;;-1:-1:-1;46076:44:0;46100:5;40824:10;46971:164;:::i;46076:44::-;46043:161;;;;-1:-1:-1;;;46043:161:0;;12523:2:1;46043:161:0;;;12505:21:1;12562:2;12542:18;;;12535:30;12601:34;12581:18;;;12574:62;12672:26;12652:18;;;12645:54;12716:19;;46043:161:0;12321:420:1;46043:161:0;46217:21;46226:2;46230:7;46217:8;:21::i;:::-;45912:334;45842:404;;:::o;71178:116::-;57809:6;;-1:-1:-1;;;;;57809:6:0;40824:10;57956:23;57948:68;;;;-1:-1:-1;;;57948:68:0;;;;;;;:::i;:::-;71254:32;;::::1;::::0;:24:::1;::::0;:32:::1;::::0;::::1;::::0;::::1;:::i;:::-;;71178:116:::0;:::o;45320:211::-;45381:7;45502:21;:12;:19;:21::i;:::-;45495:28;;45320:211;:::o;47202:305::-;47363:41;40824:10;47396:7;47363:18;:41::i;:::-;47355:103;;;;-1:-1:-1;;;47355:103:0;;;;;;;:::i;:::-;47471:28;47481:4;47487:2;47491:7;47471:9;:28::i;71760:79::-;57809:6;;-1:-1:-1;;;;;57809:6:0;40824:10;57956:23;57948:68;;;;-1:-1:-1;;;57948:68:0;;;;;;;:::i;:::-;71809:14:::1;:22:::0;;-1:-1:-1;;;;71809:22:0::1;::::0;;71760:79::o;66350:70::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;45082:162::-;-1:-1:-1;;;;;45206:20:0;;45179:7;45206:20;;;:13;:20;;;;;:30;;45230:5;45206:23;:30::i;:::-;45199:37;;45082:162;;;;;:::o;71670:78::-;57809:6;;-1:-1:-1;;;;;57809:6:0;40824:10;57956:23;57948:68;;;;-1:-1:-1;;;57948:68:0;;;;;;;:::i;:::-;71719:14:::1;:21:::0;;-1:-1:-1;;;;71719:21:0::1;-1:-1:-1::0;;;71719:21:0::1;::::0;;71670:78::o;47578:151::-;47682:39;47699:4;47705:2;47709:7;47682:39;;;;;;;;;;;;:16;:39::i;70524:292::-;70583:10;70573:21;;;;:9;:21;;;;;;;;70565:46;;;;-1:-1:-1;;;70565:46:0;;15307:2:1;70565:46:0;;;15289:21:1;15346:2;15326:18;;;15319:30;-1:-1:-1;;;15365:18:1;;;15358:42;15417:18;;70565:46:0;15105:336:1;70565:46:0;70636:10;70650:5;70626:21;;;:9;:21;;;;;:29;;-1:-1:-1;;70626:29:0;;;70701:13;:11;:13::i;:::-;70729:19;;;;:8;:19;;;;;:32;;-1:-1:-1;;;;;;70729:32:0;70751:10;70729:32;;;;;;70684:30;;-1:-1:-1;70776:32:0;;70684:30;70776:9;:32::i;:::-;70550:266;70524:292::o;45608:172::-;45683:7;;45725:22;:12;45741:5;45725:15;:22::i;:::-;-1:-1:-1;45703:44:0;45608:172;-1:-1:-1;;;45608:172:0:o;71556:99::-;57809:6;;-1:-1:-1;;;;;57809:6:0;40824:10;57956:23;57948:68;;;;-1:-1:-1;;;57948:68:0;;;;;;;:::i;:::-;71627:20:::1;71639:7;71627:11;:20::i;43282:177::-:0;43354:7;43381:70;43398:7;43381:70;;;;;;;;;;;;;;;;;:12;;:70;:16;:70::i;72221:222::-;72285:13;72319:16;72327:7;72319;:16::i;:::-;72311:43;;;;-1:-1:-1;;;72311:43:0;;;;;;;:::i;:::-;72396:17;72415:18;:7;:16;:18::i;:::-;72379:55;;;;;;;;;:::i;:::-;;;;;;;;;;;;;72365:70;;72221:222;;;:::o;44901:97::-;44949:13;44982:8;44975:15;;;;;:::i;42972:221::-;43044:7;-1:-1:-1;;;;;43072:19:0;;43064:74;;;;-1:-1:-1;;;43064:74:0;;12948:2:1;43064:74:0;;;12930:21:1;12987:2;12967:18;;;12960:30;13026:34;13006:18;;;12999:62;-1:-1:-1;;;13077:18:1;;;13070:40;13127:19;;43064:74:0;12746:406:1;43064:74:0;-1:-1:-1;;;;;43156:20:0;;;;;;:13;:20;;;;;:29;;:27;:29::i;58387:148::-;57809:6;;-1:-1:-1;;;;;57809:6:0;40824:10;57956:23;57948:68;;;;-1:-1:-1;;;57948:68:0;;;;;;;:::i;:::-;58478:6:::1;::::0;58457:40:::1;::::0;58494:1:::1;::::0;-1:-1:-1;;;;;58478:6:0::1;::::0;58457:40:::1;::::0;58494:1;;58457:40:::1;58508:6;:19:::0;;-1:-1:-1;;;;;;58508:19:0::1;::::0;;58387:148::o;66427:41::-;;;;;;;:::i;71069:67::-;57809:6;;-1:-1:-1;;;;;57809:6:0;40824:10;57956:23;57948:68;;;;-1:-1:-1;;;57948:68:0;;;;;;;:::i;:::-;71115:6:::1;:13:::0;;-1:-1:-1;;71115:13:0::1;71124:4;71115:13;::::0;;71069:67::o;69972:540::-;70033:16;70063:18;70084:17;70094:6;70084:9;:17::i;:::-;70063:38;-1:-1:-1;70116:15:0;70112:393;;70193:16;;;70207:1;70193:16;;;;;;;;;;;;70112:393;70242:23;70282:10;70268:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;70268:25:0;;70242:51;;70308:13;70336:130;70360:10;70352:5;:18;70336:130;;;70416:34;70436:6;70444:5;70416:19;:34::i;:::-;70400:6;70407:5;70400:13;;;;;;;;:::i;:::-;;;;;;;;;;:50;70372:7;;;;:::i;:::-;;;;70336:130;;70112:393;70052:460;69972:540;;;:::o;71851:123::-;57809:6;;-1:-1:-1;;;;;57809:6:0;40824:10;57956:23;57948:68;;;;-1:-1:-1;;;57948:68:0;;;;;;;:::i;:::-;71918:47:::1;::::0;71926:10:::1;::::0;71943:21:::1;71918:47:::0;::::1;;;::::0;::::1;::::0;;;71943:21;71926:10;71918:47;::::1;;;;;;71910:56;;;::::0;::::1;;71851:123::o:0;71306:117::-;57809:6;;-1:-1:-1;;;;;57809:6:0;40824:10;57956:23;57948:68;;;;-1:-1:-1;;;57948:68:0;;;;;;;:::i;:::-;71385:30;;::::1;::::0;:22:::1;::::0;:30:::1;::::0;::::1;::::0;::::1;:::i;43695:104::-:0;43751:13;43784:7;43777:14;;;;;:::i;72455:231::-;72523:13;72557:16;72565:7;72557;:16::i;:::-;72549:43;;;;-1:-1:-1;;;72549:43:0;;;;;;;:::i;:::-;72634:22;72658:18;:7;:16;:18::i;46605:295::-;-1:-1:-1;;;;;46708:24:0;;40824:10;46708:24;;46700:62;;;;-1:-1:-1;;;46700:62:0;;11756:2:1;46700:62:0;;;11738:21:1;11795:2;11775:18;;;11768:30;11834:27;11814:18;;;11807:55;11879:18;;46700:62:0;11554:349:1;46700:62:0;40824:10;46775:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;46775:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;46775:53:0;;;;;;;;;;46844:48;;8773:41:1;;;46775:42:0;;40824:10;46844:48;;8746:18:1;46844:48:0;;;;;;;46605:295;;:::o;71986:223::-;72042:7;72069:16;72077:7;72069;:16::i;:::-;72061:43;;;;-1:-1:-1;;;72061:43:0;;;;;;;:::i;:::-;-1:-1:-1;72172:17:0;;;;:8;:17;;;;;;;;;;72140:59;;-1:-1:-1;;72165:4:0;5493:2:1;5489:15;;;5485:24;;72140:59:0;;;5473:37:1;5544:15;;;;;;;5526:12;;;5519:46;5581:12;;;;5574:28;;;;72140:59:0;;;;;;;;;;5618:12:1;;72140:59:0;;;72130:70;;;;;;71986:223::o;71435:109::-;57809:6;;-1:-1:-1;;;;;57809:6:0;40824:10;57956:23;57948:68;;;;-1:-1:-1;;;57948:68:0;;;;;;;:::i;:::-;71512:24;;::::1;::::0;:17:::1;::::0;:24:::1;::::0;::::1;::::0;::::1;:::i;47800:285::-:0;47932:41;40824:10;47965:7;47932:18;:41::i;:::-;47924:103;;;;-1:-1:-1;;;47924:103:0;;;;;;;:::i;:::-;48038:39;48052:4;48058:2;48062:7;48071:5;48038:13;:39::i;:::-;47800:285;;;;:::o;70860:197::-;57809:6;;-1:-1:-1;;;;;57809:6:0;40824:10;57956:23;57948:68;;;;-1:-1:-1;;;57948:68:0;;;;;;;:::i;:::-;70941:6:::1;::::0;::::1;;70940:7;70932:24;;;;-1:-1:-1::0;;;70932:24:0::1;;;;;;9836:2:1::0;9818:21;;;9875:1;9855:18;;;9848:29;-1:-1:-1;;;9908:2:1;9893:18;;9886:34;9952:2;9937:18;;9634:327;70932:24:0::1;70971:6;70967:83;70986:1;:8;70983:1;:11;70967:83;;;71034:4;71016:9;:15;71026:1;71028;71026:4;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;;;71016:15:0::1;::::0;;;::::1;::::0;;;;;;-1:-1:-1;71016:15:0;:22;;-1:-1:-1;;71016:22:0::1;::::0;::::1;;::::0;;;::::1;::::0;;70996:3;::::1;::::0;::::1;:::i;:::-;;;;70967:83;;43870:792:::0;43943:13;43977:16;43985:7;43977;:16::i;:::-;43969:76;;;;-1:-1:-1;;;43969:76:0;;15648:2:1;43969:76:0;;;15630:21:1;15687:2;15667:18;;;15660:30;15726:34;15706:18;;;15699:62;-1:-1:-1;;;15777:18:1;;;15770:45;15832:19;;43969:76:0;15446:411:1;43969:76:0;44058:23;44084:19;;;:10;:19;;;;;44058:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44114:18;44135:9;:7;:9::i;:::-;44114:30;;44226:4;44220:18;44242:1;44220:23;44216:72;;;-1:-1:-1;44267:9:0;43870:792;-1:-1:-1;;43870:792:0:o;44216:72::-;44392:23;;:27;44388:108;;44467:4;44473:9;44450:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;44436:48;;;;43870:792;;;:::o;44388:108::-;44628:4;44634:18;:7;:16;:18::i;:::-;44611:42;;;;;;;;;:::i;66475:25::-;;;;;;;:::i;66300:43::-;;;;;;;:::i;58690:244::-;57809:6;;-1:-1:-1;;;;;57809:6:0;40824:10;57956:23;57948:68;;;;-1:-1:-1;;;57948:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;58779:22:0;::::1;58771:73;;;::::0;-1:-1:-1;;;58771:73:0;;10587:2:1;58771:73:0::1;::::0;::::1;10569:21:1::0;10626:2;10606:18;;;10599:30;10665:34;10645:18;;;10638:62;-1:-1:-1;;;10716:18:1;;;10709:36;10762:19;;58771:73:0::1;10385:402:1::0;58771:73:0::1;58881:6;::::0;58860:38:::1;::::0;-1:-1:-1;;;;;58860:38:0;;::::1;::::0;58881:6:::1;::::0;58860:38:::1;::::0;58881:6:::1;::::0;58860:38:::1;58909:6;:17:::0;;-1:-1:-1;;;;;;58909:17:0::1;-1:-1:-1::0;;;;;58909:17:0;;;::::1;::::0;;;::::1;::::0;;58690:244::o;49552:127::-;49617:4;49641:30;:12;49663:7;49641:21;:30::i;55696:183::-;55762:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;55762:29:0;-1:-1:-1;;;;;55762:29:0;;;;;;;;:24;;55816:23;55762:24;55816:14;:23::i;:::-;-1:-1:-1;;;;;55807:46:0;;;;;;;;;;;55696:183;;:::o;10270:123::-;10339:7;10366:19;10374:3;6932:19;;6849:110;49846:355;49939:4;49964:16;49972:7;49964;:16::i;:::-;49956:73;;;;-1:-1:-1;;;49956:73:0;;12110:2:1;49956:73:0;;;12092:21:1;12149:2;12129:18;;;12122:30;12188:34;12168:18;;;12161:62;-1:-1:-1;;;12239:18:1;;;12232:42;12291:19;;49956:73:0;11908:408:1;49956:73:0;50040:13;50056:23;50071:7;50056:14;:23::i;:::-;50040:39;;50109:5;-1:-1:-1;;;;;50098:16:0;:7;-1:-1:-1;;;;;50098:16:0;;:51;;;;50142:7;-1:-1:-1;;;;;50118:31:0;:20;50130:7;50118:11;:20::i;:::-;-1:-1:-1;;;;;50118:31:0;;50098:51;:94;;;-1:-1:-1;;;;;;47092:25:0;;;47068:4;47092:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;50153:39;50090:103;49846:355;-1:-1:-1;;;;49846:355:0:o;52982:597::-;53107:4;-1:-1:-1;;;;;53080:31:0;:23;53095:7;53080:14;:23::i;:::-;-1:-1:-1;;;;;53080:31:0;;53072:85;;;;-1:-1:-1;;;53072:85:0;;14897:2:1;53072:85:0;;;14879:21:1;14936:2;14916:18;;;14909:30;14975:34;14955:18;;;14948:62;-1:-1:-1;;;15026:18:1;;;15019:39;15075:19;;53072:85:0;14695:405:1;53072:85:0;-1:-1:-1;;;;;53194:16:0;;53186:65;;;;-1:-1:-1;;;53186:65:0;;11351:2:1;53186:65:0;;;11333:21:1;11390:2;11370:18;;;11363:30;11429:34;11409:18;;;11402:62;-1:-1:-1;;;11480:18:1;;;11473:34;11524:19;;53186:65:0;11149:400:1;53186:65:0;53368:29;53385:1;53389:7;53368:8;:29::i;:::-;-1:-1:-1;;;;;53410:19:0;;;;;;:13;:19;;;;;:35;;53437:7;53410:26;:35::i;:::-;-1:-1:-1;;;;;;53456:17:0;;;;;;:13;:17;;;;;:30;;53478:7;53456:21;:30::i;:::-;-1:-1:-1;53499:29:0;:12;53516:7;53525:2;53499:16;:29::i;:::-;;53563:7;53559:2;-1:-1:-1;;;;;53544:27:0;53553:4;-1:-1:-1;;;;;53544:27:0;;;;;;;;;;;52982:597;;;:::o;21844:137::-;21915:7;21950:22;21954:3;21966:5;21950:3;:22::i;50544:110::-;50620:26;50630:2;50634:7;50620:26;;;;;;;;;;;;:9;:26::i;10732:236::-;10812:7;;;;10872:22;10876:3;10888:5;10872:3;:22::i;:::-;10841:53;;;;-1:-1:-1;10732:236:0;-1:-1:-1;;;;;10732:236:0:o;54180:100::-;54253:19;;;;:8;;:19;;;;;:::i;12018:213::-;12125:7;12176:44;12181:3;12201;12207:12;12176:4;:44::i;:::-;12168:53;-1:-1:-1;12018:213:0;;;;;;:::o;414:723::-;470:13;691:10;687:53;;-1:-1:-1;;718:10:0;;;;;;;;;;;;-1:-1:-1;;;718:10:0;;;;;414:723::o;687:53::-;765:5;750:12;806:78;813:9;;806:78;;839:8;;;;:::i;:::-;;-1:-1:-1;862:10:0;;-1:-1:-1;870:2:0;862:10;;:::i;:::-;;;806:78;;;894:19;926:6;916:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;916:17:0;;894:39;;944:154;951:10;;944:154;;978:11;988:1;978:11;;:::i;:::-;;-1:-1:-1;1047:10:0;1055:2;1047:5;:10;:::i;:::-;1034:24;;:2;:24;:::i;:::-;1021:39;;1004:6;1011;1004:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;1004:56:0;;;;;;;;-1:-1:-1;1075:11:0;1084:2;1075:11;;:::i;:::-;;;944:154;;48967:272;49081:28;49091:4;49097:2;49101:7;49081:9;:28::i;:::-;49128:48;49151:4;49157:2;49161:7;49170:5;49128:22;:48::i;:::-;49120:111;;;;-1:-1:-1;;;49120:111:0;;;;;;;:::i;10031:151::-;10115:4;6724:17;;;:12;;;:17;;;;;;:22;;10139:35;6629:125;20931:137;21001:4;21025:35;21033:3;21053:5;21025:7;:35::i;20624:131::-;20691:4;20715:32;20720:3;20740:5;20715:4;:32::i;9454:185::-;9543:4;9567:64;9572:3;9592;-1:-1:-1;;;;;9606:23:0;;9567:4;:64::i;16882:204::-;16977:18;;16949:7;;16977:26;-1:-1:-1;16969:73:0;;;;-1:-1:-1;;;16969:73:0;;9433:2:1;16969:73:0;;;9415:21:1;9472:2;9452:18;;;9445:30;9511:34;9491:18;;;9484:62;-1:-1:-1;;;9562:18:1;;;9555:32;9604:19;;16969:73:0;9231:398:1;16969:73:0;17060:3;:11;;17072:5;17060:18;;;;;;;;:::i;:::-;;;;;;;;;17053:25;;16882:204;;;;:::o;50881:250::-;50977:18;50983:2;50987:7;50977:5;:18::i;:::-;51014:54;51045:1;51049:2;51053:7;51062:5;51014:22;:54::i;:::-;51006:117;;;;-1:-1:-1;;;51006:117:0;;;;;;;:::i;7314:279::-;7418:19;;7381:7;;;;7418:27;-1:-1:-1;7410:74:0;;;;-1:-1:-1;;;7410:74:0;;13359:2:1;7410:74:0;;;13341:21:1;13398:2;13378:18;;;13371:30;13437:34;13417:18;;;13410:62;-1:-1:-1;;;13488:18:1;;;13481:32;13530:19;;7410:74:0;13157:398:1;7410:74:0;7497:22;7522:3;:12;;7535:5;7522:19;;;;;;;;:::i;:::-;;;;;;;;;;;7497:44;;7560:5;:10;;;7572:5;:12;;;7552:33;;;;;7314:279;;;;;:::o;8811:319::-;8905:7;8944:17;;;:12;;;:17;;;;;;8995:12;8980:13;8972:36;;;;-1:-1:-1;;;8972:36:0;;;;;;;;:::i;:::-;-1:-1:-1;9062:3:0;9075:12;9086:1;9075:8;:12;:::i;:::-;9062:26;;;;;;;;:::i;:::-;;;;;;;;;;;:33;;;9055:40;;;8811:319;;;;;:::o;54845:843::-;54966:4;-1:-1:-1;;;;;54992:13:0;;23163:20;23202:8;54988:693;;55028:72;;-1:-1:-1;;;55028:72:0;;-1:-1:-1;;;;;55028:36:0;;;;;:72;;40824:10;;55079:4;;55085:7;;55094:5;;55028:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55028:72:0;;;;;;;;-1:-1:-1;;55028:72:0;;;;;;;;;;;;:::i;:::-;;;55024:602;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55274:13:0;;55270:341;;55317:60;;-1:-1:-1;;;55317:60:0;;;;;;;:::i;55270:341::-;55561:6;55555:13;55546:6;55542:2;55538:15;55531:38;55024:602;-1:-1:-1;;;;;;55151:55:0;-1:-1:-1;;;55151:55:0;;-1:-1:-1;55144:62:0;;54988:693;-1:-1:-1;55665:4:0;54845:843;;;;;;:::o;14584:1544::-;14650:4;14789:19;;;:12;;;:19;;;;;;14825:15;;14821:1300;;15187:21;15211:14;15224:1;15211:10;:14;:::i;:::-;15260:18;;15187:38;;-1:-1:-1;15240:17:0;;15260:22;;15281:1;;15260:22;:::i;:::-;15240:42;;15527:17;15547:3;:11;;15559:9;15547:22;;;;;;;;:::i;:::-;;;;;;;;;15527:42;;15693:9;15664:3;:11;;15676:13;15664:26;;;;;;;;:::i;:::-;;;;;;;;;;:38;15796:17;:13;15812:1;15796:17;:::i;:::-;15770:23;;;;:12;;;:23;;;;;:43;15922:17;;15770:3;;15922:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;16017:3;:12;;:19;16030:5;16017:19;;;;;;;;;;;16010:26;;;16060:4;16053:11;;;;;;;;14821:1300;16104:5;16097:12;;;;;13994:414;14057:4;6724:17;;;:12;;;:17;;;;;;14074:327;;-1:-1:-1;14117:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;14300:18;;14278:19;;;:12;;;:19;;;;;;:40;;;;14333:11;;14074:327;-1:-1:-1;14384:5:0;14377:12;;4129:692;4205:4;4340:17;;;:12;;;:17;;;;;;4374:13;4370:444;;-1:-1:-1;;4459:38:0;;;;;;;;;;;;;;;;;;4441:57;;;;;;;;:12;:57;;;;;;;;;;;;;;;;;;;;;;;;4656:19;;4636:17;;;:12;;;:17;;;;;;;:39;4690:11;;4370:444;4770:5;4734:3;4747:12;4758:1;4747:8;:12;:::i;:::-;4734:26;;;;;;;;:::i;:::-;;;;;;;;;;;:33;;:41;;;;4797:5;4790:12;;;;;51467:404;-1:-1:-1;;;;;51547:16:0;;51539:61;;;;-1:-1:-1;;;51539:61:0;;13762:2:1;51539:61:0;;;13744:21:1;;;13781:18;;;13774:30;13840:34;13820:18;;;13813:62;13892:18;;51539:61:0;13560:356:1;51539:61:0;51620:16;51628:7;51620;:16::i;:::-;51619:17;51611:58;;;;-1:-1:-1;;;51611:58:0;;10994:2:1;51611:58:0;;;10976:21:1;11033:2;11013:18;;;11006:30;11072;11052:18;;;11045:58;11120:18;;51611:58:0;10792:352:1;51611:58:0;-1:-1:-1;;;;;51740:17:0;;;;;;:13;:17;;;;;:30;;51762:7;51740:21;:30::i;:::-;-1:-1:-1;51783:29:0;:12;51800:7;51809:2;51783:16;:29::i;:::-;-1:-1:-1;51830:33:0;;51855:7;;-1:-1:-1;;;;;51830:33:0;;;51847:1;;51830:33;;51847:1;;51830:33;51467:404;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:406:1;78:5;112:18;104:6;101:30;98:56;;;134:18;;:::i;:::-;172:57;217:2;196:15;;-1:-1:-1;;192:29:1;223:4;188:40;172:57;:::i;:::-;163:66;;252:6;245:5;238:21;292:3;283:6;278:3;274:16;271:25;268:45;;;309:1;306;299:12;268:45;358:6;353:3;346:4;339:5;335:16;322:43;412:1;405:4;396:6;389:5;385:18;381:29;374:40;14:406;;;;;:::o;425:173::-;493:20;;-1:-1:-1;;;;;542:31:1;;532:42;;522:70;;588:1;585;578:12;522:70;425:173;;;:::o;603:186::-;662:6;715:2;703:9;694:7;690:23;686:32;683:52;;;731:1;728;721:12;683:52;754:29;773:9;754:29;:::i;794:260::-;862:6;870;923:2;911:9;902:7;898:23;894:32;891:52;;;939:1;936;929:12;891:52;962:29;981:9;962:29;:::i;:::-;952:39;;1010:38;1044:2;1033:9;1029:18;1010:38;:::i;:::-;1000:48;;794:260;;;;;:::o;1059:328::-;1136:6;1144;1152;1205:2;1193:9;1184:7;1180:23;1176:32;1173:52;;;1221:1;1218;1211:12;1173:52;1244:29;1263:9;1244:29;:::i;:::-;1234:39;;1292:38;1326:2;1315:9;1311:18;1292:38;:::i;:::-;1282:48;;1377:2;1366:9;1362:18;1349:32;1339:42;;1059:328;;;;;:::o;1392:666::-;1487:6;1495;1503;1511;1564:3;1552:9;1543:7;1539:23;1535:33;1532:53;;;1581:1;1578;1571:12;1532:53;1604:29;1623:9;1604:29;:::i;:::-;1594:39;;1652:38;1686:2;1675:9;1671:18;1652:38;:::i;:::-;1642:48;;1737:2;1726:9;1722:18;1709:32;1699:42;;1792:2;1781:9;1777:18;1764:32;1819:18;1811:6;1808:30;1805:50;;;1851:1;1848;1841:12;1805:50;1874:22;;1927:4;1919:13;;1915:27;-1:-1:-1;1905:55:1;;1956:1;1953;1946:12;1905:55;1979:73;2044:7;2039:2;2026:16;2021:2;2017;2013:11;1979:73;:::i;:::-;1969:83;;;1392:666;;;;;;;:::o;2063:347::-;2128:6;2136;2189:2;2177:9;2168:7;2164:23;2160:32;2157:52;;;2205:1;2202;2195:12;2157:52;2228:29;2247:9;2228:29;:::i;:::-;2218:39;;2307:2;2296:9;2292:18;2279:32;2354:5;2347:13;2340:21;2333:5;2330:32;2320:60;;2376:1;2373;2366:12;2320:60;2399:5;2389:15;;;2063:347;;;;;:::o;2415:254::-;2483:6;2491;2544:2;2532:9;2523:7;2519:23;2515:32;2512:52;;;2560:1;2557;2550:12;2512:52;2583:29;2602:9;2583:29;:::i;:::-;2573:39;2659:2;2644:18;;;;2631:32;;-1:-1:-1;;;2415:254:1:o;2674:963::-;2758:6;2789:2;2832;2820:9;2811:7;2807:23;2803:32;2800:52;;;2848:1;2845;2838:12;2800:52;2888:9;2875:23;2917:18;2958:2;2950:6;2947:14;2944:34;;;2974:1;2971;2964:12;2944:34;3012:6;3001:9;2997:22;2987:32;;3057:7;3050:4;3046:2;3042:13;3038:27;3028:55;;3079:1;3076;3069:12;3028:55;3115:2;3102:16;3137:2;3133;3130:10;3127:36;;;3143:18;;:::i;:::-;3189:2;3186:1;3182:10;3172:20;;3212:28;3236:2;3232;3228:11;3212:28;:::i;:::-;3274:15;;;3305:12;;;;3337:11;;;3367;;;3363:20;;3360:33;-1:-1:-1;3357:53:1;;;3406:1;3403;3396:12;3357:53;3428:1;3419:10;;3438:169;3452:2;3449:1;3446:9;3438:169;;;3509:23;3528:3;3509:23;:::i;:::-;3497:36;;3470:1;3463:9;;;;;3553:12;;;;3585;;3438:169;;;-1:-1:-1;3626:5:1;2674:963;-1:-1:-1;;;;;;;;2674:963:1:o;3642:245::-;3700:6;3753:2;3741:9;3732:7;3728:23;3724:32;3721:52;;;3769:1;3766;3759:12;3721:52;3808:9;3795:23;3827:30;3851:5;3827:30;:::i;3892:249::-;3961:6;4014:2;4002:9;3993:7;3989:23;3985:32;3982:52;;;4030:1;4027;4020:12;3982:52;4062:9;4056:16;4081:30;4105:5;4081:30;:::i;4146:450::-;4215:6;4268:2;4256:9;4247:7;4243:23;4239:32;4236:52;;;4284:1;4281;4274:12;4236:52;4324:9;4311:23;4357:18;4349:6;4346:30;4343:50;;;4389:1;4386;4379:12;4343:50;4412:22;;4465:4;4457:13;;4453:27;-1:-1:-1;4443:55:1;;4494:1;4491;4484:12;4443:55;4517:73;4582:7;4577:2;4564:16;4559:2;4555;4551:11;4517:73;:::i;4601:180::-;4660:6;4713:2;4701:9;4692:7;4688:23;4684:32;4681:52;;;4729:1;4726;4719:12;4681:52;-1:-1:-1;4752:23:1;;4601:180;-1:-1:-1;4601:180:1:o;4786:257::-;4827:3;4865:5;4859:12;4892:6;4887:3;4880:19;4908:63;4964:6;4957:4;4952:3;4948:14;4941:4;4934:5;4930:16;4908:63;:::i;:::-;5025:2;5004:15;-1:-1:-1;;5000:29:1;4991:39;;;;5032:4;4987:50;;4786:257;-1:-1:-1;;4786:257:1:o;5048:185::-;5090:3;5128:5;5122:12;5143:52;5188:6;5183:3;5176:4;5169:5;5165:16;5143:52;:::i;:::-;5211:16;;;;;5048:185;-1:-1:-1;;5048:185:1:o;5641:470::-;5820:3;5858:6;5852:13;5874:53;5920:6;5915:3;5908:4;5900:6;5896:17;5874:53;:::i;:::-;5990:13;;5949:16;;;;6012:57;5990:13;5949:16;6046:4;6034:17;;6012:57;:::i;:::-;6085:20;;5641:470;-1:-1:-1;;;;5641:470:1:o;6116:1174::-;6292:3;6321:1;6354:6;6348:13;6384:3;6406:1;6434:9;6430:2;6426:18;6416:28;;6494:2;6483:9;6479:18;6516;6506:61;;6560:4;6552:6;6548:17;6538:27;;6506:61;6586:2;6634;6626:6;6623:14;6603:18;6600:38;6597:165;;;-1:-1:-1;;;6661:33:1;;6717:4;6714:1;6707:15;6747:4;6668:3;6735:17;6597:165;6778:18;6805:104;;;;6923:1;6918:320;;;;6771:467;;6805:104;-1:-1:-1;;6838:24:1;;6826:37;;6883:16;;;;-1:-1:-1;6805:104:1;;6918:320;17560:1;17553:14;;;17597:4;17584:18;;7013:1;7027:165;7041:6;7038:1;7035:13;7027:165;;;7119:14;;7106:11;;;7099:35;7162:16;;;;7056:10;;7027:165;;;7031:3;;7221:6;7216:3;7212:16;7205:23;;6771:467;;;;;;;7254:30;7280:3;7272:6;7254:30;:::i;:::-;7247:37;6116:1174;-1:-1:-1;;;;;6116:1174:1:o;7503:488::-;-1:-1:-1;;;;;7772:15:1;;;7754:34;;7824:15;;7819:2;7804:18;;7797:43;7871:2;7856:18;;7849:34;;;7919:3;7914:2;7899:18;;7892:31;;;7697:4;;7940:45;;7965:19;;7957:6;7940:45;:::i;:::-;7932:53;7503:488;-1:-1:-1;;;;;;7503:488:1:o;7996:632::-;8167:2;8219:21;;;8289:13;;8192:18;;;8311:22;;;8138:4;;8167:2;8390:15;;;;8364:2;8349:18;;;8138:4;8433:169;8447:6;8444:1;8441:13;8433:169;;;8508:13;;8496:26;;8577:15;;;;8542:12;;;;8469:1;8462:9;8433:169;;;-1:-1:-1;8619:3:1;;7996:632;-1:-1:-1;;;;;;7996:632:1:o;9007:219::-;9156:2;9145:9;9138:21;9119:4;9176:44;9216:2;9205:9;9201:18;9193:6;9176:44;:::i;9966:414::-;10168:2;10150:21;;;10207:2;10187:18;;;10180:30;10246:34;10241:2;10226:18;;10219:62;-1:-1:-1;;;10312:2:1;10297:18;;10290:48;10370:3;10355:19;;9966:414::o;14334:356::-;14536:2;14518:21;;;14555:18;;;14548:30;14614:34;14609:2;14594:18;;14587:62;14681:2;14666:18;;14334:356::o;16264:413::-;16466:2;16448:21;;;16505:2;16485:18;;;16478:30;16544:34;16539:2;16524:18;;16517:62;-1:-1:-1;;;16610:2:1;16595:18;;16588:47;16667:3;16652:19;;16264:413::o;16682:338::-;16884:2;16866:21;;;16923:2;16903:18;;;16896:30;-1:-1:-1;;;16957:2:1;16942:18;;16935:44;17011:2;16996:18;;16682:338::o;17207:275::-;17278:2;17272:9;17343:2;17324:13;;-1:-1:-1;;17320:27:1;17308:40;;17378:18;17363:34;;17399:22;;;17360:62;17357:88;;;17425:18;;:::i;:::-;17461:2;17454:22;17207:275;;-1:-1:-1;17207:275:1:o;17613:128::-;17653:3;17684:1;17680:6;17677:1;17674:13;17671:39;;;17690:18;;:::i;:::-;-1:-1:-1;17726:9:1;;17613:128::o;17746:120::-;17786:1;17812;17802:35;;17817:18;;:::i;:::-;-1:-1:-1;17851:9:1;;17746:120::o;17871:125::-;17911:4;17939:1;17936;17933:8;17930:34;;;17944:18;;:::i;:::-;-1:-1:-1;17981:9:1;;17871:125::o;18001:258::-;18073:1;18083:113;18097:6;18094:1;18091:13;18083:113;;;18173:11;;;18167:18;18154:11;;;18147:39;18119:2;18112:10;18083:113;;;18214:6;18211:1;18208:13;18205:48;;;-1:-1:-1;;18249:1:1;18231:16;;18224:27;18001:258::o;18264:380::-;18343:1;18339:12;;;;18386;;;18407:61;;18461:4;18453:6;18449:17;18439:27;;18407:61;18514:2;18506:6;18503:14;18483:18;18480:38;18477:161;;;18560:10;18555:3;18551:20;18548:1;18541:31;18595:4;18592:1;18585:15;18623:4;18620:1;18613:15;18649:135;18688:3;-1:-1:-1;;18709:17:1;;18706:43;;;18729:18;;:::i;:::-;-1:-1:-1;18776:1:1;18765:13;;18649:135::o;18789:112::-;18821:1;18847;18837:35;;18852:18;;:::i;:::-;-1:-1:-1;18886:9:1;;18789:112::o;18906:127::-;18967:10;18962:3;18958:20;18955:1;18948:31;18998:4;18995:1;18988:15;19022:4;19019:1;19012:15;19038:127;19099:10;19094:3;19090:20;19087:1;19080:31;19130:4;19127:1;19120:15;19154:4;19151:1;19144:15;19170:127;19231:10;19226:3;19222:20;19219:1;19212:31;19262:4;19259:1;19252:15;19286:4;19283:1;19276:15;19302:127;19363:10;19358:3;19354:20;19351:1;19344:31;19394:4;19391:1;19384:15;19418:4;19415:1;19408:15;19434:127;19495:10;19490:3;19486:20;19483:1;19476:31;19526:4;19523:1;19516:15;19550:4;19547:1;19540:15;19566:131;-1:-1:-1;;;;;;19640:32:1;;19630:43;;19620:71;;19687:1;19684;19677:12

Swarm Source

ipfs://38cb190f2d1f50aa2e181a49379fa19d040c142a914f85b8d390658918ea7929
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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