ETH Price: $3,492.32 (+6.49%)
Gas: 7 Gwei

Token

Ruler of the Land (ROTL)
 

Overview

Max Total Supply

5,000 ROTL

Holders

1,305

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
beyond-kim.eth
Balance
3 ROTL
0xe760b354f56048a1bf67a504380a5f82ac1fc0fd
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

"ROTL" is a Game PFP NFT connected to our Metaverse called MURIM. “Ruler of the Land (열혈강호)" is a legendary manhwa (comic) from South Korea with a global fan base amassing over one billion views, and running for over 28 years. It is also a well-known global game IP which multiple studios have produced and developed for. Holders will receive exclusive drops and perks for future ROTL NFT projects. Visit https://ROTL.io/ for more information on our web3 journey.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
ROTL

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 16 of 18: ROTL.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.4;

import "./ERC721A.sol";
import "./ERC721ABurnable.sol";
import "./ERC721AQueryable.sol";
import "./AccessControlEnumerable.sol";
import "./Ownable.sol";
import "./SafeMath.sol";

contract ROTL is AccessControlEnumerable, Ownable, ERC721A, ERC721ABurnable, ERC721AQueryable {
    using SafeMath for uint256;

    event SetBaseTokenURI(string uri);

    string private _baseTokenURI;
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    constructor() ERC721A("Ruler of the Land", "ROTL") {
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
    }

    function getFaction(uint256 id) external pure returns (uint256) {
        if (id < 5000) {
            return 1;
        } else if (id < 10000) {
            return 2;
        } else if (id < 15000) {
            return 3;
        } else if (id < 25000) {
            return 4;
        } else if (id < 35000) {
            return 5;
        }
        return 0;
    }

    function mint(uint256 faction, address to, uint256 quantity) external onlyRole(MINTER_ROLE) {
        if (faction == 1) {
            // darkstorm bringers
            require (totalSupply().add(quantity) <= 5000, "totalSupply().add(quantity) <= 5000");
        } else if (faction == 2) {
            // righteous faction
            require (totalSupply().add(quantity) <= 10000, "totalSupply().add(quantity) <= 10000");
        } else if (faction == 3) {
            // cult faction
            require (totalSupply().add(quantity) <= 15000, "totalSupply().add(quantity) <= 15000");
        } else if (faction == 4) {
            // the four outworld Hordes
            require (totalSupply().add(quantity) <= 25000, "totalSupply().add(quantity) <= 25000");
        } else {
            // sanctuary of the sword
            require (totalSupply().add(quantity) <= 35000, "totalSupply().add(quantity) <= 35000");
        }
        // _safeMint's second argument now takes in a quantity, not a tokenId.
        _safeMint(to, quantity);
    }

    function addMinter(address minter) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _setupRole(MINTER_ROLE, minter);
    }

    function setBaseTokenURI(string memory uri) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _baseTokenURI = uri;
        emit SetBaseTokenURI(uri);
    }

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

    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(AccessControlEnumerable, ERC721A)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

File 1 of 18: AccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (access/AccessControl.sol)

pragma solidity ^0.8.0;

import "./IAccessControl.sol";
import "./Context.sol";
import "./Strings.sol";
import "./ERC165.sol";

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role);
        _;
    }

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

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `_msgSender()` is missing `role`.
     * Overriding this function changes the behavior of the {onlyRole} modifier.
     *
     * Format of the revert message is described in {_checkRole}.
     *
     * _Available since v4.6._
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

File 2 of 18: AccessControlEnumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)

pragma solidity ^0.8.0;

import "./IAccessControlEnumerable.sol";
import "./AccessControl.sol";
import "./EnumerableSet.sol";

/**
 * @dev Extension of {AccessControl} that allows enumerating the members of each role.
 */
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
    using EnumerableSet for EnumerableSet.AddressSet;

    mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;

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

    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {
        return _roleMembers[role].at(index);
    }

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {
        return _roleMembers[role].length();
    }

    /**
     * @dev Overload {_grantRole} to track enumerable memberships
     */
    function _grantRole(bytes32 role, address account) internal virtual override {
        super._grantRole(role, account);
        _roleMembers[role].add(account);
    }

    /**
     * @dev Overload {_revokeRole} to track enumerable memberships
     */
    function _revokeRole(bytes32 role, address account) internal virtual override {
        super._revokeRole(role, account);
        _roleMembers[role].remove(account);
    }
}

File 3 of 18: Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 4 of 18: EnumerableSet.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/EnumerableSet.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

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

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

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

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

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

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

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

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

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

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

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

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

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

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

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

        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

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

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

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

        assembly {
            result := store
        }

        return result;
    }
}

File 5 of 18: ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 6 of 18: ERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721A.sol';

/**
 * @dev ERC721 token receiver interface.
 */
interface ERC721A__IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // The tokenId of the next token to be minted.
    uint256 internal _currentIndex;

    // The number of tokens burned.
    uint256 internal _burnCounter;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned. See _ownershipOf implementation for details.
    mapping(uint256 => TokenOwnership) internal _ownerships;

    // Mapping owner address to address data
    mapping(address => AddressData) private _addressData;

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

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _currentIndex = _startTokenId();
    }

    /**
     * To change the starting tokenId, please override this function.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 0;
    }

    /**
     * @dev Burned tokens are calculated here, use _totalMinted() if you want to count just minted tokens.
     */
    function totalSupply() public view override returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than _currentIndex - _startTokenId() times
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view returns (uint256) {
        // Counter underflow is impossible as _currentIndex does not decrement,
        // and it is initialized to _startTokenId()
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        // The interface IDs are constants representing the first 4 bytes of the XOR of 
        // all function selectors in the interface. See: https://eips.ethereum.org/EIPS/eip-165
        // e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return uint256(_addressData[owner].balance);
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return uint256(_addressData[owner].numberMinted);
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        return uint256(_addressData[owner].numberBurned);
    }

    /**
     * Returns the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return _addressData[owner].aux;
    }

    /**
     * Sets the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal {
        _addressData[owner].aux = aux;
    }

    /**
     * Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around in the collection over time.
     */
    function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr) if (curr < _currentIndex) {
                TokenOwnership memory ownership = _ownerships[curr];
                if (!ownership.burned) {
                    if (ownership.addr != address(0)) {
                        return ownership;
                    }
                    // Invariant:
                    // There will always be an ownership that has an address and is not burned
                    // before an ownership that does not have an address and is not burned.
                    // Hence, curr will not underflow.
                    while (true) {
                        curr--;
                        ownership = _ownerships[curr];
                        if (ownership.addr != address(0)) {
                            return ownership;
                        }
                    }
                }
            }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view override returns (address) {
        return _ownershipOf(tokenId).addr;
    }

    /**
     * @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) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        string memory baseURI = _baseURI();
        return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
    }

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

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public override {
        address owner = ERC721A.ownerOf(tokenId);
        if (to == owner) revert ApprovalToCurrentOwner();

        if (_msgSenderERC721A() != owner) if(!isApprovedForAll(owner, _msgSenderERC721A())) {
            revert ApprovalCallerNotOwnerNorApproved();
        }

        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        if (operator == _msgSenderERC721A()) revert ApproveToCaller();

        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), 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 {
        _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 {
        _transfer(from, to, tokenId);
        if (to.code.length != 0) if(!_checkContractOnERC721Received(from, to, tokenId, _data)) {
            revert TransferToNonERC721ReceiverImplementer();
        }
    }

    /**
     * @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`),
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return _startTokenId() <= tokenId && tokenId < _currentIndex && !_ownerships[tokenId].burned;
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, '');
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement
     *   {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            if (to.code.length != 0) {
                do {
                    emit Transfer(address(0), to, updatedIndex);
                    if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (updatedIndex < end);
                // Reentrancy protection
                if (_currentIndex != startTokenId) revert();
            } else {
                do {
                    emit Transfer(address(0), to, updatedIndex++);
                } while (updatedIndex < end);
            }
            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 quantity) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            do {
                emit Transfer(address(0), to, updatedIndex++);
            } while (updatedIndex < end);

            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * 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
    ) private {
        TokenOwnership memory prevOwnership = _ownershipOf(tokenId);

        if (prevOwnership.addr != from) revert TransferFromIncorrectOwner();

        bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
            isApprovedForAll(from, _msgSenderERC721A()) ||
            getApproved(tokenId) == _msgSenderERC721A());

        if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

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

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            _addressData[from].balance -= 1;
            _addressData[to].balance += 1;

            TokenOwnership storage currSlot = _ownerships[tokenId];
            currSlot.addr = to;
            currSlot.startTimestamp = uint64(block.timestamp);

            // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            TokenOwnership storage nextSlot = _ownerships[nextTokenId];
            if (nextSlot.addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId != _currentIndex) {
                    nextSlot.addr = from;
                    nextSlot.startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

        emit Transfer(from, to, tokenId);
        _afterTokenTransfers(from, to, tokenId, 1);
    }

    /**
     * @dev Equivalent to `_burn(tokenId, false)`.
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
        TokenOwnership memory prevOwnership = _ownershipOf(tokenId);

        address from = prevOwnership.addr;

        if (approvalCheck) {
            bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
                isApprovedForAll(from, _msgSenderERC721A()) ||
                getApproved(tokenId) == _msgSenderERC721A());

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

        _beforeTokenTransfers(from, address(0), tokenId, 1);

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

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            AddressData storage addressData = _addressData[from];
            addressData.balance -= 1;
            addressData.numberBurned += 1;

            // Keep track of who burned the token, and the timestamp of burning.
            TokenOwnership storage currSlot = _ownerships[tokenId];
            currSlot.addr = from;
            currSlot.startTimestamp = uint64(block.timestamp);
            currSlot.burned = true;

            // If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            TokenOwnership storage nextSlot = _ownerships[nextTokenId];
            if (nextSlot.addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId != _currentIndex) {
                    nextSlot.addr = from;
                    nextSlot.startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target 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 _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) 
        returns (bytes4 retval) {
            return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    /**
     * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
     * And also called before burning one token.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * 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, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes
     * minting.
     * And also called after one token has been burned.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Returns the message sender (defaults to `msg.sender`).
     * 
     * If you are writing GSN compatible contracts, you need to override this function.
     */
    function _msgSenderERC721A() internal view virtual returns (address) {
        return msg.sender;
    }

    /**
     * @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
        unchecked {
            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;
                buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
                value /= 10;
            }
            return string(buffer);    
        }
    }
}

File 7 of 18: ERC721ABurnable.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721ABurnable.sol';
import './ERC721A.sol';

/**
 * @title ERC721A Burnable Token
 * @dev ERC721A Token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721ABurnable is ERC721A, IERC721ABurnable {
    /**
     * @dev Burns `tokenId`. See {ERC721A-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual override {
        _burn(tokenId, true);
    }
}

File 8 of 18: ERC721AQueryable.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721AQueryable.sol';
import './ERC721A.sol';

/**
 * @title ERC721A Queryable
 * @dev ERC721A subclass with convenience query functions.
 */
abstract contract ERC721AQueryable is ERC721A, IERC721AQueryable {
    /**
     * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
     *
     * If the `tokenId` is out of bounds:
     *   - `addr` = `address(0)`
     *   - `startTimestamp` = `0`
     *   - `burned` = `false`
     *
     * If the `tokenId` is burned:
     *   - `addr` = `<Address of owner before token was burned>`
     *   - `startTimestamp` = `<Timestamp when token was burned>`
     *   - `burned = `true`
     *
     * Otherwise:
     *   - `addr` = `<Address of owner>`
     *   - `startTimestamp` = `<Timestamp of start of ownership>`
     *   - `burned = `false`
     */
    function explicitOwnershipOf(uint256 tokenId) public view override returns (TokenOwnership memory) {
        TokenOwnership memory ownership;
        if (tokenId < _startTokenId() || tokenId >= _currentIndex) {
            return ownership;
        }
        ownership = _ownerships[tokenId];
        if (ownership.burned) {
            return ownership;
        }
        return _ownershipOf(tokenId);
    }

    /**
     * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
     * See {ERC721AQueryable-explicitOwnershipOf}
     */
    function explicitOwnershipsOf(uint256[] memory tokenIds) external view override returns (TokenOwnership[] memory) {
        unchecked {
            uint256 tokenIdsLength = tokenIds.length;
            TokenOwnership[] memory ownerships = new TokenOwnership[](tokenIdsLength);
            for (uint256 i; i != tokenIdsLength; ++i) {
                ownerships[i] = explicitOwnershipOf(tokenIds[i]);
            }
            return ownerships;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start` < `stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) external view override returns (uint256[] memory) {
        unchecked {
            if (start >= stop) revert InvalidQueryRange();
            uint256 tokenIdsIdx;
            uint256 stopLimit = _currentIndex;
            // Set `start = max(start, _startTokenId())`.
            if (start < _startTokenId()) {
                start = _startTokenId();
            }
            // Set `stop = min(stop, _currentIndex)`.
            if (stop > stopLimit) {
                stop = stopLimit;
            }
            uint256 tokenIdsMaxLength = balanceOf(owner);
            // Set `tokenIdsMaxLength = min(balanceOf(owner), stop - start)`,
            // to cater for cases where `balanceOf(owner)` is too big.
            if (start < stop) {
                uint256 rangeLength = stop - start;
                if (rangeLength < tokenIdsMaxLength) {
                    tokenIdsMaxLength = rangeLength;
                }
            } else {
                tokenIdsMaxLength = 0;
            }
            uint256[] memory tokenIds = new uint256[](tokenIdsMaxLength);
            if (tokenIdsMaxLength == 0) {
                return tokenIds;
            }
            // We need to call `explicitOwnershipOf(start)`,
            // because the slot at `start` may not be initialized.
            TokenOwnership memory ownership = explicitOwnershipOf(start);
            address currOwnershipAddr;
            // If the starting slot exists (i.e. not burned), initialize `currOwnershipAddr`.
            // `ownership.address` will not be zero, as `start` is clamped to the valid token ID range.
            if (!ownership.burned) {
                currOwnershipAddr = ownership.addr;
            }
            for (uint256 i = start; i != stop && tokenIdsIdx != tokenIdsMaxLength; ++i) {
                ownership = _ownerships[i];
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            // Downsize the array to fit.
            assembly {
                mstore(tokenIds, tokenIdsIdx)
            }
            return tokenIds;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(totalSupply) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K pfp collections should be fine).
     */
    function tokensOfOwner(address owner) external view override returns (uint256[] memory) {
        unchecked {
            uint256 tokenIdsIdx;
            address currOwnershipAddr;
            uint256 tokenIdsLength = balanceOf(owner);
            uint256[] memory tokenIds = new uint256[](tokenIdsLength);
            TokenOwnership memory ownership;
            for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) {
                ownership = _ownerships[i];
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            return tokenIds;
        }
    }
}

File 9 of 18: IAccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

File 10 of 18: IAccessControlEnumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)

pragma solidity ^0.8.0;

import "./IAccessControl.sol";

/**
 * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
 */
interface IAccessControlEnumerable is IAccessControl {
    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) external view returns (address);

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) external view returns (uint256);
}

File 11 of 18: IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

File 12 of 18: IERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

/**
 * @dev Interface of an ERC721A compliant contract.
 */
interface IERC721A {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

    /**
     * The token does not exist.
     */
    error ApprovalQueryForNonexistentToken();

    /**
     * The caller cannot approve to their own address.
     */
    error ApproveToCaller();

    /**
     * The caller cannot approve to the current owner.
     */
    error ApprovalToCurrentOwner();

    /**
     * Cannot query the balance for the zero address.
     */
    error BalanceQueryForZeroAddress();

    /**
     * Cannot mint to the zero address.
     */
    error MintToZeroAddress();

    /**
     * The quantity of tokens minted must be more than zero.
     */
    error MintZeroQuantity();

    /**
     * The token does not exist.
     */
    error OwnerQueryForNonexistentToken();

    /**
     * The caller must own the token or be an approved operator.
     */
    error TransferCallerNotOwnerNorApproved();

    /**
     * The token must be owned by `from`.
     */
    error TransferFromIncorrectOwner();

    /**
     * Cannot safely transfer to a contract that does not implement the ERC721Receiver interface.
     */
    error TransferToNonERC721ReceiverImplementer();

    /**
     * Cannot transfer to the zero address.
     */
    error TransferToZeroAddress();

    /**
     * The token does not exist.
     */
    error URIQueryForNonexistentToken();

    // Compiler will pack this into a single 256bit word.
    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
    }

    // Compiler will pack this into a single 256bit word.
    struct AddressData {
        // Realistically, 2**64-1 is more than enough.
        uint64 balance;
        // Keeps track of mint count with minimal overhead for tokenomics.
        uint64 numberMinted;
        // Keeps track of burn count with minimal overhead for tokenomics.
        uint64 numberBurned;
        // For miscellaneous variable(s) pertaining to the address
        // (e.g. number of whitelist mint slots used).
        // If there are multiple variables, please pack them into a uint64.
        uint64 aux;
    }

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     * 
     * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens.
     */
    function totalSupply() external view returns (uint256);

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

    // ==============================
    //            IERC721
    // ==============================

    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must 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 Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

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

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

    // ==============================
    //        IERC721Metadata
    // ==============================

    /**
     * @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 13 of 18: IERC721ABurnable.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721A.sol';

/**
 * @dev Interface of an ERC721ABurnable compliant contract.
 */
interface IERC721ABurnable is IERC721A {
    /**
     * @dev Burns `tokenId`. See {ERC721A-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) external;
}

File 14 of 18: IERC721AQueryable.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721A.sol';

/**
 * @dev Interface of an ERC721AQueryable compliant contract.
 */
interface IERC721AQueryable is IERC721A {
    /**
     * Invalid query range (`start` >= `stop`).
     */
    error InvalidQueryRange();

    /**
     * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
     *
     * If the `tokenId` is out of bounds:
     *   - `addr` = `address(0)`
     *   - `startTimestamp` = `0`
     *   - `burned` = `false`
     *
     * If the `tokenId` is burned:
     *   - `addr` = `<Address of owner before token was burned>`
     *   - `startTimestamp` = `<Timestamp when token was burned>`
     *   - `burned = `true`
     *
     * Otherwise:
     *   - `addr` = `<Address of owner>`
     *   - `startTimestamp` = `<Timestamp of start of ownership>`
     *   - `burned = `false`
     */
    function explicitOwnershipOf(uint256 tokenId) external view returns (TokenOwnership memory);

    /**
     * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
     * See {ERC721AQueryable-explicitOwnershipOf}
     */
    function explicitOwnershipsOf(uint256[] memory tokenIds) external view returns (TokenOwnership[] memory);

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start` < `stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) external view returns (uint256[] memory);

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(totalSupply) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K pfp collections should be fine).
     */
    function tokensOfOwner(address owner) external view returns (uint256[] memory);
}

File 15 of 18: Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "./Context.sol";

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

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

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

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

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

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

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

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

File 17 of 18: SafeMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (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 generally not needed starting with Solidity 0.8, since 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 subtraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

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

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

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

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

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

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

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

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

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

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

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

File 18 of 18: Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"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":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"uri","type":"string"}],"name":"SetBaseTokenURI","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":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"addMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getFaction","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","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":[{"internalType":"uint256","name":"faction","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setBaseTokenURI","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":"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":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","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"}]

60806040523480156200001157600080fd5b5060405180604001604052806011815260200170149d5b195c881bd9881d1a194813185b99607a1b815250604051806040016040528060048152602001631493d51360e21b815250620000736200006d620000ba60201b60201c565b620000be565b81516200008890600590602085019062000275565b5080516200009e90600690602084019062000275565b50600060035550620000b4905060003362000110565b62000358565b3390565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6200011c828262000120565b5050565b6200013782826200016360201b620013491760201c565b60008281526001602090815260409091206200015e918390620013cd62000203821b17901c565b505050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166200011c576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620001bf3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006200021a836001600160a01b03841662000223565b90505b92915050565b60008181526001830160205260408120546200026c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200021d565b5060006200021d565b82805462000283906200031b565b90600052602060002090601f016020900481019282620002a75760008555620002f2565b82601f10620002c257805160ff1916838001178555620002f2565b82800160010185558215620002f2579182015b82811115620002f2578251825591602001919060010190620002d5565b506200030092915062000304565b5090565b5b8082111562000300576000815560010162000305565b600181811c908216806200033057607f821691505b602082108114156200035257634e487b7160e01b600052602260045260246000fd5b50919050565b61297580620003686000396000f3fe608060405234801561001057600080fd5b50600436106102115760003560e01c80638462151c11610125578063a8a150b8116100ad578063ca15c8731161007c578063ca15c87314610498578063d5391393146104ab578063d547741f146104d2578063e985e9c5146104e5578063f2fde38b1461052157600080fd5b8063a8a150b81461043f578063b88d4fde14610452578063c23dc68f14610465578063c87b56dd1461048557600080fd5b806395d89b41116100f457806395d89b41146103f6578063983b2d56146103fe57806399a2557a14610411578063a217fddf14610424578063a22cb4651461042c57600080fd5b80638462151c1461039f5780638da5cb5b146103bf5780639010d07c146103d057806391d14854146103e357600080fd5b806330176e13116101a85780635bbb2177116101775780635bbb21771461033e5780636352211e1461035e57806370a0823114610371578063715018a614610384578063836a10401461038c57600080fd5b806330176e13146102f257806336568abe1461030557806342842e0e1461031857806342966c681461032b57600080fd5b806318160ddd116101e457806318160ddd1461029357806323b872dd146102a9578063248a9ca3146102bc5780632f2ff15d146102df57600080fd5b806301ffc9a71461021657806306fdde031461023e578063081812fc14610253578063095ea7b31461027e575b600080fd5b610229610224366004612517565b610534565b60405190151581526020015b60405180910390f35b610246610545565b604051610235919061276d565b6102666102613660046124b9565b6105d7565b6040516001600160a01b039091168152602001610235565b61029161028c3660046123b0565b61061b565b005b600454600354035b604051908152602001610235565b6102916102b73660046122bd565b6106ee565b61029b6102ca3660046124b9565b60009081526020819052604090206001015490565b6102916102ed3660046124d2565b6106fe565b610291610300366004612551565b610723565b6102916103133660046124d2565b61077d565b6102916103263660046122bd565b610800565b6102916103393660046124b9565b61081b565b61035161034c36600461240d565b610829565b60405161023591906126cb565b61026661036c3660046124b9565b6108ef565b61029b61037f36600461226f565b610901565b61029161094f565b61029161039a366004612599565b6109b5565b6103b26103ad36600461226f565b610c44565b6040516102359190612735565b6002546001600160a01b0316610266565b6102666103de3660046124f5565b610d91565b6102296103f13660046124d2565b610db0565b610246610dd9565b61029161040c36600461226f565b610de8565b6103b261041f3660046123da565b610e1d565b61029b600081565b61029161043a366004612374565b610fd5565b61029b61044d3660046124b9565b61106b565b6102916104603660046122f9565b6110cf565b6104786104733660046124b9565b611113565b6040516102359190612780565b6102466104933660046124b9565b6111c1565b61029b6104a63660046124b9565b611245565b61029b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6102916104e03660046124d2565b61125c565b6102296104f336600461228a565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205460ff1690565b61029161052f36600461226f565b611281565b600061053f826113e2565b92915050565b60606005805461055490612876565b80601f016020809104026020016040519081016040528092919081815260200182805461058090612876565b80156105cd5780601f106105a2576101008083540402835291602001916105cd565b820191906000526020600020905b8154815290600101906020018083116105b057829003601f168201915b5050505050905090565b60006105e282611430565b6105ff576040516333d1c03960e21b815260040160405180910390fd5b506000908152600960205260409020546001600160a01b031690565b6000610626826108ef565b9050806001600160a01b0316836001600160a01b0316141561065b5760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b038216146106925761067581336104f3565b610692576040516367d9dca160e11b815260040160405180910390fd5b60008281526009602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6106f983838361145c565b505050565b60008281526020819052604090206001015461071981611646565b6106f98383611650565b600061072e81611646565b815161074190600b906020850190612163565b507f199e933997358e1789d8b56ea8c551befeb05ce2fe3fe506199f1230f5a591b482604051610771919061276d565b60405180910390a15050565b6001600160a01b03811633146107f25760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6107fc8282611672565b5050565b6106f9838383604051806020016040528060008152506110cf565b610826816001611694565b50565b80516060906000816001600160401b03811115610848576108486128f3565b60405190808252806020026020018201604052801561089357816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816108665790505b50905060005b8281146108e7576108c28582815181106108b5576108b56128dd565b6020026020010151611113565b8282815181106108d4576108d46128dd565b6020908102919091010152600101610899565b509392505050565b60006108fa82611857565b5192915050565b60006001600160a01b03821661092a576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600860205260409020546001600160401b031690565b6002546001600160a01b031633146109a95760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107e9565b6109b36000611971565b565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66109df81611646565b8360011415610a6157611388610a02836109fc6004546003540390565b906119c3565b1115610a5c5760405162461bcd60e51b815260206004820152602360248201527f746f74616c537570706c7928292e616464287175616e7469747929203c3d203560448201526203030360ec1b60648201526084016107e9565b610c34565b8360021415610ad857612710610a7e836109fc6004546003540390565b1115610a5c5760405162461bcd60e51b8152602060048201526024808201527f746f74616c537570706c7928292e616464287175616e7469747929203c3d20316044820152630303030360e41b60648201526084016107e9565b8360031415610b4f57613a98610af5836109fc6004546003540390565b1115610a5c5760405162461bcd60e51b8152602060048201526024808201527f746f74616c537570706c7928292e616464287175616e7469747929203c3d20316044820152630353030360e41b60648201526084016107e9565b8360041415610bc6576161a8610b6c836109fc6004546003540390565b1115610a5c5760405162461bcd60e51b8152602060048201526024808201527f746f74616c537570706c7928292e616464287175616e7469747929203c3d20326044820152630353030360e41b60648201526084016107e9565b6188b8610bda836109fc6004546003540390565b1115610c345760405162461bcd60e51b8152602060048201526024808201527f746f74616c537570706c7928292e616464287175616e7469747929203c3d20336044820152630353030360e41b60648201526084016107e9565b610c3e83836119cf565b50505050565b60606000806000610c5485610901565b90506000816001600160401b03811115610c7057610c706128f3565b604051908082528060200260200182016040528015610c99578160200160208202803683370190505b509050610cbf604080516060810182526000808252602082018190529181019190915290565b60005b838614610d8557600081815260076020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff16158015928201929092529250610d2857610d7d565b81516001600160a01b031615610d3d57815194505b876001600160a01b0316856001600160a01b03161415610d7d5780838780600101985081518110610d7057610d706128dd565b6020026020010181815250505b600101610cc2565b50909695505050505050565b6000828152600160205260408120610da990836119e9565b9392505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b60606006805461055490612876565b6000610df381611646565b6107fc7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6836119f5565b6060818310610e3f57604051631960ccad60e11b815260040160405180910390fd5b60035460009080841115610e51578093505b6000610e5c87610901565b905084861015610e7b5785850381811015610e75578091505b50610e7f565b5060005b6000816001600160401b03811115610e9957610e996128f3565b604051908082528060200260200182016040528015610ec2578160200160208202803683370190505b50905081610ed5579350610da992505050565b6000610ee088611113565b905060008160400151610ef1575080515b885b888114158015610f035750848714155b15610fc457600081815260076020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff16158015928201929092529350610f6757610fbc565b82516001600160a01b031615610f7c57825191505b8a6001600160a01b0316826001600160a01b03161415610fbc5780848880600101995081518110610faf57610faf6128dd565b6020026020010181815250505b600101610ef3565b505050928352509095945050505050565b6001600160a01b038216331415610fff5760405163b06307db60e01b815260040160405180910390fd5b336000818152600a602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600061138882101561107f57506001919050565b61271082101561109157506002919050565b613a988210156110a357506003919050565b6161a88210156110b557506004919050565b6188b88210156110c757506005919050565b506000919050565b6110da84848461145c565b6001600160a01b0383163b15610c3e576110f6848484846119ff565b610c3e576040516368d2bf6b60e11b815260040160405180910390fd5b60408051606080820183526000808352602080840182905283850182905284519283018552818352820181905292810183905290915060035483106111585792915050565b50600082815260076020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff1615801592820192909252906111b85792915050565b610da983611857565b60606111cc82611430565b6111e957604051630a14c4b560e41b815260040160405180910390fd5b60006111f3611af7565b90508051600014156112145760405180602001604052806000815250610da9565b8061121e84611b06565b60405160200161122f9291906125ea565b6040516020818303038152906040529392505050565b600081815260016020526040812061053f90611bd5565b60008281526020819052604090206001015461127781611646565b6106f98383611672565b6002546001600160a01b031633146112db5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107e9565b6001600160a01b0381166113405760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107e9565b61082681611971565b6113538282610db0565b6107fc576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556113893390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610da9836001600160a01b038416611bdf565b60006301ffc9a760e01b6001600160e01b03198316148061141357506380ac58cd60e01b6001600160e01b03198316145b8061053f5750506001600160e01b031916635b5e139f60e01b1490565b60006003548210801561053f575050600090815260076020526040902054600160e01b900460ff161590565b600061146782611857565b9050836001600160a01b031681600001516001600160a01b03161461149e5760405162a1148160e81b815260040160405180910390fd5b6000336001600160a01b03861614806114bc57506114bc85336104f3565b806114d75750336114cc846105d7565b6001600160a01b0316145b9050806114f757604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b03841661151e57604051633a954ecd60e21b815260040160405180910390fd5b600083815260096020908152604080832080546001600160a01b03191690556001600160a01b03888116845260088352818420805467ffffffffffffffff198082166001600160401b0392831660001901831617909255898316808752848720805493841693831660019081018416949094179055898752600790955283862080546001600160e01b031916909517600160a01b429092169190910217845587018085529190932080549293919290911661160d57600354821461160d57805460208601516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038a16171781555b50505082846001600160a01b0316866001600160a01b031660008051602061292083398151915260405160405180910390a45050505050565b6108268133611c2e565b61165a8282611349565b60008281526001602052604090206106f990826113cd565b61167c8282611c92565b60008281526001602052604090206106f99082611cf7565b600061169f83611857565b80519091508215611705576000336001600160a01b03831614806116c857506116c882336104f3565b806116e35750336116d8866105d7565b6001600160a01b0316145b90508061170357604051632ce44b5f60e11b815260040160405180910390fd5b505b600084815260096020908152604080832080546001600160a01b03191690556001600160a01b03848116808552600884528285208054600160801b6000196001600160401b0380841691909101811667ffffffffffffffff198416811783900482166001908101831690930277ffffffffffffffff0000000000000000ffffffffffffffff19909416179290921783558b88526007909652848720805460ff60e01b1942909316600160a01b026001600160e01b03199091169094179390931716600160e01b17825593890180865292909420805493949390911661181e57600354821461181e57805460208701516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038716171781555b5050604051869250600091506001600160a01b03841690600080516020612920833981519152908390a450506004805460010190555050565b60408051606081018252600080825260208201819052918101919091528160035481101561195857600081815260076020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161515918101829052906119565780516001600160a01b0316156118ed579392505050565b5060001901600081815260076020908152604091829020825160608101845290546001600160a01b038116808352600160a01b82046001600160401b031693830193909352600160e01b900460ff1615159281019290925215611951579392505050565b6118ed565b505b604051636f96cda160e11b815260040160405180910390fd5b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610da982846127e5565b6107fc828260405180602001604052806000815250611d0c565b6000610da98383611eab565b6107fc8282611650565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611a3490339089908890889060040161268e565b602060405180830381600087803b158015611a4e57600080fd5b505af1925050508015611a7e575060408051601f3d908101601f19168201909252611a7b91810190612534565b60015b611ad9573d808015611aac576040519150601f19603f3d011682016040523d82523d6000602084013e611ab1565b606091505b508051611ad1576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6060600b805461055490612876565b606081611b2a5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611b4257600101600a82049150611b2e565b6000816001600160401b03811115611b5c57611b5c6128f3565b6040519080825280601f01601f191660200182016040528015611b86576020820181803683370190505b5090505b8415611aef5760001990910190600a850660300160f81b818381518110611bb357611bb36128dd565b60200101906001600160f81b031916908160001a905350600a85049450611b8a565b600061053f825490565b6000818152600183016020526040812054611c265750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561053f565b50600061053f565b611c388282610db0565b6107fc57611c50816001600160a01b03166014611ed5565b611c5b836020611ed5565b604051602001611c6c929190612619565b60408051601f198184030181529082905262461bcd60e51b82526107e99160040161276d565b611c9c8282610db0565b156107fc576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610da9836001600160a01b038416612070565b6003546001600160a01b038416611d3557604051622e076360e81b815260040160405180910390fd5b82611d535760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038416600081815260086020908152604080832080546fffffffffffffffffffffffffffffffff1981166001600160401b038083168b0181169182176801000000000000000067ffffffffffffffff1990941690921783900481168b01811690920217909155858452600790925290912080546001600160e01b0319168317600160a01b42909316929092029190911790558190818501903b15611e69575b60405182906001600160a01b03881690600090600080516020612920833981519152908290a4611e3260008784806001019550876119ff565b611e4f576040516368d2bf6b60e11b815260040160405180910390fd5b808210611df9578260035414611e6457600080fd5b611e9c565b5b6040516001830192906001600160a01b03881690600090600080516020612920833981519152908290a4808210611e6a575b50600355610c3e600085838684565b6000826000018281548110611ec257611ec26128dd565b9060005260206000200154905092915050565b60606000611ee48360026127fd565b611eef9060026127e5565b6001600160401b03811115611f0657611f066128f3565b6040519080825280601f01601f191660200182016040528015611f30576020820181803683370190505b509050600360fc1b81600081518110611f4b57611f4b6128dd565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611f7a57611f7a6128dd565b60200101906001600160f81b031916908160001a9053506000611f9e8460026127fd565b611fa99060016127e5565b90505b6001811115612021576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110611fdd57611fdd6128dd565b1a60f81b828281518110611ff357611ff36128dd565b60200101906001600160f81b031916908160001a90535060049490941c9361201a8161285f565b9050611fac565b508315610da95760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016107e9565b6000818152600183016020526040812054801561215957600061209460018361281c565b85549091506000906120a89060019061281c565b905081811461210d5760008660000182815481106120c8576120c86128dd565b90600052602060002001549050808760000184815481106120eb576120eb6128dd565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061211e5761211e6128c7565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061053f565b600091505061053f565b82805461216f90612876565b90600052602060002090601f01602090048101928261219157600085556121d7565b82601f106121aa57805160ff19168380011785556121d7565b828001600101855582156121d7579182015b828111156121d75782518255916020019190600101906121bc565b506121e39291506121e7565b5090565b5b808211156121e357600081556001016121e8565b60006001600160401b03831115612215576122156128f3565b612228601f8401601f19166020016127b5565b905082815283838301111561223c57600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b038116811461226a57600080fd5b919050565b60006020828403121561228157600080fd5b610da982612253565b6000806040838503121561229d57600080fd5b6122a683612253565b91506122b460208401612253565b90509250929050565b6000806000606084860312156122d257600080fd5b6122db84612253565b92506122e960208501612253565b9150604084013590509250925092565b6000806000806080858703121561230f57600080fd5b61231885612253565b935061232660208601612253565b92506040850135915060608501356001600160401b0381111561234857600080fd5b8501601f8101871361235957600080fd5b612368878235602084016121fc565b91505092959194509250565b6000806040838503121561238757600080fd5b61239083612253565b9150602083013580151581146123a557600080fd5b809150509250929050565b600080604083850312156123c357600080fd5b6123cc83612253565b946020939093013593505050565b6000806000606084860312156123ef57600080fd5b6123f884612253565b95602085013595506040909401359392505050565b6000602080838503121561242057600080fd5b82356001600160401b038082111561243757600080fd5b818501915085601f83011261244b57600080fd5b81358181111561245d5761245d6128f3565b8060051b915061246e8483016127b5565b8181528481019084860184860187018a101561248957600080fd5b600095505b838610156124ac57803583526001959095019491860191860161248e565b5098975050505050505050565b6000602082840312156124cb57600080fd5b5035919050565b600080604083850312156124e557600080fd5b823591506122b460208401612253565b6000806040838503121561250857600080fd5b50508035926020909101359150565b60006020828403121561252957600080fd5b8135610da981612909565b60006020828403121561254657600080fd5b8151610da981612909565b60006020828403121561256357600080fd5b81356001600160401b0381111561257957600080fd5b8201601f8101841361258a57600080fd5b611aef848235602084016121fc565b6000806000606084860312156125ae57600080fd5b833592506122e960208501612253565b600081518084526125d6816020860160208601612833565b601f01601f19169290920160200192915050565b600083516125fc818460208801612833565b835190830190612610818360208801612833565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612651816017850160208801612833565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612682816028840160208801612833565b01602801949350505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906126c1908301846125be565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015610d855761272283855180516001600160a01b031682526020808201516001600160401b0316908301526040908101511515910152565b92840192606092909201916001016126e7565b6020808252825182820181905260009190848201906040850190845b81811015610d8557835183529284019291840191600101612751565b602081526000610da960208301846125be565b81516001600160a01b031681526020808301516001600160401b0316908201526040808301511515908201526060810161053f565b604051601f8201601f191681016001600160401b03811182821017156127dd576127dd6128f3565b604052919050565b600082198211156127f8576127f86128b1565b500190565b6000816000190483118215151615612817576128176128b1565b500290565b60008282101561282e5761282e6128b1565b500390565b60005b8381101561284e578181015183820152602001612836565b83811115610c3e5750506000910152565b60008161286e5761286e6128b1565b506000190190565b600181811c9082168061288a57607f821691505b602082108114156128ab57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b03198116811461082657600080fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212205459dc71e59dca223b53188e174168f5e4a8070a51d37feb096b55145ebd280964736f6c63430008070033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102115760003560e01c80638462151c11610125578063a8a150b8116100ad578063ca15c8731161007c578063ca15c87314610498578063d5391393146104ab578063d547741f146104d2578063e985e9c5146104e5578063f2fde38b1461052157600080fd5b8063a8a150b81461043f578063b88d4fde14610452578063c23dc68f14610465578063c87b56dd1461048557600080fd5b806395d89b41116100f457806395d89b41146103f6578063983b2d56146103fe57806399a2557a14610411578063a217fddf14610424578063a22cb4651461042c57600080fd5b80638462151c1461039f5780638da5cb5b146103bf5780639010d07c146103d057806391d14854146103e357600080fd5b806330176e13116101a85780635bbb2177116101775780635bbb21771461033e5780636352211e1461035e57806370a0823114610371578063715018a614610384578063836a10401461038c57600080fd5b806330176e13146102f257806336568abe1461030557806342842e0e1461031857806342966c681461032b57600080fd5b806318160ddd116101e457806318160ddd1461029357806323b872dd146102a9578063248a9ca3146102bc5780632f2ff15d146102df57600080fd5b806301ffc9a71461021657806306fdde031461023e578063081812fc14610253578063095ea7b31461027e575b600080fd5b610229610224366004612517565b610534565b60405190151581526020015b60405180910390f35b610246610545565b604051610235919061276d565b6102666102613660046124b9565b6105d7565b6040516001600160a01b039091168152602001610235565b61029161028c3660046123b0565b61061b565b005b600454600354035b604051908152602001610235565b6102916102b73660046122bd565b6106ee565b61029b6102ca3660046124b9565b60009081526020819052604090206001015490565b6102916102ed3660046124d2565b6106fe565b610291610300366004612551565b610723565b6102916103133660046124d2565b61077d565b6102916103263660046122bd565b610800565b6102916103393660046124b9565b61081b565b61035161034c36600461240d565b610829565b60405161023591906126cb565b61026661036c3660046124b9565b6108ef565b61029b61037f36600461226f565b610901565b61029161094f565b61029161039a366004612599565b6109b5565b6103b26103ad36600461226f565b610c44565b6040516102359190612735565b6002546001600160a01b0316610266565b6102666103de3660046124f5565b610d91565b6102296103f13660046124d2565b610db0565b610246610dd9565b61029161040c36600461226f565b610de8565b6103b261041f3660046123da565b610e1d565b61029b600081565b61029161043a366004612374565b610fd5565b61029b61044d3660046124b9565b61106b565b6102916104603660046122f9565b6110cf565b6104786104733660046124b9565b611113565b6040516102359190612780565b6102466104933660046124b9565b6111c1565b61029b6104a63660046124b9565b611245565b61029b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6102916104e03660046124d2565b61125c565b6102296104f336600461228a565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205460ff1690565b61029161052f36600461226f565b611281565b600061053f826113e2565b92915050565b60606005805461055490612876565b80601f016020809104026020016040519081016040528092919081815260200182805461058090612876565b80156105cd5780601f106105a2576101008083540402835291602001916105cd565b820191906000526020600020905b8154815290600101906020018083116105b057829003601f168201915b5050505050905090565b60006105e282611430565b6105ff576040516333d1c03960e21b815260040160405180910390fd5b506000908152600960205260409020546001600160a01b031690565b6000610626826108ef565b9050806001600160a01b0316836001600160a01b0316141561065b5760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b038216146106925761067581336104f3565b610692576040516367d9dca160e11b815260040160405180910390fd5b60008281526009602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6106f983838361145c565b505050565b60008281526020819052604090206001015461071981611646565b6106f98383611650565b600061072e81611646565b815161074190600b906020850190612163565b507f199e933997358e1789d8b56ea8c551befeb05ce2fe3fe506199f1230f5a591b482604051610771919061276d565b60405180910390a15050565b6001600160a01b03811633146107f25760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6107fc8282611672565b5050565b6106f9838383604051806020016040528060008152506110cf565b610826816001611694565b50565b80516060906000816001600160401b03811115610848576108486128f3565b60405190808252806020026020018201604052801561089357816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816108665790505b50905060005b8281146108e7576108c28582815181106108b5576108b56128dd565b6020026020010151611113565b8282815181106108d4576108d46128dd565b6020908102919091010152600101610899565b509392505050565b60006108fa82611857565b5192915050565b60006001600160a01b03821661092a576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600860205260409020546001600160401b031690565b6002546001600160a01b031633146109a95760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107e9565b6109b36000611971565b565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66109df81611646565b8360011415610a6157611388610a02836109fc6004546003540390565b906119c3565b1115610a5c5760405162461bcd60e51b815260206004820152602360248201527f746f74616c537570706c7928292e616464287175616e7469747929203c3d203560448201526203030360ec1b60648201526084016107e9565b610c34565b8360021415610ad857612710610a7e836109fc6004546003540390565b1115610a5c5760405162461bcd60e51b8152602060048201526024808201527f746f74616c537570706c7928292e616464287175616e7469747929203c3d20316044820152630303030360e41b60648201526084016107e9565b8360031415610b4f57613a98610af5836109fc6004546003540390565b1115610a5c5760405162461bcd60e51b8152602060048201526024808201527f746f74616c537570706c7928292e616464287175616e7469747929203c3d20316044820152630353030360e41b60648201526084016107e9565b8360041415610bc6576161a8610b6c836109fc6004546003540390565b1115610a5c5760405162461bcd60e51b8152602060048201526024808201527f746f74616c537570706c7928292e616464287175616e7469747929203c3d20326044820152630353030360e41b60648201526084016107e9565b6188b8610bda836109fc6004546003540390565b1115610c345760405162461bcd60e51b8152602060048201526024808201527f746f74616c537570706c7928292e616464287175616e7469747929203c3d20336044820152630353030360e41b60648201526084016107e9565b610c3e83836119cf565b50505050565b60606000806000610c5485610901565b90506000816001600160401b03811115610c7057610c706128f3565b604051908082528060200260200182016040528015610c99578160200160208202803683370190505b509050610cbf604080516060810182526000808252602082018190529181019190915290565b60005b838614610d8557600081815260076020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff16158015928201929092529250610d2857610d7d565b81516001600160a01b031615610d3d57815194505b876001600160a01b0316856001600160a01b03161415610d7d5780838780600101985081518110610d7057610d706128dd565b6020026020010181815250505b600101610cc2565b50909695505050505050565b6000828152600160205260408120610da990836119e9565b9392505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b60606006805461055490612876565b6000610df381611646565b6107fc7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6836119f5565b6060818310610e3f57604051631960ccad60e11b815260040160405180910390fd5b60035460009080841115610e51578093505b6000610e5c87610901565b905084861015610e7b5785850381811015610e75578091505b50610e7f565b5060005b6000816001600160401b03811115610e9957610e996128f3565b604051908082528060200260200182016040528015610ec2578160200160208202803683370190505b50905081610ed5579350610da992505050565b6000610ee088611113565b905060008160400151610ef1575080515b885b888114158015610f035750848714155b15610fc457600081815260076020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff16158015928201929092529350610f6757610fbc565b82516001600160a01b031615610f7c57825191505b8a6001600160a01b0316826001600160a01b03161415610fbc5780848880600101995081518110610faf57610faf6128dd565b6020026020010181815250505b600101610ef3565b505050928352509095945050505050565b6001600160a01b038216331415610fff5760405163b06307db60e01b815260040160405180910390fd5b336000818152600a602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600061138882101561107f57506001919050565b61271082101561109157506002919050565b613a988210156110a357506003919050565b6161a88210156110b557506004919050565b6188b88210156110c757506005919050565b506000919050565b6110da84848461145c565b6001600160a01b0383163b15610c3e576110f6848484846119ff565b610c3e576040516368d2bf6b60e11b815260040160405180910390fd5b60408051606080820183526000808352602080840182905283850182905284519283018552818352820181905292810183905290915060035483106111585792915050565b50600082815260076020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff1615801592820192909252906111b85792915050565b610da983611857565b60606111cc82611430565b6111e957604051630a14c4b560e41b815260040160405180910390fd5b60006111f3611af7565b90508051600014156112145760405180602001604052806000815250610da9565b8061121e84611b06565b60405160200161122f9291906125ea565b6040516020818303038152906040529392505050565b600081815260016020526040812061053f90611bd5565b60008281526020819052604090206001015461127781611646565b6106f98383611672565b6002546001600160a01b031633146112db5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107e9565b6001600160a01b0381166113405760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107e9565b61082681611971565b6113538282610db0565b6107fc576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556113893390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610da9836001600160a01b038416611bdf565b60006301ffc9a760e01b6001600160e01b03198316148061141357506380ac58cd60e01b6001600160e01b03198316145b8061053f5750506001600160e01b031916635b5e139f60e01b1490565b60006003548210801561053f575050600090815260076020526040902054600160e01b900460ff161590565b600061146782611857565b9050836001600160a01b031681600001516001600160a01b03161461149e5760405162a1148160e81b815260040160405180910390fd5b6000336001600160a01b03861614806114bc57506114bc85336104f3565b806114d75750336114cc846105d7565b6001600160a01b0316145b9050806114f757604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b03841661151e57604051633a954ecd60e21b815260040160405180910390fd5b600083815260096020908152604080832080546001600160a01b03191690556001600160a01b03888116845260088352818420805467ffffffffffffffff198082166001600160401b0392831660001901831617909255898316808752848720805493841693831660019081018416949094179055898752600790955283862080546001600160e01b031916909517600160a01b429092169190910217845587018085529190932080549293919290911661160d57600354821461160d57805460208601516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038a16171781555b50505082846001600160a01b0316866001600160a01b031660008051602061292083398151915260405160405180910390a45050505050565b6108268133611c2e565b61165a8282611349565b60008281526001602052604090206106f990826113cd565b61167c8282611c92565b60008281526001602052604090206106f99082611cf7565b600061169f83611857565b80519091508215611705576000336001600160a01b03831614806116c857506116c882336104f3565b806116e35750336116d8866105d7565b6001600160a01b0316145b90508061170357604051632ce44b5f60e11b815260040160405180910390fd5b505b600084815260096020908152604080832080546001600160a01b03191690556001600160a01b03848116808552600884528285208054600160801b6000196001600160401b0380841691909101811667ffffffffffffffff198416811783900482166001908101831690930277ffffffffffffffff0000000000000000ffffffffffffffff19909416179290921783558b88526007909652848720805460ff60e01b1942909316600160a01b026001600160e01b03199091169094179390931716600160e01b17825593890180865292909420805493949390911661181e57600354821461181e57805460208701516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038716171781555b5050604051869250600091506001600160a01b03841690600080516020612920833981519152908390a450506004805460010190555050565b60408051606081018252600080825260208201819052918101919091528160035481101561195857600081815260076020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161515918101829052906119565780516001600160a01b0316156118ed579392505050565b5060001901600081815260076020908152604091829020825160608101845290546001600160a01b038116808352600160a01b82046001600160401b031693830193909352600160e01b900460ff1615159281019290925215611951579392505050565b6118ed565b505b604051636f96cda160e11b815260040160405180910390fd5b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610da982846127e5565b6107fc828260405180602001604052806000815250611d0c565b6000610da98383611eab565b6107fc8282611650565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611a3490339089908890889060040161268e565b602060405180830381600087803b158015611a4e57600080fd5b505af1925050508015611a7e575060408051601f3d908101601f19168201909252611a7b91810190612534565b60015b611ad9573d808015611aac576040519150601f19603f3d011682016040523d82523d6000602084013e611ab1565b606091505b508051611ad1576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6060600b805461055490612876565b606081611b2a5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611b4257600101600a82049150611b2e565b6000816001600160401b03811115611b5c57611b5c6128f3565b6040519080825280601f01601f191660200182016040528015611b86576020820181803683370190505b5090505b8415611aef5760001990910190600a850660300160f81b818381518110611bb357611bb36128dd565b60200101906001600160f81b031916908160001a905350600a85049450611b8a565b600061053f825490565b6000818152600183016020526040812054611c265750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561053f565b50600061053f565b611c388282610db0565b6107fc57611c50816001600160a01b03166014611ed5565b611c5b836020611ed5565b604051602001611c6c929190612619565b60408051601f198184030181529082905262461bcd60e51b82526107e99160040161276d565b611c9c8282610db0565b156107fc576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610da9836001600160a01b038416612070565b6003546001600160a01b038416611d3557604051622e076360e81b815260040160405180910390fd5b82611d535760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038416600081815260086020908152604080832080546fffffffffffffffffffffffffffffffff1981166001600160401b038083168b0181169182176801000000000000000067ffffffffffffffff1990941690921783900481168b01811690920217909155858452600790925290912080546001600160e01b0319168317600160a01b42909316929092029190911790558190818501903b15611e69575b60405182906001600160a01b03881690600090600080516020612920833981519152908290a4611e3260008784806001019550876119ff565b611e4f576040516368d2bf6b60e11b815260040160405180910390fd5b808210611df9578260035414611e6457600080fd5b611e9c565b5b6040516001830192906001600160a01b03881690600090600080516020612920833981519152908290a4808210611e6a575b50600355610c3e600085838684565b6000826000018281548110611ec257611ec26128dd565b9060005260206000200154905092915050565b60606000611ee48360026127fd565b611eef9060026127e5565b6001600160401b03811115611f0657611f066128f3565b6040519080825280601f01601f191660200182016040528015611f30576020820181803683370190505b509050600360fc1b81600081518110611f4b57611f4b6128dd565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611f7a57611f7a6128dd565b60200101906001600160f81b031916908160001a9053506000611f9e8460026127fd565b611fa99060016127e5565b90505b6001811115612021576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110611fdd57611fdd6128dd565b1a60f81b828281518110611ff357611ff36128dd565b60200101906001600160f81b031916908160001a90535060049490941c9361201a8161285f565b9050611fac565b508315610da95760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016107e9565b6000818152600183016020526040812054801561215957600061209460018361281c565b85549091506000906120a89060019061281c565b905081811461210d5760008660000182815481106120c8576120c86128dd565b90600052602060002001549050808760000184815481106120eb576120eb6128dd565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061211e5761211e6128c7565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061053f565b600091505061053f565b82805461216f90612876565b90600052602060002090601f01602090048101928261219157600085556121d7565b82601f106121aa57805160ff19168380011785556121d7565b828001600101855582156121d7579182015b828111156121d75782518255916020019190600101906121bc565b506121e39291506121e7565b5090565b5b808211156121e357600081556001016121e8565b60006001600160401b03831115612215576122156128f3565b612228601f8401601f19166020016127b5565b905082815283838301111561223c57600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b038116811461226a57600080fd5b919050565b60006020828403121561228157600080fd5b610da982612253565b6000806040838503121561229d57600080fd5b6122a683612253565b91506122b460208401612253565b90509250929050565b6000806000606084860312156122d257600080fd5b6122db84612253565b92506122e960208501612253565b9150604084013590509250925092565b6000806000806080858703121561230f57600080fd5b61231885612253565b935061232660208601612253565b92506040850135915060608501356001600160401b0381111561234857600080fd5b8501601f8101871361235957600080fd5b612368878235602084016121fc565b91505092959194509250565b6000806040838503121561238757600080fd5b61239083612253565b9150602083013580151581146123a557600080fd5b809150509250929050565b600080604083850312156123c357600080fd5b6123cc83612253565b946020939093013593505050565b6000806000606084860312156123ef57600080fd5b6123f884612253565b95602085013595506040909401359392505050565b6000602080838503121561242057600080fd5b82356001600160401b038082111561243757600080fd5b818501915085601f83011261244b57600080fd5b81358181111561245d5761245d6128f3565b8060051b915061246e8483016127b5565b8181528481019084860184860187018a101561248957600080fd5b600095505b838610156124ac57803583526001959095019491860191860161248e565b5098975050505050505050565b6000602082840312156124cb57600080fd5b5035919050565b600080604083850312156124e557600080fd5b823591506122b460208401612253565b6000806040838503121561250857600080fd5b50508035926020909101359150565b60006020828403121561252957600080fd5b8135610da981612909565b60006020828403121561254657600080fd5b8151610da981612909565b60006020828403121561256357600080fd5b81356001600160401b0381111561257957600080fd5b8201601f8101841361258a57600080fd5b611aef848235602084016121fc565b6000806000606084860312156125ae57600080fd5b833592506122e960208501612253565b600081518084526125d6816020860160208601612833565b601f01601f19169290920160200192915050565b600083516125fc818460208801612833565b835190830190612610818360208801612833565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612651816017850160208801612833565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612682816028840160208801612833565b01602801949350505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906126c1908301846125be565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015610d855761272283855180516001600160a01b031682526020808201516001600160401b0316908301526040908101511515910152565b92840192606092909201916001016126e7565b6020808252825182820181905260009190848201906040850190845b81811015610d8557835183529284019291840191600101612751565b602081526000610da960208301846125be565b81516001600160a01b031681526020808301516001600160401b0316908201526040808301511515908201526060810161053f565b604051601f8201601f191681016001600160401b03811182821017156127dd576127dd6128f3565b604052919050565b600082198211156127f8576127f86128b1565b500190565b6000816000190483118215151615612817576128176128b1565b500290565b60008282101561282e5761282e6128b1565b500390565b60005b8381101561284e578181015183820152602001612836565b83811115610c3e5750506000910152565b60008161286e5761286e6128b1565b506000190190565b600181811c9082168061288a57607f821691505b602082108114156128ab57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b03198116811461082657600080fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212205459dc71e59dca223b53188e174168f5e4a8070a51d37feb096b55145ebd280964736f6c63430008070033

Deployed Bytecode Sourcemap

248:2511:15:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2519:237;;;;;;:::i;:::-;;:::i;:::-;;;10174:14:18;;10167:22;10149:41;;10137:2;10122:18;2519:237:15;;;;;;;;6281:98:4;;;:::i;:::-;;;;;;;:::i;7796:200::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;8106:32:18;;;8088:51;;8076:2;8061:18;7796:200:4;7942:203:18;7314:421:4;;;;;;:::i;:::-;;:::i;:::-;;2205:306;2464:12;;2448:13;;:28;2205:306;;;10347:25:18;;;10335:2;10320:18;2205:306:4;10201:177:18;8656:164:4;;;;;;:::i;:::-;;:::i;4356:129:0:-;;;;;;:::i;:::-;4430:7;4456:12;;;;;;;;;;:22;;;;4356:129;4735:145;;;;;;:::i;:::-;;:::i;2241:156:15:-;;;;;;:::i;:::-;;:::i;5752:214:0:-;;;;;;:::i;:::-;;:::i;8886:179:4:-;;;;;;:::i;:::-;;:::i;512:92:5:-;;;;;;:::i;:::-;;:::i;1499:459:6:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;6096:123:4:-;;;;;;:::i;:::-;;:::i;3610:203::-;;;;;;:::i;:::-;;:::i;1661:101:14:-;;;:::i;1041:1061:15:-;;;;;;:::i;:::-;;:::i;5219:870:6:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1029:85:14:-;1101:6;;-1:-1:-1;;;;;1101:6:14;1029:85;;1416:151:1;;;;;;:::i;:::-;;:::i;2860:145:0:-;;;;;;:::i;:::-;;:::i;6443:102:4:-;;;:::i;2110:123:15:-;;;;;;:::i;:::-;;:::i;2334:2448:6:-;;;;;;:::i;:::-;;:::i;1992:49:0:-;;2037:4;1992:49;;8063:303:4;;;;;;:::i;:::-;;:::i;654:379:15:-;;;;;;:::i;:::-;;:::i;9131:364:4:-;;;;;;:::i;:::-;;:::i;938:408:6:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;6611:313:4:-;;;;;;:::i;:::-;;:::i;1735:140:1:-;;;;;;:::i;:::-;;:::i;461:62:15:-;;499:24;461:62;;5114:147:0;;;;;;:::i;:::-;;:::i;8432:162:4:-;;;;;;:::i;:::-;-1:-1:-1;;;;;8552:25:4;;;8529:4;8552:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;8432:162;1911:198:14;;;;;;:::i;:::-;;:::i;2519:237:15:-;2683:4;2712:36;2736:11;2712:23;:36::i;:::-;2705:43;2519:237;-1:-1:-1;;2519:237:15:o;6281:98:4:-;6335:13;6367:5;6360:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6281:98;:::o;7796:200::-;7864:7;7888:16;7896:7;7888;:16::i;:::-;7883:64;;7913:34;;-1:-1:-1;;;7913:34:4;;;;;;;;;;;7883:64;-1:-1:-1;7965:24:4;;;;:15;:24;;;;;;-1:-1:-1;;;;;7965:24:4;;7796:200::o;7314:421::-;7386:13;7402:24;7418:7;7402:15;:24::i;:::-;7386:40;;7446:5;-1:-1:-1;;;;;7440:11:4;:2;-1:-1:-1;;;;;7440:11:4;;7436:48;;;7460:24;;-1:-1:-1;;;7460:24:4;;;;;;;;;;;7436:48;21666:10;-1:-1:-1;;;;;7499:28:4;;;7495:151;;7533:44;7550:5;21666:10;8432:162;:::i;7533:44::-;7529:117;;7600:35;;-1:-1:-1;;;7600:35:4;;;;;;;;;;;7529:117;7656:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;7656:29:4;-1:-1:-1;;;;;7656:29:4;;;;;;;;;7700:28;;7656:24;;7700:28;;;;;;;7376:359;7314:421;;:::o;8656:164::-;8785:28;8795:4;8801:2;8805:7;8785:9;:28::i;:::-;8656:164;;;:::o;4735:145:0:-;4430:7;4456:12;;;;;;;;;;:22;;;2470:16;2481:4;2470:10;:16::i;:::-;4848:25:::1;4859:4;4865:7;4848:10;:25::i;2241:156:15:-:0;2037:4:0;2470:16;2037:4;2470:10;:16::i;:::-;2334:19:15;;::::1;::::0;:13:::1;::::0;:19:::1;::::0;::::1;::::0;::::1;:::i;:::-;;2369:20;2385:3;2369:20;;;;;;:::i;:::-;;;;;;;;2241:156:::0;;:::o;5752:214:0:-;-1:-1:-1;;;;;5847:23:0;;21666:10:4;5847:23:0;5839:83;;;;-1:-1:-1;;;5839:83:0;;13962:2:18;5839:83:0;;;13944:21:18;14001:2;13981:18;;;13974:30;14040:34;14020:18;;;14013:62;-1:-1:-1;;;14091:18:18;;;14084:45;14146:19;;5839:83:0;;;;;;;;;5933:26;5945:4;5951:7;5933:11;:26::i;:::-;5752:214;;:::o;8886:179:4:-;9019:39;9036:4;9042:2;9046:7;9019:39;;;;;;;;;;;;:16;:39::i;512:92:5:-;577:20;583:7;592:4;577:5;:20::i;:::-;512:92;:::o;1499:459:6:-;1672:15;;1588:23;;1647:22;1672:15;-1:-1:-1;;;;;1738:36:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;1738:36:6;;-1:-1:-1;;1738:36:6;;;;;;;;;;;;1701:73;;1793:9;1788:123;1809:14;1804:1;:19;1788:123;;1864:32;1884:8;1893:1;1884:11;;;;;;;;:::i;:::-;;;;;;;1864:19;:32::i;:::-;1848:10;1859:1;1848:13;;;;;;;;:::i;:::-;;;;;;;;;;:48;1825:3;;1788:123;;;-1:-1:-1;1931:10:6;1499:459;-1:-1:-1;;;1499:459:6:o;6096:123:4:-;6160:7;6186:21;6199:7;6186:12;:21::i;:::-;:26;;6096:123;-1:-1:-1;;6096:123:4:o;3610:203::-;3674:7;-1:-1:-1;;;;;3697:19:4;;3693:60;;3725:28;;-1:-1:-1;;;3725:28:4;;;;;;;;;;;3693:60;-1:-1:-1;;;;;;3778:19:4;;;;;:12;:19;;;;;:27;-1:-1:-1;;;;;3778:27:4;;3610:203::o;1661:101:14:-;1101:6;;-1:-1:-1;;;;;1101:6:14;21666:10:4;1241:23:14;1233:68;;;;-1:-1:-1;;;1233:68:14;;12387:2:18;1233:68:14;;;12369:21:18;;;12406:18;;;12399:30;12465:34;12445:18;;;12438:62;12517:18;;1233:68:14;12185:356:18;1233:68:14;1725:30:::1;1752:1;1725:18;:30::i;:::-;1661:101::o:0;1041:1061:15:-;499:24;2470:16:0;2481:4;2470:10;:16::i;:::-;1148:7:15::1;1159:1;1148:12;1144:837;;;1252:4;1221:27;1239:8;1221:13;2464:12:4::0;;2448:13;;:28;;2205:306;1221:13:15::1;:17:::0;::::1;:27::i;:::-;:35;;1212:84;;;::::0;-1:-1:-1;;;1212:84:15;;12748:2:18;1212:84:15::1;::::0;::::1;12730:21:18::0;12787:2;12767:18;;;12760:30;12826:34;12806:18;;;12799:62;-1:-1:-1;;;12877:18:18;;;12870:33;12920:19;;1212:84:15::1;12546:399:18::0;1212:84:15::1;1144:837;;;1318:7;1329:1;1318:12;1314:667;;;1421:5;1390:27;1408:8;1390:13;2464:12:4::0;;2448:13;;:28;;2205:306;1390:27:15::1;:36;;1381:86;;;::::0;-1:-1:-1;;;1381:86:15;;11577:2:18;1381:86:15::1;::::0;::::1;11559:21:18::0;11616:2;11596:18;;;11589:30;11655:34;11635:18;;;11628:62;-1:-1:-1;;;11706:18:18;;;11699:34;11750:19;;1381:86:15::1;11375:400:18::0;1314:667:15::1;1489:7;1500:1;1489:12;1485:496;;;1587:5;1556:27;1574:8;1556:13;2464:12:4::0;;2448:13;;:28;;2205:306;1556:27:15::1;:36;;1547:86;;;::::0;-1:-1:-1;;;1547:86:15;;13557:2:18;1547:86:15::1;::::0;::::1;13539:21:18::0;13596:2;13576:18;;;13569:30;13635:34;13615:18;;;13608:62;-1:-1:-1;;;13686:18:18;;;13679:34;13730:19;;1547:86:15::1;13355:400:18::0;1485:496:15::1;1655:7;1666:1;1655:12;1651:330;;;1765:5;1734:27;1752:8;1734:13;2464:12:4::0;;2448:13;;:28;;2205:306;1734:27:15::1;:36;;1725:86;;;::::0;-1:-1:-1;;;1725:86:15;;13152:2:18;1725:86:15::1;::::0;::::1;13134:21:18::0;13191:2;13171:18;;;13164:30;13230:34;13210:18;;;13203:62;-1:-1:-1;;;13281:18:18;;;13274:34;13325:19;;1725:86:15::1;12950:400:18::0;1651:330:15::1;1923:5;1892:27;1910:8;1892:13;2464:12:4::0;;2448:13;;:28;;2205:306;1892:27:15::1;:36;;1883:86;;;::::0;-1:-1:-1;;;1883:86:15;;11982:2:18;1883:86:15::1;::::0;::::1;11964:21:18::0;12021:2;12001:18;;;11994:30;12060:34;12040:18;;;12033:62;-1:-1:-1;;;12111:18:18;;;12104:34;12155:19;;1883:86:15::1;11780:400:18::0;1883:86:15::1;2071:23;2081:2;2085:8;2071:9;:23::i;:::-;1041:1061:::0;;;;:::o;5219:870:6:-;5289:16;5341:19;5374:25;5413:22;5438:16;5448:5;5438:9;:16::i;:::-;5413:41;;5468:25;5510:14;-1:-1:-1;;;;;5496:29:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5496:29:6;;5468:57;;5539:31;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;5539:31:6;5589:9;5584:460;5633:14;5618:11;:29;5584:460;;5684:14;;;;:11;:14;;;;;;;;;5672:26;;;;;;;;;-1:-1:-1;;;;;5672:26:6;;;;-1:-1:-1;;;5672:26:6;;-1:-1:-1;;;;;5672:26:6;;;;;;;;-1:-1:-1;;;5672:26:6;;;;;;;;;;;;;;;;-1:-1:-1;5716:71:6;;5760:8;;5716:71;5808:14;;-1:-1:-1;;;;;5808:28:6;;5804:109;;5880:14;;;-1:-1:-1;5804:109:6;5955:5;-1:-1:-1;;;;;5934:26:6;:17;-1:-1:-1;;;;;5934:26:6;;5930:100;;;6010:1;5984:8;5993:13;;;;;;5984:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;5930:100;5649:3;;5584:460;;;-1:-1:-1;6064:8:6;;5219:870;-1:-1:-1;;;;;;5219:870:6:o;1416:151:1:-;1506:7;1532:18;;;:12;:18;;;;;:28;;1554:5;1532:21;:28::i;:::-;1525:35;1416:151;-1:-1:-1;;;1416:151:1:o;2860:145:0:-;2946:4;2969:12;;;;;;;;;;;-1:-1:-1;;;;;2969:29:0;;;;;;;;;;;;;;;2860:145::o;6443:102:4:-;6499:13;6531:7;6524:14;;;;;:::i;2110:123:15:-;2037:4:0;2470:16;2037:4;2470:10;:16::i;:::-;2194:31:15::1;499:24;2218:6;2194:10;:31::i;2334:2448:6:-:0;2465:16;2530:4;2521:5;:13;2517:45;;2543:19;;-1:-1:-1;;;2543:19:6;;;;;;;;;;;2517:45;2629:13;;2576:19;;2877:9;2870:4;:16;2866:71;;;2913:9;2906:16;;2866:71;2950:25;2978:16;2988:5;2978:9;:16::i;:::-;2950:44;;3169:4;3161:5;:12;3157:271;;;3215:12;;;3249:31;;;3245:109;;;3324:11;3304:31;;3245:109;3175:193;3157:271;;;-1:-1:-1;3412:1:6;3157:271;3441:25;3483:17;-1:-1:-1;;;;;3469:32:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3469:32:6;-1:-1:-1;3441:60:6;-1:-1:-1;3519:22:6;3515:76;;3568:8;-1:-1:-1;3561:15:6;;-1:-1:-1;;;3561:15:6;3515:76;3732:31;3766:26;3786:5;3766:19;:26::i;:::-;3732:60;;3806:25;4048:9;:16;;;4043:90;;-1:-1:-1;4104:14:6;;4043:90;4163:5;4146:466;4175:4;4170:1;:9;;:45;;;;;4198:17;4183:11;:32;;4170:45;4146:466;;;4252:14;;;;:11;:14;;;;;;;;;4240:26;;;;;;;;;-1:-1:-1;;;;;4240:26:6;;;;-1:-1:-1;;;4240:26:6;;-1:-1:-1;;;;;4240:26:6;;;;;;;;-1:-1:-1;;;4240:26:6;;;;;;;;;;;;;;;;-1:-1:-1;4284:71:6;;4328:8;;4284:71;4376:14;;-1:-1:-1;;;;;4376:28:6;;4372:109;;4448:14;;;-1:-1:-1;4372:109:6;4523:5;-1:-1:-1;;;;;4502:26:6;:17;-1:-1:-1;;;;;4502:26:6;;4498:100;;;4578:1;4552:8;4561:13;;;;;;4552:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;4498:100;4217:3;;4146:466;;;-1:-1:-1;;;4694:29:6;;;-1:-1:-1;4694:29:6;;2334:2448;-1:-1:-1;;;;;2334:2448:6:o;8063:303:4:-;-1:-1:-1;;;;;8161:31:4;;21666:10;8161:31;8157:61;;;8201:17;;-1:-1:-1;;;8201:17:4;;;;;;;;;;;8157:61;21666:10;8229:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;8229:49:4;;;;;;;;;;;;:60;;-1:-1:-1;;8229:60:4;;;;;;;;;;8304:55;;10149:41:18;;;8229:49:4;;21666:10;8304:55;;10122:18:18;8304:55:4;;;;;;;8063:303;;:::o;654:379:15:-;709:7;738:4;733:2;:9;729:278;;;-1:-1:-1;766:1:15;;654:379;-1:-1:-1;654:379:15:o;729:278::-;794:5;789:2;:10;785:222;;;-1:-1:-1;823:1:15;;654:379;-1:-1:-1;654:379:15:o;785:222::-;851:5;846:2;:10;842:165;;;-1:-1:-1;880:1:15;;654:379;-1:-1:-1;654:379:15:o;842:165::-;908:5;903:2;:10;899:108;;;-1:-1:-1;937:1:15;;654:379;-1:-1:-1;654:379:15:o;899:108::-;965:5;960:2;:10;956:51;;;-1:-1:-1;994:1:15;;654:379;-1:-1:-1;654:379:15:o;956:51::-;-1:-1:-1;1024:1:15;;654:379;-1:-1:-1;654:379:15:o;9131:364:4:-;9292:28;9302:4;9308:2;9312:7;9292:9;:28::i;:::-;-1:-1:-1;;;;;9334:14:4;;;:19;9330:159;;9359:56;9390:4;9396:2;9400:7;9409:5;9359:30;:56::i;:::-;9355:134;;9438:40;;-1:-1:-1;;;9438:40:4;;;;;;;;;;;938:408:6;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1092:53:6;1132:13;;1121:7;:24;1088:100;;1168:9;938:408;-1:-1:-1;;938:408:6:o;1088:100::-;-1:-1:-1;1209:20:6;;;;:11;:20;;;;;;;;;1197:32;;;;;;;;;-1:-1:-1;;;;;1197:32:6;;;;-1:-1:-1;;;1197:32:6;;-1:-1:-1;;;;;1197:32:6;;;;;;;;-1:-1:-1;;;1197:32:6;;;;;;;;;;;;;;;;1239:63;;1282:9;938:408;-1:-1:-1;;938:408:6:o;1239:63::-;1318:21;1331:7;1318:12;:21::i;6611:313:4:-;6684:13;6714:16;6722:7;6714;:16::i;:::-;6709:59;;6739:29;;-1:-1:-1;;;6739:29:4;;;;;;;;;;;6709:59;6779:21;6803:10;:8;:10::i;:::-;6779:34;;6836:7;6830:21;6855:1;6830:26;;:87;;;;;;;;;;;;;;;;;6883:7;6892:18;6902:7;6892:9;:18::i;:::-;6866:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;6823:94;6611:313;-1:-1:-1;;;6611:313:4:o;1735:140:1:-;1815:7;1841:18;;;:12;:18;;;;;:27;;:25;:27::i;5114:147:0:-;4430:7;4456:12;;;;;;;;;;:22;;;2470:16;2481:4;2470:10;:16::i;:::-;5228:26:::1;5240:4;5246:7;5228:11;:26::i;1911:198:14:-:0;1101:6;;-1:-1:-1;;;;;1101:6:14;21666:10:4;1241:23:14;1233:68;;;;-1:-1:-1;;;1233:68:14;;12387:2:18;1233:68:14;;;12369:21:18;;;12406:18;;;12399:30;12465:34;12445:18;;;12438:62;12517:18;;1233:68:14;12185:356:18;1233:68:14;-1:-1:-1;;;;;1999:22:14;::::1;1991:73;;;::::0;-1:-1:-1;;;1991:73:14;;11170:2:18;1991:73:14::1;::::0;::::1;11152:21:18::0;11209:2;11189:18;;;11182:30;11248:34;11228:18;;;11221:62;-1:-1:-1;;;11299:18:18;;;11292:36;11345:19;;1991:73:14::1;10968:402:18::0;1991:73:14::1;2074:28;2093:8;2074:18;:28::i;7209:233:0:-:0;7292:22;7300:4;7306:7;7292;:22::i;:::-;7287:149;;7330:6;:12;;;;;;;;;;;-1:-1:-1;;;;;7330:29:0;;;;;;;;;:36;;-1:-1:-1;;7330:36:0;7362:4;7330:36;;;7412:12;21666:10:4;;21580:103;7412:12:0;-1:-1:-1;;;;;7385:40:0;7403:7;-1:-1:-1;;;;;7385:40:0;7397:4;7385:40;;;;;;;;;;7209:233;;:::o;7627:150:7:-;7697:4;7720:50;7725:3;-1:-1:-1;;;;;7745:23:7;;7720:4;:50::i;2943:608:4:-;3028:4;-1:-1:-1;;;;;;;;;3324:25:4;;;;:101;;-1:-1:-1;;;;;;;;;;3400:25:4;;;3324:101;:177;;;-1:-1:-1;;;;;;;;3476:25:4;-1:-1:-1;;;3476:25:4;;2943:608::o;9741:172::-;9798:4;9861:13;;9851:7;:23;9821:85;;;;-1:-1:-1;;9879:20:4;;;;:11;:20;;;;;:27;-1:-1:-1;;;9879:27:4;;;;9878:28;;9741:172::o;13801:2100::-;13911:35;13949:21;13962:7;13949:12;:21::i;:::-;13911:59;;14007:4;-1:-1:-1;;;;;13985:26:4;:13;:18;;;-1:-1:-1;;;;;13985:26:4;;13981:67;;14020:28;;-1:-1:-1;;;14020:28:4;;;;;;;;;;;13981:67;14059:22;21666:10;-1:-1:-1;;;;;14085:27:4;;;;:86;;-1:-1:-1;14128:43:4;14145:4;21666:10;8432:162;:::i;14128:43::-;14085:145;;;-1:-1:-1;21666:10:4;14187:20;14199:7;14187:11;:20::i;:::-;-1:-1:-1;;;;;14187:43:4;;14085:145;14059:172;;14247:17;14242:66;;14273:35;;-1:-1:-1;;;14273:35:4;;;;;;;;;;;14242:66;-1:-1:-1;;;;;14322:16:4;;14318:52;;14347:23;;-1:-1:-1;;;14347:23:4;;;;;;;;;;;14318:52;14494:24;;;;:15;:24;;;;;;;;14487:31;;-1:-1:-1;;;;;;14487:31:4;;;-1:-1:-1;;;;;14808:18:4;;;;;:12;:18;;;;;:31;;-1:-1:-1;;14808:31:4;;;-1:-1:-1;;;;;14808:31:4;;;-1:-1:-1;;14808:31:4;;;;;;;14853:16;;;;;;;;;:29;;;;;;;;-1:-1:-1;14853:29:4;;;;;;;;;;;14931:20;;;:11;:20;;;;;;14965:18;;-1:-1:-1;;;;;;14997:49:4;;;;-1:-1:-1;;;15030:15:4;14997:49;;;;;;;;;;15316:11;;15375:24;;;;;;;15417:13;;14931:20;;15316:11;;15375:24;;15417:13;15413:377;;15624:13;;15609:11;:28;15605:171;;15661:20;;15729:28;;;;-1:-1:-1;;;;;15703:54:4;-1:-1:-1;;;15703:54:4;-1:-1:-1;;;;;;15703:54:4;;;-1:-1:-1;;;;;15661:20:4;;15703:54;;;;15605:171;14784:1016;;;15834:7;15830:2;-1:-1:-1;;;;;15815:27:4;15824:4;-1:-1:-1;;;;;15815:27:4;-1:-1:-1;;;;;;;;;;;15815:27:4;;;;;;;;;13901:2000;;13801:2100;;;:::o;3299:103:0:-;3365:30;3376:4;21666:10:4;3365::0;:30::i;1963:166:1:-;2050:31;2067:4;2073:7;2050:16;:31::i;:::-;2091:18;;;;:12;:18;;;;;:31;;2114:7;2091:22;:31::i;2218:171::-;2306:32;2324:4;2330:7;2306:17;:32::i;:::-;2348:18;;;;:12;:18;;;;;:34;;2374:7;2348:25;:34::i;16278:2373:4:-;16357:35;16395:21;16408:7;16395:12;:21::i;:::-;16442:18;;16357:59;;-1:-1:-1;16471:305:4;;;;16504:22;21666:10;-1:-1:-1;;;;;16530:27:4;;;;:90;;-1:-1:-1;16577:43:4;16594:4;21666:10;8432:162;:::i;16577:43::-;16530:153;;;-1:-1:-1;21666:10:4;16640:20;16652:7;16640:11;:20::i;:::-;-1:-1:-1;;;;;16640:43:4;;16530:153;16504:180;;16704:17;16699:66;;16730:35;;-1:-1:-1;;;16730:35:4;;;;;;;;;;;16699:66;16490:286;16471:305;16907:24;;;;:15;:24;;;;;;;;16900:31;;-1:-1:-1;;;;;;16900:31:4;;;-1:-1:-1;;;;;17255:18:4;;;;;;:12;:18;;;;;17287:24;;-1:-1:-1;;;;;;;;;;17287:24:4;;;;;;;;;-1:-1:-1;;17287:24:4;;;;17325:29;;;;;16900:31;17325:29;;;;;;;;-1:-1:-1;;17325:29:4;;;;;;;;;;17484:20;;;:11;:20;;;;;;17518;;-1:-1:-1;;;;17585:15:4;17552:49;;;-1:-1:-1;;;17552:49:4;-1:-1:-1;;;;;;17552:49:4;;;;;;;;;;17615:22;-1:-1:-1;;;17615:22:4;;;17903:11;;;17962:24;;;;;;;18004:13;;17255:18;;17484:20;17962:24;;18004:13;18000:377;;18211:13;;18196:11;:28;18192:171;;18248:20;;18316:28;;;;-1:-1:-1;;;;;18290:54:4;-1:-1:-1;;;18290:54:4;-1:-1:-1;;;;;;18290:54:4;;;-1:-1:-1;;;;;18248:20:4;;18290:54;;;;18192:171;-1:-1:-1;;18402:35:4;;18429:7;;-1:-1:-1;18425:1:4;;-1:-1:-1;;;;;;18402:35:4;;;-1:-1:-1;;;;;;;;;;;18402:35:4;18425:1;;18402:35;-1:-1:-1;;18620:12:4;:14;;;;;;-1:-1:-1;;16278:2373:4:o;4953:1086::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;5063:7:4;5145:13;;5138:4;:20;5134:841;;;5178:31;5212:17;;;:11;:17;;;;;;;;;5178:51;;;;;;;;;-1:-1:-1;;;;;5178:51:4;;;;-1:-1:-1;;;5178:51:4;;-1:-1:-1;;;;;5178:51:4;;;;;;;;-1:-1:-1;;;5178:51:4;;;;;;;;;;;;;;5247:714;;5296:14;;-1:-1:-1;;;;;5296:28:4;;5292:99;;5359:9;4953:1086;-1:-1:-1;;;4953:1086:4:o;5292:99::-;-1:-1:-1;;;5727:6:4;5771:17;;;;:11;:17;;;;;;;;;5759:29;;;;;;;;;-1:-1:-1;;;;;5759:29:4;;;;;-1:-1:-1;;;5759:29:4;;-1:-1:-1;;;;;5759:29:4;;;;;;;;-1:-1:-1;;;5759:29:4;;;;;;;;;;;;;5818:28;5814:107;;5885:9;4953:1086;-1:-1:-1;;;4953:1086:4:o;5814:107::-;5688:255;;;5160:815;5134:841;6001:31;;-1:-1:-1;;;6001:31:4;;;;;;;;;;;2263:187:14;2355:6;;;-1:-1:-1;;;;;2371:17:14;;;-1:-1:-1;;;;;;2371:17:14;;;;;;;2403:40;;2355:6;;;2371:17;2355:6;;2403:40;;2336:16;;2403:40;2326:124;2263:187;:::o;2755:96:16:-;2813:7;2839:5;2843:1;2839;:5;:::i;9992:102:4:-;10060:27;10070:2;10074:8;10060:27;;;;;;;;;;;;:9;:27::i;8885:156:7:-;8959:7;9009:22;9013:3;9025:5;9009:3;:22::i;6605:110:0:-;6683:25;6694:4;6700:7;6683:10;:25::i;19132:684:4:-;19310:88;;-1:-1:-1;;;19310:88:4;;19290:4;;-1:-1:-1;;;;;19310:45:4;;;;;:88;;21666:10;;19377:4;;19383:7;;19392:5;;19310:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19310:88:4;;;;;;;;-1:-1:-1;;19310:88:4;;;;;;;;;;;;:::i;:::-;;;19306:504;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19575:13:4;;19571:229;;19620:40;;-1:-1:-1;;;19620:40:4;;;;;;;;;;;19571:229;19760:6;19754:13;19745:6;19741:2;19737:15;19730:38;19306:504;-1:-1:-1;;;;;;19453:64:4;-1:-1:-1;;;19453:64:4;;-1:-1:-1;19306:504:4;19132:684;;;;;;:::o;2405:106:15:-;2457:13;2490;2483:20;;;;;:::i;21784:798:4:-;21841:13;22081:10;22077:59;;-1:-1:-1;;22111:10:4;;;;;;;;;;;;-1:-1:-1;;;22111:10:4;;;;;21784:798::o;22077:59::-;22164:5;22149:12;22211:87;22218:9;;22211:87;;22247:8;;22281:2;22273:10;;;;22211:87;;;22311:19;22343:6;-1:-1:-1;;;;;22333:17:4;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22333:17:4;;22311:39;;22364:163;22371:10;;22364:163;;-1:-1:-1;;22401:8:4;;;;22478:2;22470:5;:10;22457:2;:24;22444:39;;22427:6;22434;22427:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;22427:56:4;;;;;;;;-1:-1:-1;22510:2:4;22501:11;;;;22364:163;;8428:115:7;8491:7;8517:19;8525:3;4043:18;;3961:107;1712:404;1775:4;3849:19;;;:12;;;:19;;;;;;1791:319;;-1:-1:-1;1833:23:7;;;;;;;;:11;:23;;;;;;;;;;;;;2013:18;;1991:19;;;:12;;;:19;;;;;;:40;;;;2045:11;;1791:319;-1:-1:-1;2094:5:7;2087:12;;3683:492:0;3771:22;3779:4;3785:7;3771;:22::i;:::-;3766:403;;3954:41;3982:7;-1:-1:-1;;;;;3954:41:0;3992:2;3954:19;:41::i;:::-;4066:38;4094:4;4101:2;4066:19;:38::i;:::-;3861:265;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;3861:265:0;;;;;;;;;;-1:-1:-1;;;3809:349:0;;;;;;;:::i;7567:234::-;7650:22;7658:4;7664:7;7650;:22::i;:::-;7646:149;;;7720:5;7688:12;;;;;;;;;;;-1:-1:-1;;;;;7688:29:0;;;;;;;;;;:37;;-1:-1:-1;;7688:37:0;;;7744:40;21666:10:4;;7688:12:0;;7744:40;;7720:5;7744:40;7567:234;;:::o;7945:156:7:-;8018:4;8041:53;8049:3;-1:-1:-1;;;;;8069:23:7;;8041:7;:53::i;10454:1712:4:-;10595:13;;-1:-1:-1;;;;;10622:16:4;;10618:48;;10647:19;;-1:-1:-1;;;10647:19:4;;;;;;;;;;;10618:48;10680:13;10676:44;;10702:18;;-1:-1:-1;;;10702:18:4;;;;;;;;;;;10676:44;-1:-1:-1;;;;;11063:16:4;;;;;;:12;:16;;;;;;;;:44;;-1:-1:-1;;11121:49:4;;-1:-1:-1;;;;;11063:44:4;;;;;;;11121:49;;;;-1:-1:-1;;11063:44:4;;;;;;11121:49;;;;;;;;;;;;;;;;11185:25;;;:11;:25;;;;;;:35;;-1:-1:-1;;;;;;11234:66:4;;;-1:-1:-1;;;11284:15:4;11234:66;;;;;;;;;;;;;11185:25;;11378:23;;;;11420:14;:19;11416:622;;11459:308;11489:38;;11514:12;;-1:-1:-1;;;;;11489:38:4;;;11506:1;;-1:-1:-1;;;;;;;;;;;11489:38:4;11506:1;;11489:38;11554:69;11593:1;11597:2;11601:14;;;;;;11617:5;11554:30;:69::i;:::-;11549:172;;11658:40;;-1:-1:-1;;;11658:40:4;;;;;;;;;;;11549:172;11762:3;11747:12;:18;11459:308;;11846:12;11829:13;;:29;11825:43;;11860:8;;;11825:43;11416:622;;;11907:117;11937:40;;11962:14;;;;;-1:-1:-1;;;;;11937:40:4;;;11954:1;;-1:-1:-1;;;;;;;;;;;11937:40:4;11954:1;;11937:40;12019:3;12004:12;:18;11907:117;;11416:622;-1:-1:-1;12051:13:4;:28;12099:60;12128:1;12132:2;12136:12;12150:8;12099:60;:::i;4410:118:7:-;4477:7;4503:3;:11;;4515:5;4503:18;;;;;;;;:::i;:::-;;;;;;;;;4496:25;;4410:118;;;;:::o;1637:441:17:-;1712:13;1737:19;1769:10;1773:6;1769:1;:10;:::i;:::-;:14;;1782:1;1769:14;:::i;:::-;-1:-1:-1;;;;;1759:25:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1759:25:17;;1737:47;;-1:-1:-1;;;1794:6:17;1801:1;1794:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;1794:15:17;;;;;;;;;-1:-1:-1;;;1819:6:17;1826:1;1819:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;1819:15:17;;;;;;;;-1:-1:-1;1849:9:17;1861:10;1865:6;1861:1;:10;:::i;:::-;:14;;1874:1;1861:14;:::i;:::-;1849:26;;1844:132;1881:1;1877;:5;1844:132;;;-1:-1:-1;;;1928:5:17;1936:3;1928:11;1915:25;;;;;;;:::i;:::-;;;;1903:6;1910:1;1903:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;1903:37:17;;;;;;;;-1:-1:-1;1964:1:17;1954:11;;;;;1884:3;;;:::i;:::-;;;1844:132;;;-1:-1:-1;1993:10:17;;1985:55;;;;-1:-1:-1;;;1985:55:17;;10809:2:18;1985:55:17;;;10791:21:18;;;10828:18;;;10821:30;10887:34;10867:18;;;10860:62;10939:18;;1985:55:17;10607:356:18;2284:1388:7;2350:4;2487:19;;;:12;;;:19;;;;;;2521:15;;2517:1149;;2890:21;2914:14;2927:1;2914:10;:14;:::i;:::-;2962:18;;2890:38;;-1:-1:-1;2942:17:7;;2962:22;;2983:1;;2962:22;:::i;:::-;2942:42;;3016:13;3003:9;:26;2999:398;;3049:17;3069:3;:11;;3081:9;3069:22;;;;;;;;:::i;:::-;;;;;;;;;3049:42;;3220:9;3191:3;:11;;3203:13;3191:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;3303:23;;;:12;;;:23;;;;;:36;;;2999:398;3475:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;3567:3;:12;;:19;3580:5;3567:19;;;;;;;;;;;3560:26;;;3608:4;3601:11;;;;;;;2517:1149;3650:5;3643:12;;;;;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:406:18;78:5;-1:-1:-1;;;;;104:6:18;101:30;98:56;;;134:18;;:::i;:::-;172:57;217:2;196:15;;-1:-1:-1;;192:29:18;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:18;;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;-1:-1:-1;;;;;1811:6:18;1808:30;1805:50;;;1851:1;1848;1841:12;1805:50;1874:22;;1927:4;1919:13;;1915:27;-1:-1:-1;1905:55:18;;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:18:o;2674:322::-;2751:6;2759;2767;2820:2;2808:9;2799:7;2795:23;2791:32;2788:52;;;2836:1;2833;2826:12;2788:52;2859:29;2878:9;2859:29;:::i;:::-;2849:39;2935:2;2920:18;;2907:32;;-1:-1:-1;2986:2:18;2971:18;;;2958:32;;2674:322;-1:-1:-1;;;2674:322:18:o;3001:957::-;3085:6;3116:2;3159;3147:9;3138:7;3134:23;3130:32;3127:52;;;3175:1;3172;3165:12;3127:52;3215:9;3202:23;-1:-1:-1;;;;;3285:2:18;3277:6;3274:14;3271:34;;;3301:1;3298;3291:12;3271:34;3339:6;3328:9;3324:22;3314:32;;3384:7;3377:4;3373:2;3369:13;3365:27;3355:55;;3406:1;3403;3396:12;3355:55;3442:2;3429:16;3464:2;3460;3457:10;3454:36;;;3470:18;;:::i;:::-;3516:2;3513:1;3509:10;3499:20;;3539:28;3563:2;3559;3555:11;3539:28;:::i;:::-;3601:15;;;3632:12;;;;3664:11;;;3694;;;3690:20;;3687:33;-1:-1:-1;3684:53:18;;;3733:1;3730;3723:12;3684:53;3755:1;3746:10;;3765:163;3779:2;3776:1;3773:9;3765:163;;;3836:17;;3824:30;;3797:1;3790:9;;;;;3874:12;;;;3906;;3765:163;;;-1:-1:-1;3947:5:18;3001:957;-1:-1:-1;;;;;;;;3001:957:18:o;3963:180::-;4022:6;4075:2;4063:9;4054:7;4050:23;4046:32;4043:52;;;4091:1;4088;4081:12;4043:52;-1:-1:-1;4114:23:18;;3963:180;-1:-1:-1;3963:180:18:o;4148:254::-;4216:6;4224;4277:2;4265:9;4256:7;4252:23;4248:32;4245:52;;;4293:1;4290;4283:12;4245:52;4329:9;4316:23;4306:33;;4358:38;4392:2;4381:9;4377:18;4358:38;:::i;4407:248::-;4475:6;4483;4536:2;4524:9;4515:7;4511:23;4507:32;4504:52;;;4552:1;4549;4542:12;4504:52;-1:-1:-1;;4575:23:18;;;4645:2;4630:18;;;4617:32;;-1:-1:-1;4407:248:18:o;4660:245::-;4718:6;4771:2;4759:9;4750:7;4746:23;4742:32;4739:52;;;4787:1;4784;4777:12;4739:52;4826:9;4813:23;4845:30;4869:5;4845:30;:::i;4910:249::-;4979:6;5032:2;5020:9;5011:7;5007:23;5003:32;5000:52;;;5048:1;5045;5038:12;5000:52;5080:9;5074:16;5099:30;5123:5;5099:30;:::i;5164:450::-;5233:6;5286:2;5274:9;5265:7;5261:23;5257:32;5254:52;;;5302:1;5299;5292:12;5254:52;5342:9;5329:23;-1:-1:-1;;;;;5367:6:18;5364:30;5361:50;;;5407:1;5404;5397:12;5361:50;5430:22;;5483:4;5475:13;;5471:27;-1:-1:-1;5461:55:18;;5512:1;5509;5502:12;5461:55;5535:73;5600:7;5595:2;5582:16;5577:2;5573;5569:11;5535:73;:::i;5804:322::-;5881:6;5889;5897;5950:2;5938:9;5929:7;5925:23;5921:32;5918:52;;;5966:1;5963;5956:12;5918:52;6002:9;5989:23;5979:33;;6031:38;6065:2;6054:9;6050:18;6031:38;:::i;6131:257::-;6172:3;6210:5;6204:12;6237:6;6232:3;6225:19;6253:63;6309:6;6302:4;6297:3;6293:14;6286:4;6279:5;6275:16;6253:63;:::i;:::-;6370:2;6349:15;-1:-1:-1;;6345:29:18;6336:39;;;;6377:4;6332:50;;6131:257;-1:-1:-1;;6131:257:18:o;6676:470::-;6855:3;6893:6;6887:13;6909:53;6955:6;6950:3;6943:4;6935:6;6931:17;6909:53;:::i;:::-;7025:13;;6984:16;;;;7047:57;7025:13;6984:16;7081:4;7069:17;;7047:57;:::i;:::-;7120:20;;6676:470;-1:-1:-1;;;;6676:470:18:o;7151:786::-;7562:25;7557:3;7550:38;7532:3;7617:6;7611:13;7633:62;7688:6;7683:2;7678:3;7674:12;7667:4;7659:6;7655:17;7633:62;:::i;:::-;-1:-1:-1;;;7754:2:18;7714:16;;;7746:11;;;7739:40;7804:13;;7826:63;7804:13;7875:2;7867:11;;7860:4;7848:17;;7826:63;:::i;:::-;7909:17;7928:2;7905:26;;7151:786;-1:-1:-1;;;;7151:786:18:o;8150:488::-;-1:-1:-1;;;;;8419:15:18;;;8401:34;;8471:15;;8466:2;8451:18;;8444:43;8518:2;8503:18;;8496:34;;;8566:3;8561:2;8546:18;;8539:31;;;8344:4;;8587:45;;8612:19;;8604:6;8587:45;:::i;:::-;8579:53;8150:488;-1:-1:-1;;;;;;8150:488:18:o;8643:724::-;8878:2;8930:21;;;9000:13;;8903:18;;;9022:22;;;8849:4;;8878:2;9101:15;;;;9075:2;9060:18;;;8849:4;9144:197;9158:6;9155:1;9152:13;9144:197;;;9207:52;9255:3;9246:6;9240:13;6477:12;;-1:-1:-1;;;;;6473:38:18;6461:51;;6565:4;6554:16;;;6548:23;-1:-1:-1;;;;;6544:48:18;6528:14;;;6521:72;6656:4;6645:16;;;6639:23;6632:31;6625:39;6609:14;;6602:63;6393:278;9207:52;9316:15;;;;9288:4;9279:14;;;;;9180:1;9173:9;9144:197;;9372:632;9543:2;9595:21;;;9665:13;;9568:18;;;9687:22;;;9514:4;;9543:2;9766:15;;;;9740:2;9725:18;;;9514:4;9809:169;9823:6;9820:1;9817:13;9809:169;;;9884:13;;9872:26;;9953:15;;;;9918:12;;;;9845:1;9838:9;9809:169;;10383:219;10532:2;10521:9;10514:21;10495:4;10552:44;10592:2;10581:9;10577:18;10569:6;10552:44;:::i;14176:267::-;6477:12;;-1:-1:-1;;;;;6473:38:18;6461:51;;6565:4;6554:16;;;6548:23;-1:-1:-1;;;;;6544:48:18;6528:14;;;6521:72;6656:4;6645:16;;;6639:23;6632:31;6625:39;6609:14;;;6602:63;14374:2;14359:18;;14386:51;6393:278;14630:275;14701:2;14695:9;14766:2;14747:13;;-1:-1:-1;;14743:27:18;14731:40;;-1:-1:-1;;;;;14786:34:18;;14822:22;;;14783:62;14780:88;;;14848:18;;:::i;:::-;14884:2;14877:22;14630:275;;-1:-1:-1;14630:275:18:o;14910:128::-;14950:3;14981:1;14977:6;14974:1;14971:13;14968:39;;;14987:18;;:::i;:::-;-1:-1:-1;15023:9:18;;14910:128::o;15043:168::-;15083:7;15149:1;15145;15141:6;15137:14;15134:1;15131:21;15126:1;15119:9;15112:17;15108:45;15105:71;;;15156:18;;:::i;:::-;-1:-1:-1;15196:9:18;;15043:168::o;15216:125::-;15256:4;15284:1;15281;15278:8;15275:34;;;15289:18;;:::i;:::-;-1:-1:-1;15326:9:18;;15216:125::o;15346:258::-;15418:1;15428:113;15442:6;15439:1;15436:13;15428:113;;;15518:11;;;15512:18;15499:11;;;15492:39;15464:2;15457:10;15428:113;;;15559:6;15556:1;15553:13;15550:48;;;-1:-1:-1;;15594:1:18;15576:16;;15569:27;15346:258::o;15609:136::-;15648:3;15676:5;15666:39;;15685:18;;:::i;:::-;-1:-1:-1;;;15721:18:18;;15609:136::o;15750:380::-;15829:1;15825:12;;;;15872;;;15893:61;;15947:4;15939:6;15935:17;15925:27;;15893:61;16000:2;15992:6;15989:14;15969:18;15966:38;15963:161;;;16046:10;16041:3;16037:20;16034:1;16027:31;16081:4;16078:1;16071:15;16109:4;16106:1;16099:15;15963:161;;15750:380;;;:::o;16135:127::-;16196:10;16191:3;16187:20;16184:1;16177:31;16227:4;16224:1;16217:15;16251:4;16248:1;16241:15;16399:127;16460:10;16455:3;16451:20;16448:1;16441:31;16491:4;16488:1;16481:15;16515:4;16512:1;16505:15;16531:127;16592:10;16587:3;16583:20;16580:1;16573:31;16623:4;16620:1;16613:15;16647:4;16644:1;16637:15;16663:127;16724:10;16719:3;16715:20;16712:1;16705:31;16755:4;16752:1;16745:15;16779:4;16776:1;16769:15;16795:131;-1:-1:-1;;;;;;16869:32:18;;16859:43;;16849:71;;16916:1;16913;16906:12

Swarm Source

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