ETH Price: $3,749.47 (-1.88%)
Gas: 24 Gwei

Token

SOMBRA (SMBR)
 

Overview

Max Total Supply

25,000,000 SMBR

Holders

643 (0.00%)

Total Transfers

-

Market

Price

$0.02 @ 0.000004 ETH (-3.68%)

Onchain Market Cap

$393,013.50

Circulating Supply Market Cap

$790,724.00

Other Info

Token Contract (WITH 9 Decimals)

Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Sombra is an NFT / VFX / Design DAO and a group of experts in digital creation.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Sombra

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-03-19
*/

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


// OpenZeppelin Contracts v4.4.1 (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: @openzeppelin/contracts/utils/introspection/IERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

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


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


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

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


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

pragma solidity ^0.8.0;

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

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

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

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

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

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


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

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


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


// OpenZeppelin Contracts v4.4.1 (access/AccessControl.sol)

pragma solidity ^0.8.0;





/**
 * @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, _msgSender());
        _;
    }

    /**
     * @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 override returns (bool) {
        return _roles[role].members[account];
    }

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


// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)

pragma solidity ^0.8.0;


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


// OpenZeppelin Contracts v4.4.1 (access/AccessControlEnumerable.sol)

pragma solidity ^0.8.0;




/**
 * @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 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 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: ESombra_erc20_final.sol


pragma solidity ^0.8.0;


/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

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

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

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

/**
 * @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() {
        _setOwner(_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 {
        _setOwner(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");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

interface SwapAndLiquifier {
    function swapAndLiquify(uint256 contractTokenBalance) external;

}

contract Sombra is Context, IERC20Metadata, Ownable, AccessControlEnumerable {

    string private constant NAME = "SOMBRA";
    string private constant SYMBOL = "SMBR";
    uint8 private constant DECIMALS = 9;

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

    mapping (address => bool) private _isExcludedFromFee;
    mapping (address => bool) private _isExcluded;

    uint256 private constant MAX_INT = ~uint256(0);
    uint256 private TOTAL_SUPPLY = 0;
    uint256 private MAX_SUPPLY = 100000000  * 10**DECIMALS;
    uint256 private REFLECTION_TOTAL = (MAX_INT - (MAX_INT % MAX_SUPPLY));
    uint256 private _tFeeTotal;

    // _tSupply and _rSupply keep track of the reflection-tokens supply.
    // Essentially, they are the total supply minus balances of excluded addresses.
    uint256 private _tSupply = 0;
    uint256 private _rSupply = 0;
    
    uint256 public _taxFee = 3;
    uint256 public _liquidityFee = 3;
    event TaxFeeUpdated(uint256 oldTaxFee, uint256 newTaxFee);
    event LiquidityFeeUpdated(uint256 oldLiqFee, uint256 newLiqFee);

    // IUniswapV2Router02 public uniswapV2Router;
    // IUniswapV2Pair public uniswapV2Pair;
    // address private WETH;

    event UniswapRouterUpdated(address newRouter);

    mapping (address => bool) public marketPair;
    event MarketPairUpdated(address pair, bool isMarketPair);
    
    bool private inSwapAndLiquify;
    bool public swapAndLiquifyEnabled = true;
    uint256 private numTokensSellToAddToLiquidity = 100000 * 10**DECIMALS;

    // current swapAndLiquify contract address
    address swap_and_liquify_contract;

    event MinTokensBeforeSwapUpdated(uint256 minTokensBeforeSwap);
    event SwapAndLiquifyEnabledUpdated(bool enabled);
    event SwapAndLiquify(
        uint256 tokensSwapped,
        uint256 ethReceived,
        uint256 tokensIntoLiqudity
    );

    event ExcludedFromReward(address account);
    event IncludedInReward(address account);
    event ExcludedFromFee(address account);
    event IncludedInFee(address account);

    // burn permissions
    bool burn_approval_required = false;
    
    mapping (address => bool) public give_right_to_burn;

    // events and variables for crosschain
    event LogSwapin(bytes32 indexed txhash, address indexed account, uint amount);
    event LogSwapout(address indexed account, address indexed bindaddr, uint amount);

    // flag to enable/disable swapout vs vault.burn so multiple events are triggered
    // Disable/Enable swapout for v1 tokens vs mint/burn for v3 tokens
    bool private _vaultOnly = false;

    address public vault;

    function setVaultOnly(bool enabled) external onlyOperator() {
        _vaultOnly = enabled;
    }


    modifier lockTheSwap {
        inSwapAndLiquify = true;
        _;
        inSwapAndLiquify = false;
    }

    // roles for access control //
    bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
    bytes32 public constant VAULT_ROLE = keccak256("VAULT_ROLE");
    
    constructor() {
        // set up roles
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
        _setupRole(OPERATOR_ROLE, _msgSender());
        _setupRole(MINTER_ROLE, _msgSender());
        _setupRole(BURNER_ROLE, _msgSender());
        _setupRole(VAULT_ROLE, _msgSender());

        //exclude owner and this contract from fee
        _isExcludedFromFee[owner()] = true;
        _isExcludedFromFee[address(this)] = true;
        
        uint256 chainId;
        assembly {chainId := chainid()}
        DOMAIN_SEPARATOR = keccak256(
            abi.encode(
                keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                keccak256(bytes("SOMBRA")),
                keccak256(bytes("1")),
                chainId,
                address(this)));

    }

    modifier onlyOperator() {
        require(
            hasRole(OPERATOR_ROLE, _msgSender()),
            'must have operator role to use this function'
        );
        _;
    }

    function name() public pure override returns (string memory) {
        return NAME;
    }

    function symbol() public pure override returns (string memory) {
        return SYMBOL;
    }

    function decimals() public pure override returns (uint8) {
        return DECIMALS;
    }

    function totalSupply() public view override returns (uint256) {
        return TOTAL_SUPPLY;
    }

    function balanceOf(address account) public view override returns (uint256) {
        if (_isExcluded[account]) return _tOwned[account];
        return tokenFromReflection(_rOwned[account]);
    }

    function transfer(address recipient, uint256 amount) public override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    function allowance(address owner, address spender) public view override returns (uint256) {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint256 amount) public override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
        _transfer(sender, recipient, amount);

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

    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        }
        return true;
    }

    function isExcludedFromReward(address account) external view returns (bool) {
        return _isExcluded[account];
    }

    function taxCollected() external view returns (uint256) {
        return _tFeeTotal;
    }

    function deliver(uint256 tAmount) external {
        address sender = _msgSender();
        require(!_isExcluded[sender], "Excluded addresses cannot call this function");

        (uint256 rAmount,,,,,,) = _getValues(tAmount, false);
        _rOwned[sender] = _rOwned[sender] - rAmount;
        _rSupply = _rSupply - rAmount;
        _tFeeTotal = _tFeeTotal + tAmount;
    }

    function reflectionFromToken(uint256 tAmount, bool deductTransferFee) public view returns(uint256) {
        require(tAmount <= MAX_SUPPLY, "Amount must be less than supply");
        (,uint256 rTransferAmount,,,,,) = _getValues(tAmount, deductTransferFee);
        return rTransferAmount;
    }

    function tokenFromReflection(uint256 rAmount) private view returns(uint256) {
        require(rAmount <= _rSupply, "Amount must be less than total reflections");
        uint256 currentRate =  _getRate();
        return rAmount / currentRate;
    }

    function excludeFromReward(address account) external onlyOperator() {
        // require(account != 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D, 'We can not exclude Uniswap router.');
        require(!_isExcluded[account], "Account is already excluded");
        uint256 rBalance = _rOwned[account];
        if(rBalance > 0) {
            uint256 rTokens = tokenFromReflection(rBalance);
            _tOwned[account] = rTokens;
            _rSupply -= rBalance;
            _tSupply -= rTokens;
        }
        _isExcluded[account] = true;

        emit ExcludedFromReward(account);
    }

    function includeInReward(address account) external onlyOperator() {
        require(_isExcluded[account], "Account is already excluded");
        uint256 tOwned = _tOwned[account];
        uint256 rAmount = reflectionFromToken(tOwned, false);

        _tSupply += tOwned;
        _rSupply += rAmount;

        _rOwned[account] = rAmount;
        _tOwned[account] = 0;

        _isExcluded[account] = false;

        emit IncludedInReward(account);
    }

     function burn(address from, uint256 amount) public returns(bool){
         // require this is called to burn your own tokens or an address that has the BURNER_ROLE
        require(from == _msgSender() || 
        hasRole(BURNER_ROLE, _msgSender()) ||
        hasRole(OPERATOR_ROLE, _msgSender()) || 
        _msgSender() == vault
        ,"DOES NOT HAVE RIGHT TO BURN");

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

        require(from != address(0), "do not burn from the zero address");
        // determine if the address from which tokens are being burned is excluded from reflective rewards
        bool isExcludedSender = _isExcluded[from];

        if (isExcludedSender){
            //check that in fact the _tOwned of the burner is greater than the ammount requested to be burned
            require(_tOwned[from] >= amount, "in burn: not enough balance owned by from address");

            _tOwned[from] -= amount;

            // emit the transfer event to indicate the burning to the "zero" address
            emit Transfer(from,address(0), amount);

            TOTAL_SUPPLY -= amount;
            // return true successful burning 
            return true;
        
        }

        // if control gets to here then the burner address is included in the reward
        // we will calculate the appropriate ammount of reflection to remove
        uint256 rAmount = reflectionFromToken(amount, false);

        //check that in fact the _rOwned of the burner is greater than the calculated ammount
        require(_rOwned[from] >= rAmount, "in burn: not enough balance owned by from address");

        unchecked {
            _rOwned[from] -= rAmount;
        }
        
        _rSupply -= rAmount;
        _tSupply -= amount;

        emit Transfer(from, address(0), amount);
        
        TOTAL_SUPPLY -= amount;

        // return true successful burning
        return true;
    }

    
    function mint(address to, uint256 amount) public returns(bool) {
        // require this is called by an address that has the MINTER_ROLE
        require(hasRole(MINTER_ROLE, _msgSender()) ||
        hasRole(OPERATOR_ROLE, _msgSender()) || 
        _msgSender() == vault
        ,"DOES NOT HAVE RIGHT TO MINT");

        require((TOTAL_SUPPLY + amount) <= MAX_SUPPLY, "Minting over MAX_SUPPLY is not permitted");
        require(to != address(0), "do not mint to the zero address");
        // determine if recipient is excluded from reflective rewards
        bool isExcludedRecipient = _isExcluded[to];

        // if the reciever is excluded from the reward then simply increase the _tOwned amount by 
        // the desired amount of tokens
        if (isExcludedRecipient){

            _tOwned[to] += amount;

            // emit the transfer event to indicate the minting from the "zero" address
            emit Transfer(address(0), to, amount);

            // now increase the total supply of the token by the ammount 
            TOTAL_SUPPLY += amount;

            // return true successful minting
            return true;
        
        }

        // if control gets to here then the recipient of the mint is included in the reward
        // we will calculate the appropriate ammount of reflection to give them
        uint256 rAmount = reflectionFromToken(amount, false);
        
        // now based on the amount of tokens minted and the reflection amount change the _tSupply
        // and the _rSupply respectively 
        _tSupply += amount;

        _rSupply += rAmount;
        
        // increast the _rOwned of the recipient 
        _rOwned[to] += rAmount;
        
        // emit the transfer event to indicate the minting from the "zero" address
        emit Transfer(address(0), to, amount);

        // now increase the total supply of the token by the ammount 
        TOTAL_SUPPLY += amount;

        // return true successful minting
        return true;
    }

    /// the following Swapin and Swapout functions are for the benifit of anyswap bridge capabilities
    // 
    function Swapin(bytes32 txhash, address account, uint256 amount) public returns (bool) {
        // require this is called by an address that has the MINTER_ROLE
        require(hasRole(MINTER_ROLE, _msgSender()) ||
        hasRole(OPERATOR_ROLE, _msgSender()) || 
        _msgSender() == vault
        ,"DOES NOT HAVE RIGHT TO MINT");

        mint(account, amount);
        emit LogSwapin(txhash, account, amount);
        return true;
    }

    function Swapout(uint256 amount, address bindaddr) public returns (bool) {
    
        require(!_vaultOnly, "AnyswapV4ERC20: onlyAuth");

        require(bindaddr != address(0), "AnyswapV3ERC20: address(0x0)");

        burn(_msgSender(), amount);

        emit LogSwapout(_msgSender(), bindaddr, amount);

        return true;
    }

    
    function changeVault(address newVault) external returns (bool) {
        
        // require vault has access now //
        require(hasRole(OPERATOR_ROLE, _msgSender()) || 
        _msgSender() == vault
        ,"DOES NOT HAVE RIGHT TO CHANGE VAULT");

        vault = newVault;
        // give vault minting burning swapin and swapout rights //
        
        return true;
    }

    // for compatibility for older versions
    function changeMPCOwner(address newVault) external returns (bool) {

        // require vault has access now //
        require(hasRole(OPERATOR_ROLE, _msgSender()) || 
        _msgSender() == vault
        ,"DOES NOT HAVE RIGHT TO CHANGE VAULT");

        vault = newVault;
        // give vault minting burning swapin and swapout rights //

        return true;
        
    }

    /////////
    bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
    bytes32 public constant TRANSFER_TYPEHASH = keccak256("Transfer(address owner,address to,uint256 value,uint256 nonce,uint256 deadline)");
    bytes32 public immutable DOMAIN_SEPARATOR;
    
    /// @dev Records current ERC2612 nonce for account. This value must be included whenever signature is generated for {permit}.
    /// Every successful call to {permit} increases account's nonce by one. This prevents signature from being used multiple times.
    mapping (address => uint256) public nonces;

        /// @dev Sets `value` as allowance of `spender` account over `owner` account's AnyswapV3ERC20 token, given `owner` account's signed approval.
    /// Emits {Approval} event.
    /// Requirements:
    ///   - `deadline` must be timestamp in future.
    ///   - `v`, `r` and `s` must be valid `secp256k1` signature from `owner` account over EIP712-formatted function arguments.
    ///   - the signature must use `owner` account's current nonce (see {nonces}).
    ///   - the signer cannot be zero address and must be `owner` account.
    /// For more information on signature format, see https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP section].
    /// AnyswapV3ERC20 token implementation adapted from https://github.com/albertocuestacanada/ERC20Permit/blob/master/contracts/ERC20Permit.sol.
    function permit(address target, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external {
        require(block.timestamp <= deadline, "AnyswapV3ERC20: Expired permit");

        bytes32 hashStruct = keccak256(
            abi.encode(
                PERMIT_TYPEHASH,
                target,
                spender,
                value,
                nonces[target]++,
                deadline));

        require(verifyEIP712(target, hashStruct, v, r, s) || verifyPersonalSign(target, hashStruct, v, r, s));

        _approve(target, spender, value);
        emit Approval(target, spender, value);
        
    }


    function verifyEIP712(address target, bytes32 hashStruct, uint8 v, bytes32 r, bytes32 s) internal view returns (bool) {
        bytes32 hash = keccak256(
            abi.encodePacked(
                "\x19\x01",
                DOMAIN_SEPARATOR,
                hashStruct));
        address signer = ecrecover(hash, v, r, s);
        return (signer != address(0) && signer == target);
    }

    function verifyPersonalSign(address target, bytes32 hashStruct, uint8 v, bytes32 r, bytes32 s) internal view returns (bool) {
        bytes32 hash = prefixed(hashStruct);
        address signer = ecrecover(hash, v, r, s);
        return (signer != address(0) && signer == target);
    }

    // Builds a prefixed hash to mimic the behavior of eth_sign.
    function prefixed(bytes32 hash) internal view returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", DOMAIN_SEPARATOR, hash));
    }



    /////

    ///
    
    function excludeFromFee(address account) external onlyOperator {
        _isExcludedFromFee[account] = true;
        emit ExcludedFromFee(account);
    }
    
    function includeInFee(address account) external onlyOperator {
        _isExcludedFromFee[account] = false;
        emit IncludedInFee(account);
    }

    function setTaxFee(uint256 taxFee) external onlyOperator {
        require(taxFee + _liquidityFee <= 6, "Fees cannot exceed 6%");

        uint256 currentTaxFee = _taxFee;
        require(taxFee != currentTaxFee, "Tax fee cannot be the same");

        _taxFee = taxFee;
        emit TaxFeeUpdated(currentTaxFee, taxFee);
    }

    function setLiquidityFee(uint256 liquidityFee) external onlyOperator {
        require(_taxFee + liquidityFee <= 6, "Fees cannot exceed 6%");

        uint256 currentLiqFee = _liquidityFee;
        require(liquidityFee != currentLiqFee, "Liquidity fee cannot be the same");

        _liquidityFee = liquidityFee;
        emit LiquidityFeeUpdated(currentLiqFee, liquidityFee);
    }

    function setMinTokensToSwapAndLiquify(uint256 minTokens) external onlyOperator {
        numTokensSellToAddToLiquidity = minTokens * 10**DECIMALS;
        emit MinTokensBeforeSwapUpdated(numTokensSellToAddToLiquidity);
    }

    function setSwapAndLiquifyEnabled(bool _enabled) external onlyOperator {
        swapAndLiquifyEnabled = _enabled;
        emit SwapAndLiquifyEnabledUpdated(_enabled);
    }

    // function to change the swapAndLiquify contract // 
    function setSwapAndLiquifyContractAddress(address newAddress) public onlyOperator {
        address oldAddress = swap_and_liquify_contract;
        swap_and_liquify_contract = newAddress;

        // Approve the new router to spend contract's tokens.
        _approve(address(this), newAddress, MAX_INT);
        
        // Reset approval on old router. and prevent failure if address is not set/ set to address(0)
        if (oldAddress != address(0)){
        _approve(address(this), oldAddress, 0);
        }
        
    }

    function updateMarketPair(address pair, bool isPair) external onlyOperator {
        _updateMarketPair(pair, isPair);
    }

    function _updateMarketPair(address pair, bool isPair) private {
        require(marketPair[pair] != isPair, "Pair already set");

        marketPair[pair] = isPair;
        emit MarketPairUpdated(pair, isPair);
    }

    // burn permissions setters
    
    function setBurningApprovalRequired(bool allow) external onlyOperator(){
        burn_approval_required = allow;
    }
    
    function setAllowBurning(bool allow) external {
        give_right_to_burn[_msgSender()] = allow;
    }

    // this is to recover erc20 tokens in this contract 
    // or to manually add liquidity if not using swapandliquify
    function transferToken(address token, uint amount, address receiver) onlyOperator() public{
        IERC20 erc20 = IERC20(token);
        erc20.transfer(receiver, amount);
    }



    // Use struct for RValues to prevent stack too deep error.
    struct _RValues {
        uint256 rAmount;
        uint256 rTransferAmount;
        uint256 rFee;
        uint256 rLiquidity;
    }

    // Retrieves rAmount, rTransferAmount, rFee, tTransferAmount, tFee, tLiquidity for provided tAmount.
    function _getValues(uint256 tAmount, bool takeFee) private view returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256) {
        if(!takeFee) {
            uint256 rTokens = tAmount * _getRate();
            return (rTokens, rTokens, 0, tAmount, 0, 0, 0);
        }
        (uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity) = _getTValues(tAmount);
        _RValues memory r = _getRValues(tAmount, tFee, tLiquidity, _getRate());
        return (r.rAmount, r.rTransferAmount, r.rFee, tTransferAmount, tFee, tLiquidity, r.rLiquidity);
    }

    function _getTValues(uint256 tAmount) private view returns (uint256, uint256, uint256) {
        uint256 tFee = calculateTaxFee(tAmount);
        uint256 tLiquidity = calculateLiquidityFee(tAmount);
        uint256 tTransferAmount = tAmount - tFee - tLiquidity;
        return (tTransferAmount, tFee, tLiquidity);
    }

    function _getRValues(uint256 tAmount, uint256 tFee, uint256 tLiquidity, uint256 currentRate) private pure returns (_RValues memory) {
        uint256 rAmount = tAmount * currentRate;
        uint256 rFee = tFee * currentRate;
        uint256 rLiquidity = tLiquidity * currentRate;
        uint256 rTransferAmount = rAmount - rFee - rLiquidity;

        return _RValues(
            rAmount,
            rTransferAmount,
            rFee,
            rLiquidity
        );
    }

    function _getRate() private view returns(uint256) {
        (uint256 rSupply, uint256 tSupply) = _getCurrentSupply();
        return rSupply / tSupply;
    }

    function _getCurrentSupply() private view returns(uint256, uint256) {
        // _tSupply is 0 when every token is held by excluded wallet.
        uint256 tSupply = _tSupply;
        if(tSupply == 0) return (REFLECTION_TOTAL, MAX_SUPPLY);
        return (_rSupply, tSupply);
    }

    function _reflectFee(uint256 rFee, uint256 tFee) private {
        _rSupply    = _rSupply - rFee;
        _tFeeTotal  = _tFeeTotal + tFee;
    }
    
    function _takeLiquidity(address sender, uint256 rLiquidity, uint256 tLiquidity) private {
        if(_isExcluded[address(this)]) {
            _tOwned[address(this)] = _tOwned[address(this)] + tLiquidity;
            _rSupply -= rLiquidity;
            _tSupply -= tLiquidity;
        } else {
            _rOwned[address(this)] = _rOwned[address(this)] + rLiquidity;
        }

        emit Transfer(sender, address(this), tLiquidity);
    }

    function calculateTaxFee(uint256 _amount) private view returns (uint256) {
        return _amount * _taxFee / (10 ** 2);
    }

    function calculateLiquidityFee(uint256 _amount) private view returns (uint256) {
        return _amount * _liquidityFee / (10 ** 2);
    }
    
    function isExcludedFromFee(address account) external view returns(bool) {
        return _isExcludedFromFee[account];
    }

    function _approve(address owner, address spender, uint256 amount) private {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

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

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) private {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");
        
        bool isRecipientMarketPair = marketPair[to];
        bool isSenderMarketPair = marketPair[from];

        // is the token balance of this contract address over the min number of
        // tokens that we need to initiate a swap + liquidity lock?
        // also, don't get caught in a circular liquidity event.
        // also, don't swap & liquify if sender is uniswap pair.
        uint256 contractTokenBalance = balanceOf(address(this));
        
        uint256 numTokens = numTokensSellToAddToLiquidity;
        bool overMinTokenBalance = contractTokenBalance >= numTokens;
        if (
            overMinTokenBalance &&
            !inSwapAndLiquify &&
            isRecipientMarketPair && // Only swap & liquify on sells.
            !isSenderMarketPair &&
            swapAndLiquifyEnabled
        ) {

            // Try to swap and liquify.
           
            inSwapAndLiquify = true;
            
            // swapper is approved and does a transferfrom then executes the appropriate liquidity logic
            // factored out so that different liquidity interfaces can be supported
            SwapAndLiquifier swapper = SwapAndLiquifier(swap_and_liquify_contract);

            try swapper.swapAndLiquify(contractTokenBalance) {} catch {
                
            }

            inSwapAndLiquify = false;
            
        }
        
        // Only deduct fee if the transaction is to/from the market pair.
        bool takeFee = (isRecipientMarketPair || isSenderMarketPair);
        
        //if any account belongs to _isExcludedFromFee account then remove the fee
        if(takeFee && (_isExcludedFromFee[from] || _isExcludedFromFee[to])) {
            takeFee = false;
        }
        
        //transfer amount, it will take tax, burn, liquidity fee
        _tokenTransfer(from, to, amount, takeFee);
    }

    function _tokenTransfer(address sender, address recipient, uint256 amount, bool takeFee) private {
        bool isExcludedSender = _isExcluded[sender];
        bool isExcludedRecipient = _isExcluded[recipient];

        if (isExcludedSender && !isExcludedRecipient) {
            _transferFromExcluded(sender, recipient, amount, takeFee);
        } else if (!isExcludedSender && isExcludedRecipient) {
            _transferToExcluded(sender, recipient, amount, takeFee);
        } else if (!isExcludedSender && !isExcludedRecipient) {
            _transferStandard(sender, recipient, amount, takeFee);
        } else if (isExcludedSender && isExcludedRecipient) {
            _transferBothExcluded(sender, recipient, amount, takeFee);
        }
    }

    function _transferStandard(address sender, address recipient, uint256 tAmount, bool takeFee) private {
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity, uint256 rLiquidity) = _getValues(tAmount, takeFee);

        require(_rOwned[sender] >= rAmount, "Insufficient Balance");
        unchecked {
            _rOwned[sender] -= rAmount;
        }
        _rOwned[recipient] += rTransferAmount;

        // Do not have to change the supply when transfering from/to standard accounts.

        if(tLiquidity != 0) {
            _takeLiquidity(sender, rLiquidity, tLiquidity);
        }
        if(tFee != 0) {
            _reflectFee(rFee, tFee);
        }

        emit Transfer(sender, recipient, tTransferAmount);
    }
    
    function _transferBothExcluded(address sender, address recipient, uint256 tAmount, bool takeFee) private {
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity, uint256 rLiquidity) = _getValues(tAmount, takeFee);

        require(_tOwned[sender] >= tAmount, "Insufficient Balance");
        unchecked {
            _tOwned[sender] -= tAmount;
        }
        _tOwned[recipient] += tTransferAmount;

        // Increase the supply by amount spent on taxes. As that amount is no longer held by an excluded wallet.
        _rSupply += (rAmount - rTransferAmount);
        _tSupply += (tAmount - tTransferAmount);

        if(tLiquidity != 0) {
            _takeLiquidity(sender, rLiquidity, tLiquidity);
        }
        if(tFee != 0) {
            _reflectFee(rFee, tFee);
        }

        emit Transfer(sender, recipient, tTransferAmount);
    }
    
    function _transferToExcluded(address sender, address recipient, uint256 tAmount, bool takeFee) private {
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity, uint256 rLiquidity) = _getValues(tAmount, takeFee);

        require(_rOwned[sender] >= rAmount, "Insufficient Balance");
        unchecked {
            _rOwned[sender] -= rAmount;
        }
        _tOwned[recipient] += tTransferAmount;

        // Decrease the supply by the amount of tokens the user received, as that is now held by an excluded wallet.
        _rSupply -= rTransferAmount;
        _tSupply -= tTransferAmount;

        if(tLiquidity != 0) {
            _takeLiquidity(sender, rLiquidity, tLiquidity);
        }
        if(tFee != 0) {
            _reflectFee(rFee, tFee);
        }

        emit Transfer(sender, recipient, tTransferAmount);
    }

    function _transferFromExcluded(address sender, address recipient, uint256 tAmount, bool takeFee) private {
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity, uint256 rLiquidity) = _getValues(tAmount, takeFee);

        require(_tOwned[sender] >= tAmount, "Insufficient Balance");
        unchecked {
            _tOwned[sender] -= tAmount;
        }
        _rOwned[recipient] += rTransferAmount;

        // Increase the supply by the amount of tokens the user sent, as that is no longer held by an excluded wallet.
        _rSupply += rAmount;
        _tSupply += tAmount;

        if(tLiquidity != 0) {
            _takeLiquidity(sender, rLiquidity, tLiquidity);
        }
        if(tFee != 0) {
            _reflectFee(rFee, tFee);
        }

        emit Transfer(sender, recipient, tTransferAmount);
    }
    
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"ExcludedFromFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"ExcludedFromReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"IncludedInFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"IncludedInReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldLiqFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLiqFee","type":"uint256"}],"name":"LiquidityFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"txhash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LogSwapin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"bindaddr","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LogSwapout","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"bool","name":"isMarketPair","type":"bool"}],"name":"MarketPairUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minTokensBeforeSwap","type":"uint256"}],"name":"MinTokensBeforeSwapUpdated","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":"uint256","name":"tokensSwapped","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethReceived","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokensIntoLiqudity","type":"uint256"}],"name":"SwapAndLiquify","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"SwapAndLiquifyEnabledUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldTaxFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTaxFee","type":"uint256"}],"name":"TaxFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newRouter","type":"address"}],"name":"UniswapRouterUpdated","type":"event"},{"inputs":[],"name":"BURNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","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":[],"name":"OPERATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"txhash","type":"bytes32"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Swapin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"bindaddr","type":"address"}],"name":"Swapout","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"TRANSFER_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VAULT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_liquidityFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_taxFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newVault","type":"address"}],"name":"changeMPCOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newVault","type":"address"}],"name":"changeVault","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tAmount","type":"uint256"}],"name":"deliver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"excludeFromFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"excludeFromReward","outputs":[],"stateMutability":"nonpayable","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":"address","name":"","type":"address"}],"name":"give_right_to_burn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"account","type":"address"}],"name":"includeInFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"includeInReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"marketPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tAmount","type":"uint256"},{"internalType":"bool","name":"deductTransferFee","type":"bool"}],"name":"reflectionFromToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"bool","name":"allow","type":"bool"}],"name":"setAllowBurning","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"allow","type":"bool"}],"name":"setBurningApprovalRequired","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"liquidityFee","type":"uint256"}],"name":"setLiquidityFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minTokens","type":"uint256"}],"name":"setMinTokensToSwapAndLiquify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"setSwapAndLiquifyContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setSwapAndLiquifyEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"taxFee","type":"uint256"}],"name":"setTaxFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setVaultOnly","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":"swapAndLiquifyEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"taxCollected","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":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"transferToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"bool","name":"isPair","type":"bool"}],"name":"updateMarketPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60a06040526000600855620000176009600a6200049d565b62000027906305f5e1006200055c565b60098190556200003a9060001962000598565b62000048906000196200057e565b600a9081556000600c819055600d556003600e819055600f556011805461ff0019166101001790556200007e906009906200049d565b6200008d90620186a06200055c565b6012556013805460ff60a01b191690556015805460ff19169055348015620000b457600080fd5b50620000c033620002b7565b620000cd60003362000307565b620000f97f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9293362000307565b620001257f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a63362000307565b620001517f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8483362000307565b6200017d7f31e0210044b4f6757ce6aa31f9c6e8d4896d24a755014887391a926c5224d9593362000307565b600160066000620001966000546001600160a01b031690565b6001600160a01b0316815260208082019290925260409081016000908120805494151560ff1995861617905530808252600680855291839020805490951660019081179095558251808401845291825265534f4d42524160d01b9184019190915281518083018352938452603160f81b9383019390935280517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f928101929092527f51d2b22e453b3d05b957a369c88fd2379092e7420b42aa1bce150ed7d5c86a98908201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152466080820181905260a082019290925260c00160408051601f19818403018152919052805160209091012060805250620005d1565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b62000313828262000317565b5050565b6200032e82826200035a60201b620022dd1760201c565b60008281526002602090815260409091206200035591839062002348620003e2821b17901c565b505050565b60008281526001602090815260408083206001600160a01b038516845290915290205460ff16620003135760008281526001602081815260408084206001600160a01b0386168086529252808420805460ff19169093179092559051339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b6000620003f9836001600160a01b03841662000402565b90505b92915050565b60008181526001830160205260408120546200044b57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003fc565b506000620003fc565b600181815b8085111562000495578160001904821115620004795762000479620005bb565b808516156200048757918102915b93841c939080029062000459565b509250929050565b6000620003f960ff841683600082620004b957506001620003fc565b81620004c857506000620003fc565b8160018114620004e15760028114620004ec576200050c565b6001915050620003fc565b60ff841115620005005762000500620005bb565b50506001821b620003fc565b5060208310610133831016604e8410600b841016171562000531575081810a620003fc565b6200053d838362000454565b8060001904821115620005545762000554620005bb565b029392505050565b6000816000190483118215151615620005795762000579620005bb565b500290565b600082821015620005935762000593620005bb565b500390565b600082620005b657634e487b7160e01b600052601260045260246000fd5b500690565b634e487b7160e01b600052601160045260246000fd5b608051613ca1620005fb6000396000818161052d015281816129d30152612ae60152613ca16000f3fe608060405234801561001057600080fd5b50600436106103c45760003560e01c80637ecebe00116101ff578063c49b9a801161011a578063dd62ed3e116100ad578063f5b3c3bf1161007c578063f5b3c3bf14610947578063f5b541a61461096a578063f640d5081461097f578063fbfa77cf1461099257600080fd5b8063dd62ed3e146108d5578063ea2f0b371461090e578063ec126c7714610921578063f2fde38b1461093457600080fd5b8063d505accf116100e9578063d505accf1461085a578063d53913931461086d578063d547741f14610894578063d5a162f1146108a757600080fd5b8063c49b9a80146107fe578063c4b740f514610811578063ca15c87314610824578063d498c6e61461083757600080fd5b8063977d3cec11610192578063a217fddf11610161578063a217fddf146107bd578063a457c2d7146107c5578063a9059cbb146107d8578063c4081a4c146107eb57600080fd5b8063977d3cec1461075d57806398c4f1ac146107705780639dc29fac146107975780639fe90789146107aa57600080fd5b8063916a47f7116101ce578063916a47f71461070f57806391d148541461071757806393670c9d1461072a57806395d89b411461073d57600080fd5b80637ecebe001461068b57806388f82020146106ab5780638da5cb5b146106d75780639010d07c146106fc57600080fd5b806339509351116102ef5780635342acb4116102825780636bc87c3a116102515780636bc87c3a1461065457806370a082311461065d578063715018a6146106705780637bb37c8e1461067857600080fd5b80635342acb4146106025780635f9b105d1461062e57806360e232a91461062e578063628d6cba1461064157600080fd5b8063437823ec116102be578063437823ec146105b75780634549b039146105ca5780634a74bb02146105dd57806352390c02146105ef57600080fd5b806339509351146105755780633b124fe7146105885780633bd5d1731461059157806340c10f19146105a457600080fd5b8063282c51f311610367578063357bf15c11610336578063357bf15c146105155780633644e5151461052857806336568abe1461054f5780633685d4191461056257600080fd5b8063282c51f3146104a35780632f2ff15d146104ca57806330adf81f146104df578063313ce5671461050657600080fd5b8063095ea7b3116103a3578063095ea7b31461045157806318160ddd1461046457806323b872dd1461046c578063248a9ca31461047f57600080fd5b8062bf26f4146103c957806301ffc9a71461040357806306fdde0314610426575b600080fd5b6103f07f42ce63790c28229c123925d83266e77c04d28784552ab68b350a9003226cbd5981565b6040519081526020015b60405180910390f35b6104166104113660046137fb565b6109aa565b60405190151581526020016103fa565b604080518082019091526006815265534f4d42524160d01b60208201525b6040516103fa91906138bf565b61041661045f3660046136d8565b6109d5565b6008546103f0565b61041661047a3660046135f2565b6109eb565b6103f061048d366004613778565b6000908152600160208190526040909120015490565b6103f07f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b6104dd6104d8366004613791565b610a5e565b005b6103f07f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b604051600981526020016103fa565b6104dd610523366004613778565b610a8a565b6103f07f000000000000000000000000000000000000000000000000000000000000000081565b6104dd61055d366004613791565b610baa565b6104dd6105703660046135a4565b610c28565b6104166105833660046136d8565b610d87565b6103f0600e5481565b6104dd61059f366004613778565b610dc3565b6104166105b23660046136d8565b610eb3565b6104dd6105c53660046135a4565b61118f565b6103f06105d8366004613825565b61121e565b60115461041690610100900460ff1681565b6104dd6105fd3660046135a4565b61128d565b6104166106103660046135a4565b6001600160a01b031660009081526006602052604090205460ff1690565b61041661063c3660046135a4565b6113fa565b61041661064f366004613791565b6114bb565b6103f0600f5481565b6103f061066b3660046135a4565b6115bb565b6104dd61161a565b6104dd6106863660046136a1565b611680565b6103f06106993660046135a4565b60166020526000908152604090205481565b6104166106b93660046135a4565b6001600160a01b031660009081526007602052604090205460ff1690565b6000546001600160a01b03165b6040516001600160a01b0390911681526020016103fa565b6106e461070a3660046137d9565b6116be565b600b546103f0565b610416610725366004613791565b6116dd565b6104dd61073836600461373e565b611708565b60408051808201909152600481526329a6a12960e11b6020820152610444565b6104dd61076b3660046135a4565b61175a565b6103f07f31e0210044b4f6757ce6aa31f9c6e8d4896d24a755014887391a926c5224d95981565b6104166107a53660046136d8565b6117d5565b6104dd6107b8366004613778565b611b00565b6103f0600081565b6104166107d33660046136d8565b611b7f565b6104166107e63660046136d8565b611c18565b6104dd6107f9366004613778565b611c25565b6104dd61080c36600461373e565b611d3d565b6104dd61081f36600461373e565b611dba565b6103f0610832366004613778565b611e01565b6104166108453660046135a4565b60146020526000908152604090205460ff1681565b6104dd61086836600461362e565b611e18565b6103f07f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6104dd6108a2366004613791565b611f94565b6104dd6108b536600461373e565b336000908152601460205260409020805460ff1916911515919091179055565b6103f06108e33660046135bf565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205490565b6104dd61091c3660046135a4565b611fbb565b61041661092f3660046137b4565b612040565b6104dd6109423660046135a4565b612152565b6104166109553660046135a4565b60106020526000908152604090205460ff1681565b6103f0600080516020613c2c83398151915281565b6104dd61098d366004613702565b61221d565b6015546106e49061010090046001600160a01b031681565b60006001600160e01b03198216635a05180f60e01b14806109cf57506109cf8261235d565b92915050565b60006109e2338484612392565b50600192915050565b60006109f88484846124b7565b6001600160a01b038416600090815260056020908152604080832033845290915290205482811015610a455760405162461bcd60e51b8152600401610a3c9061393e565b60405180910390fd5b610a5385335b858403612392565b506001949350505050565b60008281526001602081905260409091200154610a7b81336126de565b610a858383612742565b505050565b610aa2600080516020613c2c833981519152336116dd565b610abe5760405162461bcd60e51b8152600401610a3c906138f2565b600681600e54610ace9190613a05565b1115610b145760405162461bcd60e51b8152602060048201526015602482015274466565732063616e6e6f742065786365656420362560581b6044820152606401610a3c565b600f5481811415610b675760405162461bcd60e51b815260206004820181905260248201527f4c6971756964697479206665652063616e6e6f74206265207468652073616d656044820152606401610a3c565b600f82905560408051828152602081018490527f2596ea4192286cc20062cf773414aef3b23a5b57b4bdc47f888e9d9059d838c491015b60405180910390a15050565b6001600160a01b0381163314610c1a5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610a3c565b610c248282612764565b5050565b610c40600080516020613c2c833981519152336116dd565b610c5c5760405162461bcd60e51b8152600401610a3c906138f2565b6001600160a01b03811660009081526007602052604090205460ff16610cc45760405162461bcd60e51b815260206004820152601b60248201527f4163636f756e7420697320616c7265616479206578636c7564656400000000006044820152606401610a3c565b6001600160a01b03811660009081526004602052604081205490610ce8828261121e565b905081600c6000828254610cfc9190613a05565b9250508190555080600d6000828254610d159190613a05565b90915550506001600160a01b0383166000818152600360209081526040808320859055600482528083208390556007825291829020805460ff1916905590519182527f47ab6b2d1f416edec684889dc42cd04ed7cc6c6244edaa04c4215e1077548614910160405180910390a1505050565b3360008181526005602090815260408083206001600160a01b038716845290915281205490916109e2918590610dbe908690613a05565b612392565b3360008181526007602052604090205460ff1615610e385760405162461bcd60e51b815260206004820152602c60248201527f4578636c75646564206164647265737365732063616e6e6f742063616c6c207460448201526b3434b990333ab731ba34b7b760a11b6064820152608401610a3c565b6000610e45836000612786565b505050506001600160a01b038516600090815260036020526040902054929350610e73928492509050613b4c565b6001600160a01b038316600090815260036020526040902055600d54610e9a908290613b4c565b600d55600b54610eab908490613a05565b600b55505050565b6000610edf7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336116dd565b80610efd5750610efd600080516020613c2c833981519152336116dd565b80610f20575060155461010090046001600160a01b0316336001600160a01b0316145b610f6c5760405162461bcd60e51b815260206004820152601b60248201527f444f4553204e4f54204841564520524947485420544f204d494e5400000000006044820152606401610a3c565b60095482600854610f7d9190613a05565b1115610fdc5760405162461bcd60e51b815260206004820152602860248201527f4d696e74696e67206f766572204d41585f535550504c59206973206e6f742070604482015267195c9b5a5d1d195960c21b6064820152608401610a3c565b6001600160a01b0383166110325760405162461bcd60e51b815260206004820152601f60248201527f646f206e6f74206d696e7420746f20746865207a65726f2061646472657373006044820152606401610a3c565b6001600160a01b03831660009081526007602052604090205460ff1680156110d2576001600160a01b0384166000908152600460205260408120805485929061107c908490613a05565b90915550506040518381526001600160a01b03851690600090600080516020613c4c8339815191529060200160405180910390a382600860008282546110c29190613a05565b90915550600192506109cf915050565b60006110df84600061121e565b905083600c60008282546110f39190613a05565b9250508190555080600d600082825461110c9190613a05565b90915550506001600160a01b03851660009081526003602052604081208054839290611139908490613a05565b90915550506040518481526001600160a01b03861690600090600080516020613c4c8339815191529060200160405180910390a3836008600082825461117f9190613a05565b9091555060019695505050505050565b6111a7600080516020613c2c833981519152336116dd565b6111c35760405162461bcd60e51b8152600401610a3c906138f2565b6001600160a01b038116600081815260066020908152604091829020805460ff1916600117905590519182527ff1d6512ec7550bf605a5a38910e48fb6a57938ed74a5afa01753fa023001005c91015b60405180910390a150565b60006009548311156112725760405162461bcd60e51b815260206004820152601f60248201527f416d6f756e74206d757374206265206c657373207468616e20737570706c79006044820152606401610a3c565b600061127e8484612786565b50939998505050505050505050565b6112a5600080516020613c2c833981519152336116dd565b6112c15760405162461bcd60e51b8152600401610a3c906138f2565b6001600160a01b03811660009081526007602052604090205460ff161561132a5760405162461bcd60e51b815260206004820152601b60248201527f4163636f756e7420697320616c7265616479206578636c7564656400000000006044820152606401610a3c565b6001600160a01b03811660009081526003602052604090205480156113a657600061135482612822565b6001600160a01b0384166000908152600460205260408120829055600d80549293508492909190611386908490613b4c565b9250508190555080600c600082825461139f9190613b4c565b9091555050505b6001600160a01b038216600081815260076020908152604091829020805460ff1916600117905590519182527f110b1fbed46dec7bc9019c3fba97541a3d64821a824872bb7b2ad678490855bf9101610b9e565b6000611414600080516020613c2c833981519152336116dd565b80611437575060155461010090046001600160a01b0316336001600160a01b0316145b61148f5760405162461bcd60e51b815260206004820152602360248201527f444f4553204e4f54204841564520524947485420544f204348414e474520564160448201526215531560ea1b6064820152608401610a3c565b50601580546001600160a01b0390921661010002610100600160a81b0319909216919091179055600190565b60155460009060ff16156115115760405162461bcd60e51b815260206004820152601860248201527f416e7973776170563445524332303a206f6e6c794175746800000000000000006044820152606401610a3c565b6001600160a01b0382166115675760405162461bcd60e51b815260206004820152601c60248201527f416e7973776170563345524332303a20616464726573732830783029000000006044820152606401610a3c565b61157133846117d5565b506040518381526001600160a01b0383169033907f6b616089d04950dc06c45c6dd787d657980543f89651aec47924752c7d16c8889060200160405180910390a350600192915050565b6001600160a01b03811660009081526007602052604081205460ff16156115f857506001600160a01b031660009081526004602052604090205490565b6001600160a01b0382166000908152600360205260409020546109cf90612822565b6000546001600160a01b031633146116745760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a3c565b61167e600061289f565b565b611698600080516020613c2c833981519152336116dd565b6116b45760405162461bcd60e51b8152600401610a3c906138f2565b610c2482826128ef565b60008281526002602052604081206116d690836129ad565b9392505050565b60009182526001602090815260408084206001600160a01b0393909316845291905290205460ff1690565b611720600080516020613c2c833981519152336116dd565b61173c5760405162461bcd60e51b8152600401610a3c906138f2565b60138054911515600160a01b0260ff60a01b19909216919091179055565b611772600080516020613c2c833981519152336116dd565b61178e5760405162461bcd60e51b8152600401610a3c906138f2565b601380546001600160a01b038381166001600160a01b0319831617909255166117ba3083600019612392565b6001600160a01b03811615610c2457610c2430826000612392565b60006001600160a01b03831633148061181357506118137f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848336116dd565b806118315750611831600080516020613c2c833981519152336116dd565b80611854575060155461010090046001600160a01b0316336001600160a01b0316145b6118a05760405162461bcd60e51b815260206004820152601b60248201527f444f4553204e4f54204841564520524947485420544f204255524e00000000006044820152606401610a3c565b6001600160a01b0383163314611900576001600160a01b0383166000908152600560209081526040808320338452909152902054828110156118f45760405162461bcd60e51b8152600401610a3c9061393e565b6118fe8433610a4b565b505b6001600160a01b0383166119605760405162461bcd60e51b815260206004820152602160248201527f646f206e6f74206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610a3c565b6001600160a01b03831660009081526007602052604090205460ff168015611a28576001600160a01b0384166000908152600460205260409020548311156119ba5760405162461bcd60e51b8152600401610a3c906139b4565b6001600160a01b038416600090815260046020526040812080548592906119e2908490613b4c565b90915550506040518381526000906001600160a01b03861690600080516020613c4c8339815191529060200160405180910390a382600860008282546110c29190613b4c565b6000611a3584600061121e565b6001600160a01b038616600090815260036020526040902054909150811115611a705760405162461bcd60e51b8152600401610a3c906139b4565b6001600160a01b038516600090815260036020526040812080548390039055600d8054839290611aa1908490613b4c565b9250508190555083600c6000828254611aba9190613b4c565b90915550506040518481526000906001600160a01b03871690600080516020613c4c8339815191529060200160405180910390a3836008600082825461117f9190613b4c565b611b18600080516020613c2c833981519152336116dd565b611b345760405162461bcd60e51b8152600401610a3c906138f2565b611b406009600a613a82565b611b4a9082613b2d565b60128190556040519081527f5948780118f41f7c4577ae4619d5cbd064057bd8562d9f7b7e60324053375c0090602001611213565b3360009081526005602090815260408083206001600160a01b038616845290915281205482811015611c015760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610a3c565b611c0e3385858403612392565b5060019392505050565b60006109e23384846124b7565b611c3d600080516020613c2c833981519152336116dd565b611c595760405162461bcd60e51b8152600401610a3c906138f2565b6006600f5482611c699190613a05565b1115611caf5760405162461bcd60e51b8152602060048201526015602482015274466565732063616e6e6f742065786365656420362560581b6044820152606401610a3c565b600e5481811415611d025760405162461bcd60e51b815260206004820152601a60248201527f546178206665652063616e6e6f74206265207468652073616d650000000000006044820152606401610a3c565b600e82905560408051828152602081018490527f2211abb4bbc4d80b7505c31b54d01d15ac6e33a42c59540d309d89daf759063a9101610b9e565b611d55600080516020613c2c833981519152336116dd565b611d715760405162461bcd60e51b8152600401610a3c906138f2565b601180548215156101000261ff00199091161790556040517f53726dfcaf90650aa7eb35524f4d3220f07413c8d6cb404cc8c18bf5591bc1599061121390831515815260200190565b611dd2600080516020613c2c833981519152336116dd565b611dee5760405162461bcd60e51b8152600401610a3c906138f2565b6015805460ff1916911515919091179055565b60008181526002602052604081206109cf906129b9565b83421115611e685760405162461bcd60e51b815260206004820152601e60248201527f416e7973776170563345524332303a2045787069726564207065726d697400006044820152606401610a3c565b6001600160a01b038716600090815260166020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a919086611eb583613baa565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050611f1688828686866129c3565b80611f295750611f298882868686612ab4565b611f3257600080fd5b611f3d888888612392565b866001600160a01b0316886001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92588604051611f8291815260200190565b60405180910390a35050505050505050565b60008281526001602081905260409091200154611fb181336126de565b610a858383612764565b611fd3600080516020613c2c833981519152336116dd565b611fef5760405162461bcd60e51b8152600401610a3c906138f2565b6001600160a01b038116600081815260066020908152604091829020805460ff1916905590519182527f78ce087db51d01d3e32355f2d83455d5a39f99194c8d3d1c2614893695cee4429101611213565b600061206c7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336116dd565b8061208a575061208a600080516020613c2c833981519152336116dd565b806120ad575060155461010090046001600160a01b0316336001600160a01b0316145b6120f95760405162461bcd60e51b815260206004820152601b60248201527f444f4553204e4f54204841564520524947485420544f204d494e5400000000006044820152606401610a3c565b6121038383610eb3565b50826001600160a01b0316847f05d0634fe981be85c22e2942a880821b70095d84e152c3ea3c17a4e4250d9d618460405161214091815260200190565b60405180910390a35060019392505050565b6000546001600160a01b031633146121ac5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a3c565b6001600160a01b0381166122115760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a3c565b61221a8161289f565b50565b612235600080516020613c2c833981519152336116dd565b6122515760405162461bcd60e51b8152600401610a3c906138f2565b60405163a9059cbb60e01b81526001600160a01b0382811660048301526024820184905284919082169063a9059cbb90604401602060405180830381600087803b15801561229e57600080fd5b505af11580156122b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d6919061375b565b5050505050565b6122e782826116dd565b610c245760008281526001602081815260408084206001600160a01b0386168086529252808420805460ff19169093179092559051339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b60006116d6836001600160a01b038416612b6f565b60006001600160e01b03198216637965db0b60e01b14806109cf57506301ffc9a760e01b6001600160e01b03198316146109cf565b6001600160a01b0383166123f45760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610a3c565b6001600160a01b0382166124555760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610a3c565b6001600160a01b0383811660008181526005602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b03831661251b5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610a3c565b6001600160a01b03821661257d5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610a3c565b6001600160a01b0380831660009081526010602052604080822054928616825281205460ff9283169216906125b1306115bb565b60125490915080821080159081906125cc575060115460ff16155b80156125d55750845b80156125df575083155b80156125f25750601154610100900460ff165b1561266a576011805460ff1916600117905560135460405163173865ad60e01b8152600481018590526001600160a01b0390911690819063173865ad90602401600060405180830381600087803b15801561264c57600080fd5b505af192505050801561265d575060015b50506011805460ff191690555b600085806126755750845b90508080156126be57506001600160a01b03891660009081526006602052604090205460ff16806126be57506001600160a01b03881660009081526006602052604090205460ff165b156126c7575060005b6126d389898984612bbe565b505050505050505050565b6126e882826116dd565b610c2457612700816001600160a01b03166014612c65565b61270b836020612c65565b60405160200161271c92919061384a565b60408051601f198184030181529082905262461bcd60e51b8252610a3c916004016138bf565b61274c82826122dd565b6000828152600260205260409020610a859082612348565b61276e8282612e01565b6000828152600260205260409020610a859082612e68565b6000806000806000806000876127c65760006127a0612e7d565b6127aa908b613b2d565b9750879650600095508994508593508392508291506128169050565b60008060006127d48c612ea0565b92509250925060006127ef8d84846127ea612e7d565b612ee3565b805160208201516040830151606090930151919d509b509099509397509195509350909150505b92959891949750929550565b6000600d548211156128895760405162461bcd60e51b815260206004820152602a60248201527f416d6f756e74206d757374206265206c657373207468616e20746f74616c207260448201526965666c656374696f6e7360b01b6064820152608401610a3c565b6000612893612e7d565b90506116d68184613a1d565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03821660009081526010602052604090205460ff16151581151514156129515760405162461bcd60e51b815260206004820152601060248201526f14185a5c88185b1c9958591e481cd95d60821b6044820152606401610a3c565b6001600160a01b038216600081815260106020908152604091829020805460ff19168515159081179091558251938452908301527f160ff69a72bc70f3e792a86c87d27070e421562197f032d96bcab11c5010222e9101610b9e565b60006116d68383612f79565b60006109cf825490565b60405161190160f01b60208201527f0000000000000000000000000000000000000000000000000000000000000000602282015260428101859052600090819060620160408051601f198184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0015b6020604051602081039080840390855afa158015612a72573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590612aa85750876001600160a01b0316816001600160a01b0316145b98975050505050505050565b600080612b34866040517f19457468657265756d205369676e6564204d6573736167653a0a33320000000060208201527f0000000000000000000000000000000000000000000000000000000000000000603c820152605c8101829052600090607c01604051602081830303815290604052805190602001209050919050565b6040805160008082526020820180845284905260ff89169282019290925260608101879052608081018690529192509060019060a001612a50565b6000818152600183016020526040812054612bb6575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109cf565b5060006109cf565b6001600160a01b0380851660009081526007602052604080822054928616825290205460ff9182169116818015612bf3575080155b15612c0957612c0486868686612fa3565b612c5d565b81158015612c145750805b15612c2557612c04868686866130ea565b81158015612c31575080155b15612c4257612c04868686866131c3565b818015612c4c5750805b15612c5d57612c5d86868686613264565b505050505050565b60606000612c74836002613b2d565b612c7f906002613a05565b67ffffffffffffffff811115612c9757612c97613c07565b6040519080825280601f01601f191660200182016040528015612cc1576020820181803683370190505b509050600360fc1b81600081518110612cdc57612cdc613bf1565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612d0b57612d0b613bf1565b60200101906001600160f81b031916908160001a9053506000612d2f846002613b2d565b612d3a906001613a05565b90505b6001811115612db2576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612d6e57612d6e613bf1565b1a60f81b828281518110612d8457612d84613bf1565b60200101906001600160f81b031916908160001a90535060049490941c93612dab81613b93565b9050612d3d565b5083156116d65760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a3c565b612e0b82826116dd565b15610c245760008281526001602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006116d6836001600160a01b038416613347565b6000806000612e8a61343a565b9092509050612e998183613a1d565b9250505090565b600080600080612eaf85613461565b90506000612ebc8661347d565b9050600081612ecb8489613b4c565b612ed59190613b4c565b979296509094509092505050565b612f0e6040518060800160405280600081526020016000815260200160008152602001600081525090565b6000612f1a8387613b2d565b90506000612f288487613b2d565b90506000612f368587613b2d565b9050600081612f458486613b4c565b612f4f9190613b4c565b60408051608081018252958652602086019190915284019290925260608301525095945050505050565b6000826000018281548110612f9057612f90613bf1565b9060005260206000200154905092915050565b6000806000806000806000612fb88989612786565b965096509650965096509650965088600460008d6001600160a01b03166001600160a01b0316815260200190815260200160002054101561300b5760405162461bcd60e51b8152600401610a3c90613986565b6001600160a01b03808c16600090815260046020908152604080832080548e90039055928d16825260039052908120805488929061304a908490613a05565b9250508190555086600d60008282546130639190613a05565b9250508190555088600c600082825461307c9190613a05565b90915550508115613092576130928b828461348f565b82156130a2576130a28584613562565b896001600160a01b03168b6001600160a01b0316600080516020613c4c833981519152866040516130d591815260200190565b60405180910390a35050505050505050505050565b60008060008060008060006130ff8989612786565b965096509650965096509650965086600360008d6001600160a01b03166001600160a01b031681526020019081526020016000205410156131525760405162461bcd60e51b8152600401610a3c90613986565b6001600160a01b03808c16600090815260036020908152604080832080548c90039055928d168252600490529081208054869290613191908490613a05565b9250508190555085600d60008282546131aa9190613b4c565b9250508190555083600c600082825461307c9190613b4c565b60008060008060008060006131d88989612786565b965096509650965096509650965086600360008d6001600160a01b03166001600160a01b0316815260200190815260200160002054101561322b5760405162461bcd60e51b8152600401610a3c90613986565b6001600160a01b03808c1660009081526003602052604080822080548b90039055918c168152908120805488929061307c908490613a05565b60008060008060008060006132798989612786565b965096509650965096509650965088600460008d6001600160a01b03166001600160a01b031681526020019081526020016000205410156132cc5760405162461bcd60e51b8152600401610a3c90613986565b6001600160a01b03808c1660009081526004602052604080822080548d90039055918c1681529081208054869290613305908490613a05565b9091555061331590508688613b4c565b600d60008282546133269190613a05565b909155506133369050848a613b4c565b600c600082825461307c9190613a05565b6000818152600183016020526040812054801561343057600061336b600183613b4c565b855490915060009061337f90600190613b4c565b90508181146133e457600086600001828154811061339f5761339f613bf1565b90600052602060002001549050808760000184815481106133c2576133c2613bf1565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806133f5576133f5613bdb565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506109cf565b60009150506109cf565b600c5460009081908061345657600a5460095492509250509091565b600d54939092509050565b60006064600e54836134739190613b2d565b6109cf9190613a1d565b60006064600f54836134739190613b2d565b3060009081526007602052604090205460ff161561350b57306000908152600460205260409020546134c2908290613a05565b30600090815260046020526040812091909155600d80548492906134e7908490613b4c565b9250508190555080600c60008282546135009190613b4c565b909155506135379050565b30600090815260036020526040902054613526908390613a05565b306000908152600360205260409020555b60405181815230906001600160a01b03851690600080516020613c4c833981519152906020016124aa565b81600d546135709190613b4c565b600d55600b54613581908290613a05565b600b555050565b80356001600160a01b038116811461359f57600080fd5b919050565b6000602082840312156135b657600080fd5b6116d682613588565b600080604083850312156135d257600080fd5b6135db83613588565b91506135e960208401613588565b90509250929050565b60008060006060848603121561360757600080fd5b61361084613588565b925061361e60208501613588565b9150604084013590509250925092565b600080600080600080600060e0888a03121561364957600080fd5b61365288613588565b965061366060208901613588565b95506040880135945060608801359350608088013560ff8116811461368457600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156136b457600080fd5b6136bd83613588565b915060208301356136cd81613c1d565b809150509250929050565b600080604083850312156136eb57600080fd5b6136f483613588565b946020939093013593505050565b60008060006060848603121561371757600080fd5b61372084613588565b92506020840135915061373560408501613588565b90509250925092565b60006020828403121561375057600080fd5b81356116d681613c1d565b60006020828403121561376d57600080fd5b81516116d681613c1d565b60006020828403121561378a57600080fd5b5035919050565b600080604083850312156137a457600080fd5b823591506135e960208401613588565b6000806000606084860312156137c957600080fd5b8335925061361e60208501613588565b600080604083850312156137ec57600080fd5b50508035926020909101359150565b60006020828403121561380d57600080fd5b81356001600160e01b0319811681146116d657600080fd5b6000806040838503121561383857600080fd5b8235915060208301356136cd81613c1d565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613882816017850160208801613b63565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516138b3816028840160208801613b63565b01602801949350505050565b60208152600082518060208401526138de816040850160208701613b63565b601f01601f19169190910160400192915050565b6020808252602c908201527f6d7573742068617665206f70657261746f7220726f6c6520746f20757365207460408201526b3434b990333ab731ba34b7b760a11b606082015260800190565b60208082526028908201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616040820152676c6c6f77616e636560c01b606082015260800190565b602080825260149082015273496e73756666696369656e742042616c616e636560601b604082015260600190565b60208082526031908201527f696e206275726e3a206e6f7420656e6f7567682062616c616e6365206f776e65604082015270642062792066726f6d206164647265737360781b606082015260800190565b60008219821115613a1857613a18613bc5565b500190565b600082613a3a57634e487b7160e01b600052601260045260246000fd5b500490565b600181815b80851115613a7a578160001904821115613a6057613a60613bc5565b80851615613a6d57918102915b93841c9390800290613a44565b509250929050565b60006116d660ff841683600082613a9b575060016109cf565b81613aa8575060006109cf565b8160018114613abe5760028114613ac857613ae4565b60019150506109cf565b60ff841115613ad957613ad9613bc5565b50506001821b6109cf565b5060208310610133831016604e8410600b8410161715613b07575081810a6109cf565b613b118383613a3f565b8060001904821115613b2557613b25613bc5565b029392505050565b6000816000190483118215151615613b4757613b47613bc5565b500290565b600082821015613b5e57613b5e613bc5565b500390565b60005b83811015613b7e578181015183820152602001613b66565b83811115613b8d576000848401525b50505050565b600081613ba257613ba2613bc5565b506000190190565b6000600019821415613bbe57613bbe613bc5565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b801515811461221a57600080fdfe97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122042ed18db273749d0e1dbe137eb625e07bf8d89be8bfe8f1e149782893eeccb1064736f6c63430008070033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106103c45760003560e01c80637ecebe00116101ff578063c49b9a801161011a578063dd62ed3e116100ad578063f5b3c3bf1161007c578063f5b3c3bf14610947578063f5b541a61461096a578063f640d5081461097f578063fbfa77cf1461099257600080fd5b8063dd62ed3e146108d5578063ea2f0b371461090e578063ec126c7714610921578063f2fde38b1461093457600080fd5b8063d505accf116100e9578063d505accf1461085a578063d53913931461086d578063d547741f14610894578063d5a162f1146108a757600080fd5b8063c49b9a80146107fe578063c4b740f514610811578063ca15c87314610824578063d498c6e61461083757600080fd5b8063977d3cec11610192578063a217fddf11610161578063a217fddf146107bd578063a457c2d7146107c5578063a9059cbb146107d8578063c4081a4c146107eb57600080fd5b8063977d3cec1461075d57806398c4f1ac146107705780639dc29fac146107975780639fe90789146107aa57600080fd5b8063916a47f7116101ce578063916a47f71461070f57806391d148541461071757806393670c9d1461072a57806395d89b411461073d57600080fd5b80637ecebe001461068b57806388f82020146106ab5780638da5cb5b146106d75780639010d07c146106fc57600080fd5b806339509351116102ef5780635342acb4116102825780636bc87c3a116102515780636bc87c3a1461065457806370a082311461065d578063715018a6146106705780637bb37c8e1461067857600080fd5b80635342acb4146106025780635f9b105d1461062e57806360e232a91461062e578063628d6cba1461064157600080fd5b8063437823ec116102be578063437823ec146105b75780634549b039146105ca5780634a74bb02146105dd57806352390c02146105ef57600080fd5b806339509351146105755780633b124fe7146105885780633bd5d1731461059157806340c10f19146105a457600080fd5b8063282c51f311610367578063357bf15c11610336578063357bf15c146105155780633644e5151461052857806336568abe1461054f5780633685d4191461056257600080fd5b8063282c51f3146104a35780632f2ff15d146104ca57806330adf81f146104df578063313ce5671461050657600080fd5b8063095ea7b3116103a3578063095ea7b31461045157806318160ddd1461046457806323b872dd1461046c578063248a9ca31461047f57600080fd5b8062bf26f4146103c957806301ffc9a71461040357806306fdde0314610426575b600080fd5b6103f07f42ce63790c28229c123925d83266e77c04d28784552ab68b350a9003226cbd5981565b6040519081526020015b60405180910390f35b6104166104113660046137fb565b6109aa565b60405190151581526020016103fa565b604080518082019091526006815265534f4d42524160d01b60208201525b6040516103fa91906138bf565b61041661045f3660046136d8565b6109d5565b6008546103f0565b61041661047a3660046135f2565b6109eb565b6103f061048d366004613778565b6000908152600160208190526040909120015490565b6103f07f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b6104dd6104d8366004613791565b610a5e565b005b6103f07f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b604051600981526020016103fa565b6104dd610523366004613778565b610a8a565b6103f07f7542acf483916eccef5b829d41ffe98aeac5e14a88b0783ce9da38dfbba2fe2e81565b6104dd61055d366004613791565b610baa565b6104dd6105703660046135a4565b610c28565b6104166105833660046136d8565b610d87565b6103f0600e5481565b6104dd61059f366004613778565b610dc3565b6104166105b23660046136d8565b610eb3565b6104dd6105c53660046135a4565b61118f565b6103f06105d8366004613825565b61121e565b60115461041690610100900460ff1681565b6104dd6105fd3660046135a4565b61128d565b6104166106103660046135a4565b6001600160a01b031660009081526006602052604090205460ff1690565b61041661063c3660046135a4565b6113fa565b61041661064f366004613791565b6114bb565b6103f0600f5481565b6103f061066b3660046135a4565b6115bb565b6104dd61161a565b6104dd6106863660046136a1565b611680565b6103f06106993660046135a4565b60166020526000908152604090205481565b6104166106b93660046135a4565b6001600160a01b031660009081526007602052604090205460ff1690565b6000546001600160a01b03165b6040516001600160a01b0390911681526020016103fa565b6106e461070a3660046137d9565b6116be565b600b546103f0565b610416610725366004613791565b6116dd565b6104dd61073836600461373e565b611708565b60408051808201909152600481526329a6a12960e11b6020820152610444565b6104dd61076b3660046135a4565b61175a565b6103f07f31e0210044b4f6757ce6aa31f9c6e8d4896d24a755014887391a926c5224d95981565b6104166107a53660046136d8565b6117d5565b6104dd6107b8366004613778565b611b00565b6103f0600081565b6104166107d33660046136d8565b611b7f565b6104166107e63660046136d8565b611c18565b6104dd6107f9366004613778565b611c25565b6104dd61080c36600461373e565b611d3d565b6104dd61081f36600461373e565b611dba565b6103f0610832366004613778565b611e01565b6104166108453660046135a4565b60146020526000908152604090205460ff1681565b6104dd61086836600461362e565b611e18565b6103f07f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6104dd6108a2366004613791565b611f94565b6104dd6108b536600461373e565b336000908152601460205260409020805460ff1916911515919091179055565b6103f06108e33660046135bf565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205490565b6104dd61091c3660046135a4565b611fbb565b61041661092f3660046137b4565b612040565b6104dd6109423660046135a4565b612152565b6104166109553660046135a4565b60106020526000908152604090205460ff1681565b6103f0600080516020613c2c83398151915281565b6104dd61098d366004613702565b61221d565b6015546106e49061010090046001600160a01b031681565b60006001600160e01b03198216635a05180f60e01b14806109cf57506109cf8261235d565b92915050565b60006109e2338484612392565b50600192915050565b60006109f88484846124b7565b6001600160a01b038416600090815260056020908152604080832033845290915290205482811015610a455760405162461bcd60e51b8152600401610a3c9061393e565b60405180910390fd5b610a5385335b858403612392565b506001949350505050565b60008281526001602081905260409091200154610a7b81336126de565b610a858383612742565b505050565b610aa2600080516020613c2c833981519152336116dd565b610abe5760405162461bcd60e51b8152600401610a3c906138f2565b600681600e54610ace9190613a05565b1115610b145760405162461bcd60e51b8152602060048201526015602482015274466565732063616e6e6f742065786365656420362560581b6044820152606401610a3c565b600f5481811415610b675760405162461bcd60e51b815260206004820181905260248201527f4c6971756964697479206665652063616e6e6f74206265207468652073616d656044820152606401610a3c565b600f82905560408051828152602081018490527f2596ea4192286cc20062cf773414aef3b23a5b57b4bdc47f888e9d9059d838c491015b60405180910390a15050565b6001600160a01b0381163314610c1a5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610a3c565b610c248282612764565b5050565b610c40600080516020613c2c833981519152336116dd565b610c5c5760405162461bcd60e51b8152600401610a3c906138f2565b6001600160a01b03811660009081526007602052604090205460ff16610cc45760405162461bcd60e51b815260206004820152601b60248201527f4163636f756e7420697320616c7265616479206578636c7564656400000000006044820152606401610a3c565b6001600160a01b03811660009081526004602052604081205490610ce8828261121e565b905081600c6000828254610cfc9190613a05565b9250508190555080600d6000828254610d159190613a05565b90915550506001600160a01b0383166000818152600360209081526040808320859055600482528083208390556007825291829020805460ff1916905590519182527f47ab6b2d1f416edec684889dc42cd04ed7cc6c6244edaa04c4215e1077548614910160405180910390a1505050565b3360008181526005602090815260408083206001600160a01b038716845290915281205490916109e2918590610dbe908690613a05565b612392565b3360008181526007602052604090205460ff1615610e385760405162461bcd60e51b815260206004820152602c60248201527f4578636c75646564206164647265737365732063616e6e6f742063616c6c207460448201526b3434b990333ab731ba34b7b760a11b6064820152608401610a3c565b6000610e45836000612786565b505050506001600160a01b038516600090815260036020526040902054929350610e73928492509050613b4c565b6001600160a01b038316600090815260036020526040902055600d54610e9a908290613b4c565b600d55600b54610eab908490613a05565b600b55505050565b6000610edf7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336116dd565b80610efd5750610efd600080516020613c2c833981519152336116dd565b80610f20575060155461010090046001600160a01b0316336001600160a01b0316145b610f6c5760405162461bcd60e51b815260206004820152601b60248201527f444f4553204e4f54204841564520524947485420544f204d494e5400000000006044820152606401610a3c565b60095482600854610f7d9190613a05565b1115610fdc5760405162461bcd60e51b815260206004820152602860248201527f4d696e74696e67206f766572204d41585f535550504c59206973206e6f742070604482015267195c9b5a5d1d195960c21b6064820152608401610a3c565b6001600160a01b0383166110325760405162461bcd60e51b815260206004820152601f60248201527f646f206e6f74206d696e7420746f20746865207a65726f2061646472657373006044820152606401610a3c565b6001600160a01b03831660009081526007602052604090205460ff1680156110d2576001600160a01b0384166000908152600460205260408120805485929061107c908490613a05565b90915550506040518381526001600160a01b03851690600090600080516020613c4c8339815191529060200160405180910390a382600860008282546110c29190613a05565b90915550600192506109cf915050565b60006110df84600061121e565b905083600c60008282546110f39190613a05565b9250508190555080600d600082825461110c9190613a05565b90915550506001600160a01b03851660009081526003602052604081208054839290611139908490613a05565b90915550506040518481526001600160a01b03861690600090600080516020613c4c8339815191529060200160405180910390a3836008600082825461117f9190613a05565b9091555060019695505050505050565b6111a7600080516020613c2c833981519152336116dd565b6111c35760405162461bcd60e51b8152600401610a3c906138f2565b6001600160a01b038116600081815260066020908152604091829020805460ff1916600117905590519182527ff1d6512ec7550bf605a5a38910e48fb6a57938ed74a5afa01753fa023001005c91015b60405180910390a150565b60006009548311156112725760405162461bcd60e51b815260206004820152601f60248201527f416d6f756e74206d757374206265206c657373207468616e20737570706c79006044820152606401610a3c565b600061127e8484612786565b50939998505050505050505050565b6112a5600080516020613c2c833981519152336116dd565b6112c15760405162461bcd60e51b8152600401610a3c906138f2565b6001600160a01b03811660009081526007602052604090205460ff161561132a5760405162461bcd60e51b815260206004820152601b60248201527f4163636f756e7420697320616c7265616479206578636c7564656400000000006044820152606401610a3c565b6001600160a01b03811660009081526003602052604090205480156113a657600061135482612822565b6001600160a01b0384166000908152600460205260408120829055600d80549293508492909190611386908490613b4c565b9250508190555080600c600082825461139f9190613b4c565b9091555050505b6001600160a01b038216600081815260076020908152604091829020805460ff1916600117905590519182527f110b1fbed46dec7bc9019c3fba97541a3d64821a824872bb7b2ad678490855bf9101610b9e565b6000611414600080516020613c2c833981519152336116dd565b80611437575060155461010090046001600160a01b0316336001600160a01b0316145b61148f5760405162461bcd60e51b815260206004820152602360248201527f444f4553204e4f54204841564520524947485420544f204348414e474520564160448201526215531560ea1b6064820152608401610a3c565b50601580546001600160a01b0390921661010002610100600160a81b0319909216919091179055600190565b60155460009060ff16156115115760405162461bcd60e51b815260206004820152601860248201527f416e7973776170563445524332303a206f6e6c794175746800000000000000006044820152606401610a3c565b6001600160a01b0382166115675760405162461bcd60e51b815260206004820152601c60248201527f416e7973776170563345524332303a20616464726573732830783029000000006044820152606401610a3c565b61157133846117d5565b506040518381526001600160a01b0383169033907f6b616089d04950dc06c45c6dd787d657980543f89651aec47924752c7d16c8889060200160405180910390a350600192915050565b6001600160a01b03811660009081526007602052604081205460ff16156115f857506001600160a01b031660009081526004602052604090205490565b6001600160a01b0382166000908152600360205260409020546109cf90612822565b6000546001600160a01b031633146116745760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a3c565b61167e600061289f565b565b611698600080516020613c2c833981519152336116dd565b6116b45760405162461bcd60e51b8152600401610a3c906138f2565b610c2482826128ef565b60008281526002602052604081206116d690836129ad565b9392505050565b60009182526001602090815260408084206001600160a01b0393909316845291905290205460ff1690565b611720600080516020613c2c833981519152336116dd565b61173c5760405162461bcd60e51b8152600401610a3c906138f2565b60138054911515600160a01b0260ff60a01b19909216919091179055565b611772600080516020613c2c833981519152336116dd565b61178e5760405162461bcd60e51b8152600401610a3c906138f2565b601380546001600160a01b038381166001600160a01b0319831617909255166117ba3083600019612392565b6001600160a01b03811615610c2457610c2430826000612392565b60006001600160a01b03831633148061181357506118137f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848336116dd565b806118315750611831600080516020613c2c833981519152336116dd565b80611854575060155461010090046001600160a01b0316336001600160a01b0316145b6118a05760405162461bcd60e51b815260206004820152601b60248201527f444f4553204e4f54204841564520524947485420544f204255524e00000000006044820152606401610a3c565b6001600160a01b0383163314611900576001600160a01b0383166000908152600560209081526040808320338452909152902054828110156118f45760405162461bcd60e51b8152600401610a3c9061393e565b6118fe8433610a4b565b505b6001600160a01b0383166119605760405162461bcd60e51b815260206004820152602160248201527f646f206e6f74206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610a3c565b6001600160a01b03831660009081526007602052604090205460ff168015611a28576001600160a01b0384166000908152600460205260409020548311156119ba5760405162461bcd60e51b8152600401610a3c906139b4565b6001600160a01b038416600090815260046020526040812080548592906119e2908490613b4c565b90915550506040518381526000906001600160a01b03861690600080516020613c4c8339815191529060200160405180910390a382600860008282546110c29190613b4c565b6000611a3584600061121e565b6001600160a01b038616600090815260036020526040902054909150811115611a705760405162461bcd60e51b8152600401610a3c906139b4565b6001600160a01b038516600090815260036020526040812080548390039055600d8054839290611aa1908490613b4c565b9250508190555083600c6000828254611aba9190613b4c565b90915550506040518481526000906001600160a01b03871690600080516020613c4c8339815191529060200160405180910390a3836008600082825461117f9190613b4c565b611b18600080516020613c2c833981519152336116dd565b611b345760405162461bcd60e51b8152600401610a3c906138f2565b611b406009600a613a82565b611b4a9082613b2d565b60128190556040519081527f5948780118f41f7c4577ae4619d5cbd064057bd8562d9f7b7e60324053375c0090602001611213565b3360009081526005602090815260408083206001600160a01b038616845290915281205482811015611c015760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610a3c565b611c0e3385858403612392565b5060019392505050565b60006109e23384846124b7565b611c3d600080516020613c2c833981519152336116dd565b611c595760405162461bcd60e51b8152600401610a3c906138f2565b6006600f5482611c699190613a05565b1115611caf5760405162461bcd60e51b8152602060048201526015602482015274466565732063616e6e6f742065786365656420362560581b6044820152606401610a3c565b600e5481811415611d025760405162461bcd60e51b815260206004820152601a60248201527f546178206665652063616e6e6f74206265207468652073616d650000000000006044820152606401610a3c565b600e82905560408051828152602081018490527f2211abb4bbc4d80b7505c31b54d01d15ac6e33a42c59540d309d89daf759063a9101610b9e565b611d55600080516020613c2c833981519152336116dd565b611d715760405162461bcd60e51b8152600401610a3c906138f2565b601180548215156101000261ff00199091161790556040517f53726dfcaf90650aa7eb35524f4d3220f07413c8d6cb404cc8c18bf5591bc1599061121390831515815260200190565b611dd2600080516020613c2c833981519152336116dd565b611dee5760405162461bcd60e51b8152600401610a3c906138f2565b6015805460ff1916911515919091179055565b60008181526002602052604081206109cf906129b9565b83421115611e685760405162461bcd60e51b815260206004820152601e60248201527f416e7973776170563345524332303a2045787069726564207065726d697400006044820152606401610a3c565b6001600160a01b038716600090815260166020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a919086611eb583613baa565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050611f1688828686866129c3565b80611f295750611f298882868686612ab4565b611f3257600080fd5b611f3d888888612392565b866001600160a01b0316886001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92588604051611f8291815260200190565b60405180910390a35050505050505050565b60008281526001602081905260409091200154611fb181336126de565b610a858383612764565b611fd3600080516020613c2c833981519152336116dd565b611fef5760405162461bcd60e51b8152600401610a3c906138f2565b6001600160a01b038116600081815260066020908152604091829020805460ff1916905590519182527f78ce087db51d01d3e32355f2d83455d5a39f99194c8d3d1c2614893695cee4429101611213565b600061206c7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336116dd565b8061208a575061208a600080516020613c2c833981519152336116dd565b806120ad575060155461010090046001600160a01b0316336001600160a01b0316145b6120f95760405162461bcd60e51b815260206004820152601b60248201527f444f4553204e4f54204841564520524947485420544f204d494e5400000000006044820152606401610a3c565b6121038383610eb3565b50826001600160a01b0316847f05d0634fe981be85c22e2942a880821b70095d84e152c3ea3c17a4e4250d9d618460405161214091815260200190565b60405180910390a35060019392505050565b6000546001600160a01b031633146121ac5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a3c565b6001600160a01b0381166122115760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a3c565b61221a8161289f565b50565b612235600080516020613c2c833981519152336116dd565b6122515760405162461bcd60e51b8152600401610a3c906138f2565b60405163a9059cbb60e01b81526001600160a01b0382811660048301526024820184905284919082169063a9059cbb90604401602060405180830381600087803b15801561229e57600080fd5b505af11580156122b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d6919061375b565b5050505050565b6122e782826116dd565b610c245760008281526001602081815260408084206001600160a01b0386168086529252808420805460ff19169093179092559051339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b60006116d6836001600160a01b038416612b6f565b60006001600160e01b03198216637965db0b60e01b14806109cf57506301ffc9a760e01b6001600160e01b03198316146109cf565b6001600160a01b0383166123f45760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610a3c565b6001600160a01b0382166124555760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610a3c565b6001600160a01b0383811660008181526005602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b03831661251b5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610a3c565b6001600160a01b03821661257d5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610a3c565b6001600160a01b0380831660009081526010602052604080822054928616825281205460ff9283169216906125b1306115bb565b60125490915080821080159081906125cc575060115460ff16155b80156125d55750845b80156125df575083155b80156125f25750601154610100900460ff165b1561266a576011805460ff1916600117905560135460405163173865ad60e01b8152600481018590526001600160a01b0390911690819063173865ad90602401600060405180830381600087803b15801561264c57600080fd5b505af192505050801561265d575060015b50506011805460ff191690555b600085806126755750845b90508080156126be57506001600160a01b03891660009081526006602052604090205460ff16806126be57506001600160a01b03881660009081526006602052604090205460ff165b156126c7575060005b6126d389898984612bbe565b505050505050505050565b6126e882826116dd565b610c2457612700816001600160a01b03166014612c65565b61270b836020612c65565b60405160200161271c92919061384a565b60408051601f198184030181529082905262461bcd60e51b8252610a3c916004016138bf565b61274c82826122dd565b6000828152600260205260409020610a859082612348565b61276e8282612e01565b6000828152600260205260409020610a859082612e68565b6000806000806000806000876127c65760006127a0612e7d565b6127aa908b613b2d565b9750879650600095508994508593508392508291506128169050565b60008060006127d48c612ea0565b92509250925060006127ef8d84846127ea612e7d565b612ee3565b805160208201516040830151606090930151919d509b509099509397509195509350909150505b92959891949750929550565b6000600d548211156128895760405162461bcd60e51b815260206004820152602a60248201527f416d6f756e74206d757374206265206c657373207468616e20746f74616c207260448201526965666c656374696f6e7360b01b6064820152608401610a3c565b6000612893612e7d565b90506116d68184613a1d565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03821660009081526010602052604090205460ff16151581151514156129515760405162461bcd60e51b815260206004820152601060248201526f14185a5c88185b1c9958591e481cd95d60821b6044820152606401610a3c565b6001600160a01b038216600081815260106020908152604091829020805460ff19168515159081179091558251938452908301527f160ff69a72bc70f3e792a86c87d27070e421562197f032d96bcab11c5010222e9101610b9e565b60006116d68383612f79565b60006109cf825490565b60405161190160f01b60208201527f7542acf483916eccef5b829d41ffe98aeac5e14a88b0783ce9da38dfbba2fe2e602282015260428101859052600090819060620160408051601f198184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0015b6020604051602081039080840390855afa158015612a72573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590612aa85750876001600160a01b0316816001600160a01b0316145b98975050505050505050565b600080612b34866040517f19457468657265756d205369676e6564204d6573736167653a0a33320000000060208201527f7542acf483916eccef5b829d41ffe98aeac5e14a88b0783ce9da38dfbba2fe2e603c820152605c8101829052600090607c01604051602081830303815290604052805190602001209050919050565b6040805160008082526020820180845284905260ff89169282019290925260608101879052608081018690529192509060019060a001612a50565b6000818152600183016020526040812054612bb6575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109cf565b5060006109cf565b6001600160a01b0380851660009081526007602052604080822054928616825290205460ff9182169116818015612bf3575080155b15612c0957612c0486868686612fa3565b612c5d565b81158015612c145750805b15612c2557612c04868686866130ea565b81158015612c31575080155b15612c4257612c04868686866131c3565b818015612c4c5750805b15612c5d57612c5d86868686613264565b505050505050565b60606000612c74836002613b2d565b612c7f906002613a05565b67ffffffffffffffff811115612c9757612c97613c07565b6040519080825280601f01601f191660200182016040528015612cc1576020820181803683370190505b509050600360fc1b81600081518110612cdc57612cdc613bf1565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612d0b57612d0b613bf1565b60200101906001600160f81b031916908160001a9053506000612d2f846002613b2d565b612d3a906001613a05565b90505b6001811115612db2576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612d6e57612d6e613bf1565b1a60f81b828281518110612d8457612d84613bf1565b60200101906001600160f81b031916908160001a90535060049490941c93612dab81613b93565b9050612d3d565b5083156116d65760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a3c565b612e0b82826116dd565b15610c245760008281526001602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006116d6836001600160a01b038416613347565b6000806000612e8a61343a565b9092509050612e998183613a1d565b9250505090565b600080600080612eaf85613461565b90506000612ebc8661347d565b9050600081612ecb8489613b4c565b612ed59190613b4c565b979296509094509092505050565b612f0e6040518060800160405280600081526020016000815260200160008152602001600081525090565b6000612f1a8387613b2d565b90506000612f288487613b2d565b90506000612f368587613b2d565b9050600081612f458486613b4c565b612f4f9190613b4c565b60408051608081018252958652602086019190915284019290925260608301525095945050505050565b6000826000018281548110612f9057612f90613bf1565b9060005260206000200154905092915050565b6000806000806000806000612fb88989612786565b965096509650965096509650965088600460008d6001600160a01b03166001600160a01b0316815260200190815260200160002054101561300b5760405162461bcd60e51b8152600401610a3c90613986565b6001600160a01b03808c16600090815260046020908152604080832080548e90039055928d16825260039052908120805488929061304a908490613a05565b9250508190555086600d60008282546130639190613a05565b9250508190555088600c600082825461307c9190613a05565b90915550508115613092576130928b828461348f565b82156130a2576130a28584613562565b896001600160a01b03168b6001600160a01b0316600080516020613c4c833981519152866040516130d591815260200190565b60405180910390a35050505050505050505050565b60008060008060008060006130ff8989612786565b965096509650965096509650965086600360008d6001600160a01b03166001600160a01b031681526020019081526020016000205410156131525760405162461bcd60e51b8152600401610a3c90613986565b6001600160a01b03808c16600090815260036020908152604080832080548c90039055928d168252600490529081208054869290613191908490613a05565b9250508190555085600d60008282546131aa9190613b4c565b9250508190555083600c600082825461307c9190613b4c565b60008060008060008060006131d88989612786565b965096509650965096509650965086600360008d6001600160a01b03166001600160a01b0316815260200190815260200160002054101561322b5760405162461bcd60e51b8152600401610a3c90613986565b6001600160a01b03808c1660009081526003602052604080822080548b90039055918c168152908120805488929061307c908490613a05565b60008060008060008060006132798989612786565b965096509650965096509650965088600460008d6001600160a01b03166001600160a01b031681526020019081526020016000205410156132cc5760405162461bcd60e51b8152600401610a3c90613986565b6001600160a01b03808c1660009081526004602052604080822080548d90039055918c1681529081208054869290613305908490613a05565b9091555061331590508688613b4c565b600d60008282546133269190613a05565b909155506133369050848a613b4c565b600c600082825461307c9190613a05565b6000818152600183016020526040812054801561343057600061336b600183613b4c565b855490915060009061337f90600190613b4c565b90508181146133e457600086600001828154811061339f5761339f613bf1565b90600052602060002001549050808760000184815481106133c2576133c2613bf1565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806133f5576133f5613bdb565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506109cf565b60009150506109cf565b600c5460009081908061345657600a5460095492509250509091565b600d54939092509050565b60006064600e54836134739190613b2d565b6109cf9190613a1d565b60006064600f54836134739190613b2d565b3060009081526007602052604090205460ff161561350b57306000908152600460205260409020546134c2908290613a05565b30600090815260046020526040812091909155600d80548492906134e7908490613b4c565b9250508190555080600c60008282546135009190613b4c565b909155506135379050565b30600090815260036020526040902054613526908390613a05565b306000908152600360205260409020555b60405181815230906001600160a01b03851690600080516020613c4c833981519152906020016124aa565b81600d546135709190613b4c565b600d55600b54613581908290613a05565b600b555050565b80356001600160a01b038116811461359f57600080fd5b919050565b6000602082840312156135b657600080fd5b6116d682613588565b600080604083850312156135d257600080fd5b6135db83613588565b91506135e960208401613588565b90509250929050565b60008060006060848603121561360757600080fd5b61361084613588565b925061361e60208501613588565b9150604084013590509250925092565b600080600080600080600060e0888a03121561364957600080fd5b61365288613588565b965061366060208901613588565b95506040880135945060608801359350608088013560ff8116811461368457600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156136b457600080fd5b6136bd83613588565b915060208301356136cd81613c1d565b809150509250929050565b600080604083850312156136eb57600080fd5b6136f483613588565b946020939093013593505050565b60008060006060848603121561371757600080fd5b61372084613588565b92506020840135915061373560408501613588565b90509250925092565b60006020828403121561375057600080fd5b81356116d681613c1d565b60006020828403121561376d57600080fd5b81516116d681613c1d565b60006020828403121561378a57600080fd5b5035919050565b600080604083850312156137a457600080fd5b823591506135e960208401613588565b6000806000606084860312156137c957600080fd5b8335925061361e60208501613588565b600080604083850312156137ec57600080fd5b50508035926020909101359150565b60006020828403121561380d57600080fd5b81356001600160e01b0319811681146116d657600080fd5b6000806040838503121561383857600080fd5b8235915060208301356136cd81613c1d565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613882816017850160208801613b63565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516138b3816028840160208801613b63565b01602801949350505050565b60208152600082518060208401526138de816040850160208701613b63565b601f01601f19169190910160400192915050565b6020808252602c908201527f6d7573742068617665206f70657261746f7220726f6c6520746f20757365207460408201526b3434b990333ab731ba34b7b760a11b606082015260800190565b60208082526028908201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616040820152676c6c6f77616e636560c01b606082015260800190565b602080825260149082015273496e73756666696369656e742042616c616e636560601b604082015260600190565b60208082526031908201527f696e206275726e3a206e6f7420656e6f7567682062616c616e6365206f776e65604082015270642062792066726f6d206164647265737360781b606082015260800190565b60008219821115613a1857613a18613bc5565b500190565b600082613a3a57634e487b7160e01b600052601260045260246000fd5b500490565b600181815b80851115613a7a578160001904821115613a6057613a60613bc5565b80851615613a6d57918102915b93841c9390800290613a44565b509250929050565b60006116d660ff841683600082613a9b575060016109cf565b81613aa8575060006109cf565b8160018114613abe5760028114613ac857613ae4565b60019150506109cf565b60ff841115613ad957613ad9613bc5565b50506001821b6109cf565b5060208310610133831016604e8410600b8410161715613b07575081810a6109cf565b613b118383613a3f565b8060001904821115613b2557613b25613bc5565b029392505050565b6000816000190483118215151615613b4757613b47613bc5565b500290565b600082821015613b5e57613b5e613bc5565b500390565b60005b83811015613b7e578181015183820152602001613b66565b83811115613b8d576000848401525b50505050565b600081613ba257613ba2613bc5565b506000190190565b6000600019821415613bbe57613bbe613bc5565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b801515811461221a57600080fdfe97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122042ed18db273749d0e1dbe137eb625e07bf8d89be8bfe8f1e149782893eeccb1064736f6c63430008070033

Deployed Bytecode Sourcemap

37421:31309:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52534:136;;52578:92;52534:136;;;;;7912:25:1;;;7900:2;7885:18;52534:136:0;;;;;;;;29952:214;;;;;;:::i;:::-;;:::i;:::-;;;7739:14:1;;7732:22;7714:41;;7702:2;7687:18;29952:214:0;7574:187:1;41809:91:0;41888:4;;;;;;;;;;;;-1:-1:-1;;;41888:4:0;;;;41809:91;;;;;;;:::i;42750:161::-;;;;;;:::i;:::-;;:::i;42110:100::-;42190:12;;42110:100;;42919:448;;;;;;:::i;:::-;;:::i;24568:123::-;;;;;;:::i;:::-;24634:7;24661:12;;;:6;:12;;;;;;;;:22;;;24568:123;40619:62;;40657:24;40619:62;;24953:147;;;;;;:::i;:::-;;:::i;:::-;;52390:137;;52432:95;52390:137;;42011:91;;;37633:1;21377:36:1;;21365:2;21350:18;42011:91:0;21235:184:1;56214:389:0;;;;;;:::i;:::-;;:::i;52677:41::-;;;;;26001:218;;;;;;:::i;:::-;;:::i;45814:467::-;;;;;;:::i;:::-;;:::i;43375:215::-;;;;;;:::i;:::-;;:::i;38435:26::-;;;;;;44247:382;;;;;;:::i;:::-;;:::i;48541:2050::-;;;;;;:::i;:::-;;:::i;55542:156::-;;;;;;:::i;:::-;;:::i;44637:299::-;;;;;;:::i;:::-;;:::i;38980:40::-;;;;;;;;;;;;45204:602;;;;;;:::i;:::-;;:::i;61689:125::-;;;;;;:::i;:::-;-1:-1:-1;;;;;61779:27:0;61755:4;61779:27;;;:18;:27;;;;;;;;;61689:125;51977:390;;;;;;:::i;:::-;;:::i;51172:345::-;;;;;;:::i;:::-;;:::i;38468:32::-;;;;;;42218:198;;;;;;:::i;:::-;;:::i;36686:94::-;;;:::i;57636:125::-;;;;;;:::i;:::-;;:::i;52995:42::-;;;;;;:::i;:::-;;;;;;;;;;;;;;44017:122;;;;;;:::i;:::-;-1:-1:-1;;;;;44111:20:0;44087:4;44111:20;;;:11;:20;;;;;;;;;44017:122;36035:87;36081:7;36108:6;-1:-1:-1;;;;;36108:6:0;36035:87;;;-1:-1:-1;;;;;6962:32:1;;;6944:51;;6932:2;6917:18;36035:87:0;6798:203:1;30765:145:0;;;;;;:::i;:::-;;:::i;44147:92::-;44221:10;;44147:92;;23453:139;;;;;;:::i;:::-;;:::i;58037:120::-;;;;;;:::i;:::-;;:::i;41908:95::-;41989:6;;;;;;;;;;;;-1:-1:-1;;;41989:6:0;;;;41908:95;;57089:539;;;;;;:::i;:::-;;:::i;40688:60::-;;40725:23;40688:60;;46290:2237;;;;;;:::i;:::-;;:::i;56611:227::-;;;;;;:::i;:::-;;:::i;22544:49::-;;22589:4;22544:49;;43598:411;;;;;;:::i;:::-;;:::i;42424:167::-;;;;;;:::i;:::-;;:::i;55871:335::-;;;;;;:::i;:::-;;:::i;56846:176::-;;;;;;:::i;:::-;;:::i;40214:99::-;;;;;;:::i;:::-;;:::i;31084:134::-;;;;;;:::i;:::-;;:::i;39710:51::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;53875:669;;;;;;:::i;:::-;;:::i;40550:62::-;;40588:24;40550:62;;25345:149;;;;;;:::i;:::-;;:::i;58169:105::-;;;;;;:::i;:::-;17406:10;58226:32;;;;:18;:32;;;;;:40;;-1:-1:-1;;58226:40:0;;;;;;;;;;58169:105;42599:143;;;;;;:::i;:::-;-1:-1:-1;;;;;42707:18:0;;;42680:7;42707:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;42599:143;55710:153;;;;;;:::i;:::-;;:::i;50711:453::-;;;;;;:::i;:::-;;:::i;36935:192::-;;;;;;:::i;:::-;;:::i;38825:43::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;40477:66;;-1:-1:-1;;;;;;;;;;;40477:66:0;;58405:180;;;;;;:::i;:::-;;:::i;40185:20::-;;;;;;;;-1:-1:-1;;;;;40185:20:0;;;29952:214;30037:4;-1:-1:-1;;;;;;30061:57:0;;-1:-1:-1;;;30061:57:0;;:97;;;30122:36;30146:11;30122:23;:36::i;:::-;30054:104;29952:214;-1:-1:-1;;29952:214:0:o;42750:161::-;42825:4;42842:39;17406:10;42865:7;42874:6;42842:8;:39::i;:::-;-1:-1:-1;42899:4:0;42750:161;;;;:::o;42919:448::-;43017:4;43034:36;43044:6;43052:9;43063:6;43034:9;:36::i;:::-;-1:-1:-1;;;;;43110:19:0;;43083:24;43110:19;;;:11;:19;;;;;;;;17406:10;43110:33;;;;;;;;43162:26;;;;43154:79;;;;-1:-1:-1;;;43154:79:0;;;;;;;:::i;:::-;;;;;;;;;43269:57;43278:6;17406:10;43286:12;43319:6;43300:16;:25;43269:8;:57::i;:::-;-1:-1:-1;43355:4:0;;42919:448;-1:-1:-1;;;;42919:448:0:o;24953:147::-;24634:7;24661:12;;;:6;:12;;;;;;;;:22;;23035:30;23046:4;17406:10;23035;:30::i;:::-;25067:25:::1;25078:4;25084:7;25067:10;:25::i;:::-;24953:147:::0;;;:::o;56214:389::-;41673:36;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;41673:36::-;41651:130;;;;-1:-1:-1;;;41651:130:0;;;;;;;:::i;:::-;56328:1:::1;56312:12;56302:7;;:22;;;;:::i;:::-;:27;;56294:61;;;::::0;-1:-1:-1;;;56294:61:0;;14583:2:1;56294:61:0::1;::::0;::::1;14565:21:1::0;14622:2;14602:18;;;14595:30;-1:-1:-1;;;14641:18:1;;;14634:51;14702:18;;56294:61:0::1;14381:345:1::0;56294:61:0::1;56392:13;::::0;56424:29;;::::1;;56416:74;;;::::0;-1:-1:-1;;;56416:74:0;;16416:2:1;56416:74:0::1;::::0;::::1;16398:21:1::0;;;16435:18;;;16428:30;16494:34;16474:18;;;16467:62;16546:18;;56416:74:0::1;16214:356:1::0;56416:74:0::1;56503:13;:28:::0;;;56547:48:::1;::::0;;21156:25:1;;;21212:2;21197:18;;21190:34;;;56547:48:0::1;::::0;21129:18:1;56547:48:0::1;;;;;;;;56283:320;56214:389:::0;:::o;26001:218::-;-1:-1:-1;;;;;26097:23:0;;17406:10;26097:23;26089:83;;;;-1:-1:-1;;;26089:83:0;;20586:2:1;26089:83:0;;;20568:21:1;20625:2;20605:18;;;20598:30;20664:34;20644:18;;;20637:62;-1:-1:-1;;;20715:18:1;;;20708:45;20770:19;;26089:83:0;20384:411:1;26089:83:0;26185:26;26197:4;26203:7;26185:11;:26::i;:::-;26001:218;;:::o;45814:467::-;41673:36;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;41673:36::-;41651:130;;;;-1:-1:-1;;;41651:130:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;45899:20:0;::::1;;::::0;;;:11:::1;:20;::::0;;;;;::::1;;45891:60;;;::::0;-1:-1:-1;;;45891:60:0;;12702:2:1;45891:60:0::1;::::0;::::1;12684:21:1::0;12741:2;12721:18;;;12714:30;12780:29;12760:18;;;12753:57;12827:18;;45891:60:0::1;12500:351:1::0;45891:60:0::1;-1:-1:-1::0;;;;;45979:16:0;::::1;45962:14;45979:16:::0;;;:7:::1;:16;::::0;;;;;;46024:34:::1;45979:16:::0;45962:14;46024:19:::1;:34::i;:::-;46006:52;;46083:6;46071:8;;:18;;;;;;;:::i;:::-;;;;;;;;46112:7;46100:8;;:19;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;46132:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;;;;:26;;;46169:7:::1;:16:::0;;;;;:20;;;46202:11:::1;:20:::0;;;;;;:28;;-1:-1:-1;;46202:28:0::1;::::0;;46248:25;;6944:51:1;;;46248:25:0::1;::::0;6917:18:1;46248:25:0::1;;;;;;;45880:401;;45814:467:::0;:::o;43375:215::-;17406:10;43463:4;43512:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;43512:34:0;;;;;;;;;;43463:4;;43480:80;;43503:7;;43512:47;;43549:10;;43512:47;:::i;:::-;43480:8;:80::i;44247:382::-;17406:10;44301:14;44350:19;;;:11;:19;;;;;;;;44349:20;44341:77;;;;-1:-1:-1;;;44341:77:0;;19422:2:1;44341:77:0;;;19404:21:1;19461:2;19441:18;;;19434:30;19500:34;19480:18;;;19473:62;-1:-1:-1;;;19551:18:1;;;19544:42;19603:19;;44341:77:0;19220:408:1;44341:77:0;44432:15;44457:26;44468:7;44477:5;44457:10;:26::i;:::-;-1:-1:-1;;;;;;;;;44512:15:0;;;;;;:7;:15;;;;;;44431:52;;-1:-1:-1;44512:25:0;;44431:52;;-1:-1:-1;44512:15:0;-1:-1:-1;44512:25:0;:::i;:::-;-1:-1:-1;;;;;44494:15:0;;;;;;:7;:15;;;;;:43;44559:8;;:18;;44570:7;;44559:18;:::i;:::-;44548:8;:29;44601:10;;:20;;44614:7;;44601:20;:::i;:::-;44588:10;:33;-1:-1:-1;;;44247:382:0:o;48541:2050::-;48598:4;48697:34;40588:24;17406:10;23453:139;:::i;48697:34::-;:83;;;-1:-1:-1;48744:36:0;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;48744:36::-;48697:118;;;-1:-1:-1;48810:5:0;;;;;-1:-1:-1;;;;;48810:5:0;17406:10;-1:-1:-1;;;;;48794:21:0;;48697:118;48689:167;;;;-1:-1:-1;;;48689:167:0;;17532:2:1;48689:167:0;;;17514:21:1;17571:2;17551:18;;;17544:30;17610:29;17590:18;;;17583:57;17657:18;;48689:167:0;17330:351:1;48689:167:0;48904:10;;48893:6;48878:12;;:21;;;;:::i;:::-;48877:37;;48869:90;;;;-1:-1:-1;;;48869:90:0;;11523:2:1;48869:90:0;;;11505:21:1;11562:2;11542:18;;;11535:30;11601:34;11581:18;;;11574:62;-1:-1:-1;;;11652:18:1;;;11645:38;11700:19;;48869:90:0;11321:404:1;48869:90:0;-1:-1:-1;;;;;48978:16:0;;48970:60;;;;-1:-1:-1;;;48970:60:0;;15703:2:1;48970:60:0;;;15685:21:1;15742:2;15722:18;;;15715:30;15781:33;15761:18;;;15754:61;15832:18;;48970:60:0;15501:355:1;48970:60:0;-1:-1:-1;;;;;49139:15:0;;49112:24;49139:15;;;:11;:15;;;;;;;;49308:415;;;;-1:-1:-1;;;;;49349:11:0;;;;;;:7;:11;;;;;:21;;49364:6;;49349:11;:21;;49364:6;;49349:21;:::i;:::-;;;;-1:-1:-1;;49480:32:0;;7912:25:1;;;-1:-1:-1;;;;;49480:32:0;;;49497:1;;-1:-1:-1;;;;;;;;;;;49480:32:0;7900:2:1;7885:18;49480:32:0;;;;;;;49620:6;49604:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;49697:4:0;;-1:-1:-1;49690:11:0;;-1:-1:-1;;49690:11:0;49308:415;49909:15;49927:34;49947:6;49955:5;49927:19;:34::i;:::-;49909:52;;50136:6;50124:8;;:18;;;;;;;:::i;:::-;;;;;;;;50167:7;50155:8;;:19;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;50246:11:0;;;;;;:7;:11;;;;;:22;;50261:7;;50246:11;:22;;50261:7;;50246:22;:::i;:::-;;;;-1:-1:-1;;50378:32:0;;7912:25:1;;;-1:-1:-1;;;;;50378:32:0;;;50395:1;;-1:-1:-1;;;;;;;;;;;50378:32:0;7900:2:1;7885:18;50378:32:0;;;;;;;50510:6;50494:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;50579:4:0;;48541:2050;-1:-1:-1;;;;;;48541:2050:0:o;55542:156::-;41673:36;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;41673:36::-;41651:130;;;;-1:-1:-1;;;41651:130:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;55616:27:0;::::1;;::::0;;;:18:::1;:27;::::0;;;;;;;;:34;;-1:-1:-1;;55616:34:0::1;55646:4;55616:34;::::0;;55666:24;;6944:51:1;;;55666:24:0::1;::::0;6917:18:1;55666:24:0::1;;;;;;;;55542:156:::0;:::o;44637:299::-;44727:7;44766:10;;44755:7;:21;;44747:65;;;;-1:-1:-1;;;44747:65:0;;13864:2:1;44747:65:0;;;13846:21:1;13903:2;13883:18;;;13876:30;13942:33;13922:18;;;13915:61;13993:18;;44747:65:0;13662:355:1;44747:65:0;44825:23;44857:38;44868:7;44877:17;44857:10;:38::i;:::-;-1:-1:-1;44823:72:0;;44637:299;-1:-1:-1;;;;;;;;;44637:299:0:o;45204:602::-;41673:36;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;41673:36::-;41651:130;;;;-1:-1:-1;;;41651:130:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;45406:20:0;::::1;;::::0;;;:11:::1;:20;::::0;;;;;::::1;;45405:21;45397:61;;;::::0;-1:-1:-1;;;45397:61:0;;12702:2:1;45397:61:0::1;::::0;::::1;12684:21:1::0;12741:2;12721:18;;;12714:30;12780:29;12760:18;;;12753:57;12827:18;;45397:61:0::1;12500:351:1::0;45397:61:0::1;-1:-1:-1::0;;;;;45488:16:0;::::1;45469;45488::::0;;;:7:::1;:16;::::0;;;;;45518:12;;45515:201:::1;;45547:15;45565:29;45585:8;45565:19;:29::i;:::-;-1:-1:-1::0;;;;;45609:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;:26;;;45650:8:::1;:20:::0;;45547:47;;-1:-1:-1;45662:8:0;;45650;;45609:16;45650:20:::1;::::0;45662:8;;45650:20:::1;:::i;:::-;;;;;;;;45697:7;45685:8;;:19;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;45515:201:0::1;-1:-1:-1::0;;;;;45726:20:0;::::1;;::::0;;;:11:::1;:20;::::0;;;;;;;;:27;;-1:-1:-1;;45726:27:0::1;45749:4;45726:27;::::0;;45771;;6944:51:1;;;45771:27:0::1;::::0;6917:18:1;45771:27:0::1;6798:203:1::0;51977:390:0;52037:4;52108:36;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;52108:36::-;:71;;;-1:-1:-1;52174:5:0;;;;;-1:-1:-1;;;;;52174:5:0;17406:10;-1:-1:-1;;;;;52158:21:0;;52108:71;52100:128;;;;-1:-1:-1;;;52100:128:0;;13460:2:1;52100:128:0;;;13442:21:1;13499:2;13479:18;;;13472:30;13538:34;13518:18;;;13511:62;-1:-1:-1;;;13589:18:1;;;13582:33;13632:19;;52100:128:0;13258:399:1;52100:128:0;-1:-1:-1;52241:5:0;:16;;-1:-1:-1;;;;;52241:16:0;;;;;-1:-1:-1;;;;;;52241:16:0;;;;;;;;;:5;;51977:390::o;51172:345::-;51271:10;;51239:4;;51271:10;;51270:11;51262:48;;;;-1:-1:-1;;;51262:48:0;;16063:2:1;51262:48:0;;;16045:21:1;16102:2;16082:18;;;16075:30;16141:26;16121:18;;;16114:54;16185:18;;51262:48:0;15861:348:1;51262:48:0;-1:-1:-1;;;;;51331:22:0;;51323:63;;;;-1:-1:-1;;;51323:63:0;;12345:2:1;51323:63:0;;;12327:21:1;12384:2;12364:18;;;12357:30;12423;12403:18;;;12396:58;12471:18;;51323:63:0;12143:352:1;51323:63:0;51399:26;17406:10;51418:6;51399:4;:26::i;:::-;-1:-1:-1;51443:42:0;;7912:25:1;;;-1:-1:-1;;;;;51443:42:0;;;17406:10;;51443:42;;7900:2:1;7885:18;51443:42:0;;;;;;;-1:-1:-1;51505:4:0;51172:345;;;;:::o;42218:198::-;-1:-1:-1;;;;;42308:20:0;;42284:7;42308:20;;;:11;:20;;;;;;;;42304:49;;;-1:-1:-1;;;;;;42337:16:0;;;;;:7;:16;;;;;;;42218:198::o;42304:49::-;-1:-1:-1;;;;;42391:16:0;;;;;;:7;:16;;;;;;42371:37;;:19;:37::i;36686:94::-;36081:7;36108:6;-1:-1:-1;;;;;36108:6:0;17406:10;36255:23;36247:68;;;;-1:-1:-1;;;36247:68:0;;15342:2:1;36247:68:0;;;15324:21:1;;;15361:18;;;15354:30;15420:34;15400:18;;;15393:62;15472:18;;36247:68:0;15140:356:1;36247:68:0;36751:21:::1;36769:1;36751:9;:21::i;:::-;36686:94::o:0;57636:125::-;41673:36;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;41673:36::-;41651:130;;;;-1:-1:-1;;;41651:130:0;;;;;;;:::i;:::-;57722:31:::1;57740:4;57746:6;57722:17;:31::i;30765:145::-:0;30847:7;30874:18;;;:12;:18;;;;;:28;;30896:5;30874:21;:28::i;:::-;30867:35;30765:145;-1:-1:-1;;;30765:145:0:o;23453:139::-;23531:4;23555:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;23555:29:0;;;;;;;;;;;;;;;23453:139::o;58037:120::-;41673:36;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;41673:36::-;41651:130;;;;-1:-1:-1;;;41651:130:0;;;;;;;:::i;:::-;58119:22:::1;:30:::0;;;::::1;;-1:-1:-1::0;;;58119:30:0::1;-1:-1:-1::0;;;;58119:30:0;;::::1;::::0;;;::::1;::::0;;58037:120::o;57089:539::-;41673:36;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;41673:36::-;41651:130;;;;-1:-1:-1;;;41651:130:0;;;;;;;:::i;:::-;57203:25:::1;::::0;;-1:-1:-1;;;;;57239:38:0;;::::1;-1:-1:-1::0;;;;;;57239:38:0;::::1;;::::0;;;57203:25:::1;57353:44;57370:4;57267:10:::0;-1:-1:-1;;57353:8:0::1;:44::i;:::-;-1:-1:-1::0;;;;;57525:24:0;::::1;::::0;57521:90:::1;;57561:38;57578:4;57585:10;57597:1;57561:8;:38::i;46290:2237::-:0;46349:4;-1:-1:-1;;;;;46472:20:0;;17406:10;46472:20;;:68;;-1:-1:-1;46506:34:0;40657:24;17406:10;23453:139;:::i;46506:34::-;46472:117;;;-1:-1:-1;46553:36:0;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;46553:36::-;46472:152;;;-1:-1:-1;46619:5:0;;;;;-1:-1:-1;;;;;46619:5:0;17406:10;-1:-1:-1;;;;;46603:21:0;;46472:152;46464:201;;;;-1:-1:-1;;;46464:201:0;;18711:2:1;46464:201:0;;;18693:21:1;18750:2;18730:18;;;18723:30;18789:29;18769:18;;;18762:57;18836:18;;46464:201:0;18509:351:1;46464:201:0;-1:-1:-1;;;;;46682:20:0;;17406:10;46682:20;46678:318;;-1:-1:-1;;;;;46745:17:0;;46718:24;46745:17;;;:11;:17;;;;;;;;17406:10;46745:31;;;;;;;;46799:26;;;;46791:79;;;;-1:-1:-1;;;46791:79:0;;;;;;;:::i;:::-;46914:55;46923:4;17406:10;46929:12;17326:98;46914:55;46703:293;46678:318;-1:-1:-1;;;;;47016:18:0;;47008:64;;;;-1:-1:-1;;;47008:64:0;;13058:2:1;47008:64:0;;;13040:21:1;13097:2;13077:18;;;13070:30;13136:34;13116:18;;;13109:62;-1:-1:-1;;;13187:18:1;;;13180:31;13228:19;;47008:64:0;12856:397:1;47008:64:0;-1:-1:-1;;;;;47215:17:0;;47191:21;47215:17;;;:11;:17;;;;;;;;47245:548;;;;-1:-1:-1;;;;;47400:13:0;;;;;;:7;:13;;;;;;:23;-1:-1:-1;47400:23:0;47392:85;;;;-1:-1:-1;;;47392:85:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;47494:13:0;;;;;;:7;:13;;;;;:23;;47511:6;;47494:13;:23;;47511:6;;47494:23;:::i;:::-;;;;-1:-1:-1;;47625:33:0;;7912:25:1;;;47647:1:0;;-1:-1:-1;;;;;47625:33:0;;;-1:-1:-1;;;;;;;;;;;47625:33:0;7900:2:1;7885:18;47625:33:0;;;;;;;47691:6;47675:12;;:22;;;;;;;:::i;47245:548::-;47969:15;47987:34;48007:6;48015:5;47987:19;:34::i;:::-;-1:-1:-1;;;;;48137:13:0;;;;;;:7;:13;;;;;;47969:52;;-1:-1:-1;48137:24:0;-1:-1:-1;48137:24:0;48129:86;;;;-1:-1:-1;;;48129:86:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;48253:13:0;;;;;;:7;:13;;;;;:24;;;;;;;48309:8;:19;;48270:7;;48253:13;48309:19;;48270:7;;48309:19;:::i;:::-;;;;;;;;48351:6;48339:8;;:18;;;;;;;:::i;:::-;;;;-1:-1:-1;;48375:34:0;;7912:25:1;;;48398:1:0;;-1:-1:-1;;;;;48375:34:0;;;-1:-1:-1;;;;;;;;;;;48375:34:0;7900:2:1;7885:18;48375:34:0;;;;;;;48446:6;48430:12;;:22;;;;;;;:::i;56611:227::-;41673:36;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;41673:36::-;41651:130;;;;-1:-1:-1;;;41651:130:0;;;;;;;:::i;:::-;56745:12:::1;37633:1;56745:2;:12;:::i;:::-;56733:24;::::0;:9;:24:::1;:::i;:::-;56701:29;:56:::0;;;56773:57:::1;::::0;7912:25:1;;;56773:57:0::1;::::0;7900:2:1;7885:18;56773:57:0::1;7766:177:1::0;43598:411:0;17406:10;43691:4;43735:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;43735:34:0;;;;;;;;;;43788:35;;;;43780:85;;;;-1:-1:-1;;;43780:85:0;;20180:2:1;43780:85:0;;;20162:21:1;20219:2;20199:18;;;20192:30;20258:34;20238:18;;;20231:62;-1:-1:-1;;;20309:18:1;;;20302:35;20354:19;;43780:85:0;19978:401:1;43780:85:0;43901:67;17406:10;43924:7;43952:15;43933:16;:34;43901:8;:67::i;:::-;-1:-1:-1;43997:4:0;;43598:411;-1:-1:-1;;;43598:411:0:o;42424:167::-;42502:4;42519:42;17406:10;42543:9;42554:6;42519:9;:42::i;55871:335::-;41673:36;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;41673:36::-;41651:130;;;;-1:-1:-1;;;41651:130:0;;;;;;;:::i;:::-;55973:1:::1;55956:13;;55947:6;:22;;;;:::i;:::-;:27;;55939:61;;;::::0;-1:-1:-1;;;55939:61:0;;14583:2:1;55939:61:0::1;::::0;::::1;14565:21:1::0;14622:2;14602:18;;;14595:30;-1:-1:-1;;;14641:18:1;;;14634:51;14702:18;;55939:61:0::1;14381:345:1::0;55939:61:0::1;56037:7;::::0;56063:23;;::::1;;56055:62;;;::::0;-1:-1:-1;;;56055:62:0;;19067:2:1;56055:62:0::1;::::0;::::1;19049:21:1::0;19106:2;19086:18;;;19079:30;19145:28;19125:18;;;19118:56;19191:18;;56055:62:0::1;18865:350:1::0;56055:62:0::1;56130:7;:16:::0;;;56162:36:::1;::::0;;21156:25:1;;;21212:2;21197:18;;21190:34;;;56162:36:0::1;::::0;21129:18:1;56162:36:0::1;20982:248:1::0;56846:176:0;41673:36;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;41673:36::-;41651:130;;;;-1:-1:-1;;;41651:130:0;;;;;;;:::i;:::-;56928:21:::1;:32:::0;;;::::1;;;;-1:-1:-1::0;;56928:32:0;;::::1;;::::0;;56976:38:::1;::::0;::::1;::::0;::::1;::::0;56952:8;7739:14:1;7732:22;7714:41;;7702:2;7687:18;;7574:187;40214:99:0;41673:36;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;41673:36::-;41651:130;;;;-1:-1:-1;;;41651:130:0;;;;;;;:::i;:::-;40285:10:::1;:20:::0;;-1:-1:-1;;40285:20:0::1;::::0;::::1;;::::0;;;::::1;::::0;;40214:99::o;31084:134::-;31156:7;31183:18;;;:12;:18;;;;;:27;;:25;:27::i;53875:669::-;54035:8;54016:15;:27;;54008:70;;;;-1:-1:-1;;;54008:70:0;;14224:2:1;54008:70:0;;;14206:21:1;14263:2;14243:18;;;14236:30;14302:32;14282:18;;;14275:60;14352:18;;54008:70:0;14022:354:1;54008:70:0;-1:-1:-1;;;;;54274:14:0;;54091:18;54274:14;;;:6;:14;;;;;:16;;52432:95;;54199:6;;54224:7;;54250:5;;54274:16;54091:18;54274:16;;;:::i;:::-;;;;-1:-1:-1;54136:182:0;;;;;;8235:25:1;;;;-1:-1:-1;;;;;8334:15:1;;;8314:18;;;8307:43;8386:15;;;;8366:18;;;8359:43;8418:18;;;8411:34;8461:19;;;8454:35;8505:19;;;8498:35;;;8207:19;;54136:182:0;;;;;;;;;;;;54112:207;;;;;;54091:228;;54340:41;54353:6;54361:10;54373:1;54376;54379;54340:12;:41::i;:::-;:92;;;;54385:47;54404:6;54412:10;54424:1;54427;54430;54385:18;:47::i;:::-;54332:101;;;;;;54446:32;54455:6;54463:7;54472:5;54446:8;:32::i;:::-;54511:7;-1:-1:-1;;;;;54494:32:0;54503:6;-1:-1:-1;;;;;54494:32:0;;54520:5;54494:32;;;;7912:25:1;;7900:2;7885:18;;7766:177;54494:32:0;;;;;;;;53997:547;53875:669;;;;;;;:::o;25345:149::-;24634:7;24661:12;;;:6;:12;;;;;;;;:22;;23035:30;23046:4;17406:10;23035;:30::i;:::-;25460:26:::1;25472:4;25478:7;25460:11;:26::i;55710:153::-:0;41673:36;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;41673:36::-;41651:130;;;;-1:-1:-1;;;41651:130:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;55782:27:0;::::1;55812:5;55782:27:::0;;;:18:::1;:27;::::0;;;;;;;;:35;;-1:-1:-1;;55782:35:0::1;::::0;;55833:22;;6944:51:1;;;55833:22:0::1;::::0;6917:18:1;55833:22:0::1;6798:203:1::0;50711:453:0;50792:4;50891:34;40588:24;17406:10;23453:139;:::i;50891:34::-;:83;;;-1:-1:-1;50938:36:0;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;50938:36::-;50891:118;;;-1:-1:-1;51004:5:0;;;;;-1:-1:-1;;;;;51004:5:0;17406:10;-1:-1:-1;;;;;50988:21:0;;50891:118;50883:167;;;;-1:-1:-1;;;50883:167:0;;17532:2:1;50883:167:0;;;17514:21:1;17571:2;17551:18;;;17544:30;17610:29;17590:18;;;17583:57;17657:18;;50883:167:0;17330:351:1;50883:167:0;51063:21;51068:7;51077:6;51063:4;:21::i;:::-;;51118:7;-1:-1:-1;;;;;51100:34:0;51110:6;51100:34;51127:6;51100:34;;;;7912:25:1;;7900:2;7885:18;;7766:177;51100:34:0;;;;;;;;-1:-1:-1;51152:4:0;50711:453;;;;;:::o;36935:192::-;36081:7;36108:6;-1:-1:-1;;;;;36108:6:0;17406:10;36255:23;36247:68;;;;-1:-1:-1;;;36247:68:0;;15342:2:1;36247:68:0;;;15324:21:1;;;15361:18;;;15354:30;15420:34;15400:18;;;15393:62;15472:18;;36247:68:0;15140:356:1;36247:68:0;-1:-1:-1;;;;;37024:22:0;::::1;37016:73;;;::::0;-1:-1:-1;;;37016:73:0;;10713:2:1;37016:73:0::1;::::0;::::1;10695:21:1::0;10752:2;10732:18;;;10725:30;10791:34;10771:18;;;10764:62;-1:-1:-1;;;10842:18:1;;;10835:36;10888:19;;37016:73:0::1;10511:402:1::0;37016:73:0::1;37100:19;37110:8;37100:9;:19::i;:::-;36935:192:::0;:::o;58405:180::-;41673:36;-1:-1:-1;;;;;;;;;;;17406:10:0;23453:139;:::i;41673:36::-;41651:130;;;;-1:-1:-1;;;41651:130:0;;;;;;;:::i;:::-;58545:32:::1;::::0;-1:-1:-1;;;58545:32:0;;-1:-1:-1;;;;;7487:32:1;;;58545::0::1;::::0;::::1;7469:51:1::0;7536:18;;;7529:34;;;58528:5:0;;58545:14;;::::1;::::0;::::1;::::0;7442:18:1;;58545:32:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;58495:90;58405:180:::0;;;:::o;27502:238::-;27586:22;27594:4;27600:7;27586;:22::i;:::-;27581:152;;27625:12;;;;27657:4;27625:12;;;;;;;;-1:-1:-1;;;;;27625:29:0;;;;;;;;;;:36;;-1:-1:-1;;27625:36:0;;;;;;;27681:40;;17406:10;;27625:12;;27681:40;;27625:12;27681:40;27502:238;;:::o;7872:152::-;7942:4;7966:50;7971:3;-1:-1:-1;;;;;7991:23:0;;7966:4;:50::i;23157:204::-;23242:4;-1:-1:-1;;;;;;23266:47:0;;-1:-1:-1;;;23266:47:0;;:87;;-1:-1:-1;;;;;;;;;;14468:40:0;;;23317:36;14359:157;61822:337;-1:-1:-1;;;;;61915:19:0;;61907:68;;;;-1:-1:-1;;;61907:68:0;;17888:2:1;61907:68:0;;;17870:21:1;17927:2;17907:18;;;17900:30;17966:34;17946:18;;;17939:62;-1:-1:-1;;;18017:18:1;;;18010:34;18061:19;;61907:68:0;17686:400:1;61907:68:0;-1:-1:-1;;;;;61994:21:0;;61986:68;;;;-1:-1:-1;;;61986:68:0;;11120:2:1;61986:68:0;;;11102:21:1;11159:2;11139:18;;;11132:30;11198:34;11178:18;;;11171:62;-1:-1:-1;;;11249:18:1;;;11242:32;11291:19;;61986:68:0;10918:398:1;61986:68:0;-1:-1:-1;;;;;62067:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;62119:32;;7912:25:1;;;62119:32:0;;7885:18:1;62119:32:0;;;;;;;;61822:337;;;:::o;62167:2168::-;-1:-1:-1;;;;;62289:18:0;;62281:68;;;;-1:-1:-1;;;62281:68:0;;17126:2:1;62281:68:0;;;17108:21:1;17165:2;17145:18;;;17138:30;17204:34;17184:18;;;17177:62;-1:-1:-1;;;17255:18:1;;;17248:35;17300:19;;62281:68:0;16924:401:1;62281:68:0;-1:-1:-1;;;;;62368:16:0;;62360:64;;;;-1:-1:-1;;;62360:64:0;;9898:2:1;62360:64:0;;;9880:21:1;9937:2;9917:18;;;9910:30;9976:34;9956:18;;;9949:62;-1:-1:-1;;;10027:18:1;;;10020:33;10070:19;;62360:64:0;9696:399:1;62360:64:0;-1:-1:-1;;;;;62474:14:0;;;62445:26;62474:14;;;:10;:14;;;;;;;62525:16;;;;;;;;62474:14;;;;;62525:16;;62867:24;62885:4;62867:9;:24::i;:::-;62932:29;;62836:55;;-1:-1:-1;62999:33:0;;;;;;;;63061:53;;-1:-1:-1;63098:16:0;;;;63097:17;63061:53;:91;;;;;63131:21;63061:91;:160;;;;;63203:18;63202:19;63061:160;:198;;;;-1:-1:-1;63238:21:0;;;;;;;63061:198;63043:787;;;63342:16;:23;;-1:-1:-1;;63342:23:0;63361:4;63342:23;;;63629:25;;63676:44;;-1:-1:-1;;;63676:44:0;;;;;7912:25:1;;;-1:-1:-1;;;;;63629:25:0;;;;;;63676:22;;7885:18:1;;63676:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63672:92;-1:-1:-1;63780:16:0;:24;;-1:-1:-1;;63780:24:0;;;63043:787;63925:12;63941:21;:43;;;;63966:18;63941:43;63925:60;;64093:7;:63;;;;-1:-1:-1;;;;;;64105:24:0;;;;;;:18;:24;;;;;;;;;:50;;-1:-1:-1;;;;;;64133:22:0;;;;;;:18;:22;;;;;;;;64105:50;64090:110;;;-1:-1:-1;64183:5:0;64090:110;64286:41;64301:4;64307:2;64311:6;64319:7;64286:14;:41::i;:::-;62270:2065;;;;;;62167:2168;;;:::o;23882:497::-;23963:22;23971:4;23977:7;23963;:22::i;:::-;23958:414;;24151:41;24179:7;-1:-1:-1;;;;;24151:41:0;24189:2;24151:19;:41::i;:::-;24265:38;24293:4;24300:2;24265:19;:38::i;:::-;24056:270;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;24056:270:0;;;;;;;;;;-1:-1:-1;;;24002:358:0;;;;;;;:::i;31311:169::-;31399:31;31416:4;31422:7;31399:16;:31::i;:::-;31441:18;;;;:12;:18;;;;;:31;;31464:7;31441:22;:31::i;31574:174::-;31663:32;31681:4;31687:7;31663:17;:32::i;:::-;31706:18;;;;:12;:18;;;;;:34;;31732:7;31706:25;:34::i;58911:572::-;58984:7;58993;59002;59011;59020;59029;59038;59062;59058:139;;59086:15;59114:10;:8;:10::i;:::-;59104:20;;:7;:20;:::i;:::-;59086:38;-1:-1:-1;59086:38:0;;-1:-1:-1;59165:1:0;;-1:-1:-1;59168:7:0;;-1:-1:-1;59165:1:0;;-1:-1:-1;59165:1:0;;-1:-1:-1;59165:1:0;;-1:-1:-1;59139:46:0;;-1:-1:-1;59139:46:0;59058:139;59208:23;59233:12;59247:18;59269:20;59281:7;59269:11;:20::i;:::-;59207:82;;;;;;59300:17;59320:50;59332:7;59341:4;59347:10;59359;:8;:10::i;:::-;59320:11;:50::i;:::-;59389:9;;59400:17;;;;59419:6;;;;59462:12;;;;;59389:9;;-1:-1:-1;59400:17:0;-1:-1:-1;59419:6:0;;-1:-1:-1;59427:15:0;;-1:-1:-1;59444:4:0;;-1:-1:-1;59450:10:0;-1:-1:-1;59462:12:0;;-1:-1:-1;;58911:572:0;;;;;;;;;;;:::o;44944:252::-;45011:7;45050:8;;45039:7;:19;;45031:74;;;;-1:-1:-1;;;45031:74:0;;10302:2:1;45031:74:0;;;10284:21:1;10341:2;10321:18;;;10314:30;10380:34;10360:18;;;10353:62;-1:-1:-1;;;10431:18:1;;;10424:40;10481:19;;45031:74:0;10100:406:1;45031:74:0;45116:19;45139:10;:8;:10::i;:::-;45116:33;-1:-1:-1;45167:21:0;45116:33;45167:7;:21;:::i;37135:173::-;37191:16;37210:6;;-1:-1:-1;;;;;37227:17:0;;;-1:-1:-1;;;;;;37227:17:0;;;;;;37260:40;;37210:6;;;;;;;37260:40;;37191:16;37260:40;37180:128;37135:173;:::o;57769:221::-;-1:-1:-1;;;;;57850:16:0;;;;;;:10;:16;;;;;;;;:26;;;;;;;57842:55;;;;-1:-1:-1;;;57842:55:0;;19835:2:1;57842:55:0;;;19817:21:1;19874:2;19854:18;;;19847:30;-1:-1:-1;;;19893:18:1;;;19886:46;19949:18;;57842:55:0;19633:340:1;57842:55:0;-1:-1:-1;;;;;57910:16:0;;;;;;:10;:16;;;;;;;;;:25;;-1:-1:-1;;57910:25:0;;;;;;;;;;57951:31;;7174:51:1;;;7241:18;;;7234:50;57951:31:0;;7147:18:1;57951:31:0;7006:284:1;9168:158:0;9242:7;9293:22;9297:3;9309:5;9293:3;:22::i;8697:117::-;8760:7;8787:19;8795:3;4181:18;;4098:109;54554:399;54722:110;;-1:-1:-1;;;54722:110:0;;;5868:27:1;54786:16:0;5911:11:1;;;5904:27;5947:12;;;5940:28;;;54666:4:0;;;;5984:12:1;;54722:110:0;;;-1:-1:-1;;54722:110:0;;;;;;;;;54698:135;;54722:110;54698:135;;;;54844:14;54861:24;;;;;;;;;8771:25:1;;;8844:4;8832:17;;8812:18;;;8805:45;;;;8866:18;;;8859:34;;;8909:18;;;8902:34;;;54698:135:0;;-1:-1:-1;54844:14:0;54861:24;;8743:19:1;;54861:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;54861:24:0;;-1:-1:-1;;54861:24:0;;;-1:-1:-1;;;;;;;54904:20:0;;;;;;:40;;;54938:6;-1:-1:-1;;;;;54928:16:0;:6;-1:-1:-1;;;;;54928:16:0;;54904:40;54896:49;54554:399;-1:-1:-1;;;;;;;;54554:399:0:o;54961:290::-;55079:4;55096:12;55111:20;55120:10;55417:76;;5430:66:1;55417:76:0;;;5418:79:1;55470:16:0;5513:12:1;;;5506:28;5550:12;;;5543:28;;;55380:7:0;;5587:12:1;;55417:76:0;;;;;;;;;;;;55407:87;;;;;;55400:94;;55325:177;;;;55111:20;55159:24;;;55142:14;55159:24;;;;;;;;;8771:25:1;;;8844:4;8832:17;;8812:18;;;8805:45;;;;8866:18;;;8859:34;;;8909:18;;;8902:34;;;55096:35:0;;-1:-1:-1;55142:14:0;55159:24;;8743:19:1;;55159:24:0;8544:398:1;1787:414:0;1850:4;3980:19;;;:12;;;:19;;;;;;1867:327;;-1:-1:-1;1910:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;2093:18;;2071:19;;;:12;;;:19;;;;;;:40;;;;2126:11;;1867:327;-1:-1:-1;2177:5:0;2170:12;;64343:763;-1:-1:-1;;;;;64475:19:0;;;64451:21;64475:19;;;:11;:19;;;;;;;64532:22;;;;;;;;64475:19;;;;;64532:22;64475:19;64571:40;;;;;64592:19;64591:20;64571:40;64567:532;;;64628:57;64650:6;64658:9;64669:6;64677:7;64628:21;:57::i;:::-;64567:532;;;64708:16;64707:17;:40;;;;;64728:19;64707:40;64703:396;;;64764:55;64784:6;64792:9;64803:6;64811:7;64764:19;:55::i;64703:396::-;64842:16;64841:17;:41;;;;;64863:19;64862:20;64841:41;64837:262;;;64899:53;64917:6;64925:9;64936:6;64944:7;64899:17;:53::i;64837:262::-;64974:16;:39;;;;;64994:19;64974:39;64970:129;;;65030:57;65052:6;65060:9;65071:6;65079:7;65030:21;:57::i;:::-;64440:666;;64343:763;;;;:::o;16189:451::-;16264:13;16290:19;16322:10;16326:6;16322:1;:10;:::i;:::-;:14;;16335:1;16322:14;:::i;:::-;16312:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16312:25:0;;16290:47;;-1:-1:-1;;;16348:6:0;16355:1;16348:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;16348:15:0;;;;;;;;;-1:-1:-1;;;16374:6:0;16381:1;16374:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;16374:15:0;;;;;;;;-1:-1:-1;16405:9:0;16417:10;16421:6;16417:1;:10;:::i;:::-;:14;;16430:1;16417:14;:::i;:::-;16405:26;;16400:135;16437:1;16433;:5;16400:135;;;-1:-1:-1;;;16485:5:0;16493:3;16485:11;16472:25;;;;;;;:::i;:::-;;;;16460:6;16467:1;16460:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;16460:37:0;;;;;;;;-1:-1:-1;16522:1:0;16512:11;;;;;16440:3;;;:::i;:::-;;;16400:135;;;-1:-1:-1;16553:10:0;;16545:55;;;;-1:-1:-1;;;16545:55:0;;9537:2:1;16545:55:0;;;9519:21:1;;;9556:18;;;9549:30;9615:34;9595:18;;;9588:62;9667:18;;16545:55:0;9335:356:1;27872:239:0;27956:22;27964:4;27970:7;27956;:22::i;:::-;27952:152;;;28027:5;27995:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;27995:29:0;;;;;;;;;;:37;;-1:-1:-1;;27995:37:0;;;28052:40;17406:10;;27995:12;;28052:40;;28027:5;28052:40;27872:239;;:::o;8200:158::-;8273:4;8297:53;8305:3;-1:-1:-1;;;;;8325:23:0;;8297:7;:53::i;60320:160::-;60361:7;60382:15;60399;60418:19;:17;:19::i;:::-;60381:56;;-1:-1:-1;60381:56:0;-1:-1:-1;60455:17:0;60381:56;;60455:17;:::i;:::-;60448:24;;;;60320:160;:::o;59491:324::-;59551:7;59560;59569;59589:12;59604:24;59620:7;59604:15;:24::i;:::-;59589:39;;59639:18;59660:30;59682:7;59660:21;:30::i;:::-;59639:51;-1:-1:-1;59701:23:0;59639:51;59727:14;59737:4;59727:7;:14;:::i;:::-;:27;;;;:::i;:::-;59701:53;59790:4;;-1:-1:-1;59796:10:0;;-1:-1:-1;59491:324:0;;-1:-1:-1;;;59491:324:0:o;59823:489::-;59938:15;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59938:15:0;59966;59984:21;59994:11;59984:7;:21;:::i;:::-;59966:39;-1:-1:-1;60016:12:0;60031:18;60038:11;60031:4;:18;:::i;:::-;60016:33;-1:-1:-1;60060:18:0;60081:24;60094:11;60081:10;:24;:::i;:::-;60060:45;-1:-1:-1;60116:23:0;60060:45;60142:14;60152:4;60142:7;:14;:::i;:::-;:27;;;;:::i;:::-;60189:115;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;60189:115:0;59823:489;-1:-1:-1;;;;;59823:489:0:o;4561:120::-;4628:7;4655:3;:11;;4667:5;4655:18;;;;;;;;:::i;:::-;;;;;;;;;4648:25;;4561:120;;;;:::o;67815:906::-;67932:15;67949:23;67974:12;67988:23;68013:12;68027:18;68047;68069:28;68080:7;68089;68069:10;:28::i;:::-;67931:166;;;;;;;;;;;;;;68137:7;68118;:15;68126:6;-1:-1:-1;;;;;68118:15:0;-1:-1:-1;;;;;68118:15:0;;;;;;;;;;;;;:26;;68110:59;;;;-1:-1:-1;;;68110:59:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;68205:15:0;;;;;;;:7;:15;;;;;;;;:26;;;;;;;68253:18;;;;;:7;:18;;;;;:37;;68275:15;;68205;68253:37;;68275:15;;68253:37;:::i;:::-;;;;;;;;68435:7;68423:8;;:19;;;;;;;:::i;:::-;;;;;;;;68465:7;68453:8;;:19;;;;;;;:::i;:::-;;;;-1:-1:-1;;68488:15:0;;68485:93;;68520:46;68535:6;68543:10;68555;68520:14;:46::i;:::-;68591:9;;68588:64;;68617:23;68629:4;68635;68617:11;:23::i;:::-;68686:9;-1:-1:-1;;;;;68669:44:0;68678:6;-1:-1:-1;;;;;68669:44:0;-1:-1:-1;;;;;;;;;;;68697:15:0;68669:44;;;;7912:25:1;;7900:2;7885:18;;7766:177;68669:44:0;;;;;;;;67920:801;;;;;;;67815:906;;;;:::o;66889:918::-;67004:15;67021:23;67046:12;67060:23;67085:12;67099:18;67119;67141:28;67152:7;67161;67141:10;:28::i;:::-;67003:166;;;;;;;;;;;;;;67209:7;67190;:15;67198:6;-1:-1:-1;;;;;67190:15:0;-1:-1:-1;;;;;67190:15:0;;;;;;;;;;;;;:26;;67182:59;;;;-1:-1:-1;;;67182:59:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;67277:15:0;;;;;;;:7;:15;;;;;;;;:26;;;;;;;67325:18;;;;;:7;:18;;;;;:37;;67347:15;;67277;67325:37;;67347:15;;67325:37;:::i;:::-;;;;;;;;67505:15;67493:8;;:27;;;;;;;:::i;:::-;;;;;;;;67543:15;67531:8;;:27;;;;;;;:::i;65114:811::-;65227:15;65244:23;65269:12;65283:23;65308:12;65322:18;65342;65364:28;65375:7;65384;65364:10;:28::i;:::-;65226:166;;;;;;;;;;;;;;65432:7;65413;:15;65421:6;-1:-1:-1;;;;;65413:15:0;-1:-1:-1;;;;;65413:15:0;;;;;;;;;;;;;:26;;65405:59;;;;-1:-1:-1;;;65405:59:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;65500:15:0;;;;;;;:7;:15;;;;;;:26;;;;;;;65548:18;;;;;;;;:37;;65570:15;;65500;65548:37;;65570:15;;65548:37;:::i;65937:940::-;66054:15;66071:23;66096:12;66110:23;66135:12;66149:18;66169;66191:28;66202:7;66211;66191:10;:28::i;:::-;66053:166;;;;;;;;;;;;;;66259:7;66240;:15;66248:6;-1:-1:-1;;;;;66240:15:0;-1:-1:-1;;;;;66240:15:0;;;;;;;;;;;;;:26;;66232:59;;;;-1:-1:-1;;;66232:59:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;66327:15:0;;;;;;;:7;:15;;;;;;:26;;;;;;;66375:18;;;;;;;;:37;;66397:15;;66327;66375:37;;66397:15;;66375:37;:::i;:::-;;;;-1:-1:-1;66552:25:0;;-1:-1:-1;66562:15:0;66552:7;:25;:::i;:::-;66539:8;;:39;;;;;;;:::i;:::-;;;;-1:-1:-1;66602:25:0;;-1:-1:-1;66612:15:0;66602:7;:25;:::i;:::-;66589:8;;:39;;;;;;;:::i;2377:1420::-;2443:4;2582:19;;;:12;;;:19;;;;;;2618:15;;2614:1176;;2993:21;3017:14;3030:1;3017:10;:14;:::i;:::-;3066:18;;2993:38;;-1:-1:-1;3046:17:0;;3066:22;;3087:1;;3066:22;:::i;:::-;3046:42;;3122:13;3109:9;:26;3105:405;;3156:17;3176:3;:11;;3188:9;3176:22;;;;;;;;:::i;:::-;;;;;;;;;3156:42;;3330:9;3301:3;:11;;3313:13;3301:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;3415:23;;;:12;;;:23;;;;;:36;;;3105:405;3591:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;3686:3;:12;;:19;3699:5;3686:19;;;;;;;;;;;3679:26;;;3729:4;3722:11;;;;;;;2614:1176;3773:5;3766:12;;;;;60488:286;60656:8;;60538:7;;;;60678:12;60675:54;;60700:16;;60718:10;;60692:37;;;;;60488:286;;:::o;60675:54::-;60748:8;;;60758:7;;-1:-1:-1;60488:286:0;-1:-1:-1;60488:286:0:o;61401:128::-;61465:7;61513;61502;;61492;:17;;;;:::i;:::-;:29;;;;:::i;61537:140::-;61607:7;61661;61644:13;;61634:7;:23;;;;:::i;60941:452::-;61063:4;61043:26;;;;:11;:26;;;;;;;;61040:285;;;61127:4;61111:22;;;;:7;:22;;;;;;:35;;61136:10;;61111:35;:::i;:::-;61102:4;61086:22;;;;:7;:22;;;;;:60;;;;61161:8;:22;;61173:10;;61086:22;61161;;61173:10;;61161:22;:::i;:::-;;;;;;;;61210:10;61198:8;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;61040:285:0;;-1:-1:-1;61040:285:0;;61294:4;61278:22;;;;:7;:22;;;;;;:35;;61303:10;;61278:35;:::i;:::-;61269:4;61253:22;;;;:7;:22;;;;;:60;61040:285;61342:43;;7912:25:1;;;61367:4:0;;-1:-1:-1;;;;;61342:43:0;;;-1:-1:-1;;;;;;;;;;;61342:43:0;7900:2:1;7885:18;61342:43:0;7766:177:1;60782:147:0;60875:4;60864:8;;:15;;;;:::i;:::-;60850:8;:29;60904:10;;:17;;60917:4;;60904:17;:::i;:::-;60890:10;:31;-1:-1:-1;;60782:147:0:o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:186::-;251:6;304:2;292:9;283:7;279:23;275:32;272:52;;;320:1;317;310:12;272:52;343:29;362:9;343:29;:::i;383:260::-;451:6;459;512:2;500:9;491:7;487:23;483:32;480:52;;;528:1;525;518:12;480:52;551:29;570:9;551:29;:::i;:::-;541:39;;599:38;633:2;622:9;618:18;599:38;:::i;:::-;589:48;;383:260;;;;;:::o;648:328::-;725:6;733;741;794:2;782:9;773:7;769:23;765:32;762:52;;;810:1;807;800:12;762:52;833:29;852:9;833:29;:::i;:::-;823:39;;881:38;915:2;904:9;900:18;881:38;:::i;:::-;871:48;;966:2;955:9;951:18;938:32;928:42;;648:328;;;;;:::o;981:693::-;1092:6;1100;1108;1116;1124;1132;1140;1193:3;1181:9;1172:7;1168:23;1164:33;1161:53;;;1210:1;1207;1200:12;1161:53;1233:29;1252:9;1233:29;:::i;:::-;1223:39;;1281:38;1315:2;1304:9;1300:18;1281:38;:::i;:::-;1271:48;;1366:2;1355:9;1351:18;1338:32;1328:42;;1417:2;1406:9;1402:18;1389:32;1379:42;;1471:3;1460:9;1456:19;1443:33;1516:4;1509:5;1505:16;1498:5;1495:27;1485:55;;1536:1;1533;1526:12;1485:55;981:693;;;;-1:-1:-1;981:693:1;;;;1559:5;1611:3;1596:19;;1583:33;;-1:-1:-1;1663:3:1;1648:19;;;1635:33;;981:693;-1:-1:-1;;981:693:1:o;1679:315::-;1744:6;1752;1805:2;1793:9;1784:7;1780:23;1776:32;1773:52;;;1821:1;1818;1811:12;1773:52;1844:29;1863:9;1844:29;:::i;:::-;1834:39;;1923:2;1912:9;1908:18;1895:32;1936:28;1958:5;1936:28;:::i;:::-;1983:5;1973:15;;;1679:315;;;;;:::o;1999:254::-;2067:6;2075;2128:2;2116:9;2107:7;2103:23;2099:32;2096:52;;;2144:1;2141;2134:12;2096:52;2167:29;2186:9;2167:29;:::i;:::-;2157:39;2243:2;2228:18;;;;2215:32;;-1:-1:-1;;;1999:254:1:o;2258:328::-;2335:6;2343;2351;2404:2;2392:9;2383:7;2379:23;2375:32;2372:52;;;2420:1;2417;2410:12;2372:52;2443:29;2462:9;2443:29;:::i;:::-;2433:39;;2519:2;2508:9;2504:18;2491:32;2481:42;;2542:38;2576:2;2565:9;2561:18;2542:38;:::i;:::-;2532:48;;2258:328;;;;;:::o;2591:241::-;2647:6;2700:2;2688:9;2679:7;2675:23;2671:32;2668:52;;;2716:1;2713;2706:12;2668:52;2755:9;2742:23;2774:28;2796:5;2774:28;:::i;2837:245::-;2904:6;2957:2;2945:9;2936:7;2932:23;2928:32;2925:52;;;2973:1;2970;2963:12;2925:52;3005:9;2999:16;3024:28;3046:5;3024:28;:::i;3087:180::-;3146:6;3199:2;3187:9;3178:7;3174:23;3170:32;3167:52;;;3215:1;3212;3205:12;3167:52;-1:-1:-1;3238:23:1;;3087:180;-1:-1:-1;3087:180:1:o;3272:254::-;3340:6;3348;3401:2;3389:9;3380:7;3376:23;3372:32;3369:52;;;3417:1;3414;3407:12;3369:52;3453:9;3440:23;3430:33;;3482:38;3516:2;3505:9;3501:18;3482:38;:::i;3531:322::-;3608:6;3616;3624;3677:2;3665:9;3656:7;3652:23;3648:32;3645:52;;;3693:1;3690;3683:12;3645:52;3729:9;3716:23;3706:33;;3758:38;3792:2;3781:9;3777:18;3758:38;:::i;3858:248::-;3926:6;3934;3987:2;3975:9;3966:7;3962:23;3958:32;3955:52;;;4003:1;4000;3993:12;3955:52;-1:-1:-1;;4026:23:1;;;4096:2;4081:18;;;4068:32;;-1:-1:-1;3858:248:1:o;4111:286::-;4169:6;4222:2;4210:9;4201:7;4197:23;4193:32;4190:52;;;4238:1;4235;4228:12;4190:52;4264:23;;-1:-1:-1;;;;;;4316:32:1;;4306:43;;4296:71;;4363:1;4360;4353:12;4846:309;4911:6;4919;4972:2;4960:9;4951:7;4947:23;4943:32;4940:52;;;4988:1;4985;4978:12;4940:52;5024:9;5011:23;5001:33;;5084:2;5073:9;5069:18;5056:32;5097:28;5119:5;5097:28;:::i;6007:786::-;6418:25;6413:3;6406:38;6388:3;6473:6;6467:13;6489:62;6544:6;6539:2;6534:3;6530:12;6523:4;6515:6;6511:17;6489:62;:::i;:::-;-1:-1:-1;;;6610:2:1;6570:16;;;6602:11;;;6595:40;6660:13;;6682:63;6660:13;6731:2;6723:11;;6716:4;6704:17;;6682:63;:::i;:::-;6765:17;6784:2;6761:26;;6007:786;-1:-1:-1;;;;6007:786:1:o;8947:383::-;9096:2;9085:9;9078:21;9059:4;9128:6;9122:13;9171:6;9166:2;9155:9;9151:18;9144:34;9187:66;9246:6;9241:2;9230:9;9226:18;9221:2;9213:6;9209:15;9187:66;:::i;:::-;9314:2;9293:15;-1:-1:-1;;9289:29:1;9274:45;;;;9321:2;9270:54;;8947:383;-1:-1:-1;;8947:383:1:o;11730:408::-;11932:2;11914:21;;;11971:2;11951:18;;;11944:30;12010:34;12005:2;11990:18;;11983:62;-1:-1:-1;;;12076:2:1;12061:18;;12054:42;12128:3;12113:19;;11730:408::o;14731:404::-;14933:2;14915:21;;;14972:2;14952:18;;;14945:30;15011:34;15006:2;14991:18;;14984:62;-1:-1:-1;;;15077:2:1;15062:18;;15055:38;15125:3;15110:19;;14731:404::o;16575:344::-;16777:2;16759:21;;;16816:2;16796:18;;;16789:30;-1:-1:-1;;;16850:2:1;16835:18;;16828:50;16910:2;16895:18;;16575:344::o;18091:413::-;18293:2;18275:21;;;18332:2;18312:18;;;18305:30;18371:34;18366:2;18351:18;;18344:62;-1:-1:-1;;;18437:2:1;18422:18;;18415:47;18494:3;18479:19;;18091:413::o;21424:128::-;21464:3;21495:1;21491:6;21488:1;21485:13;21482:39;;;21501:18;;:::i;:::-;-1:-1:-1;21537:9:1;;21424:128::o;21557:217::-;21597:1;21623;21613:132;;21667:10;21662:3;21658:20;21655:1;21648:31;21702:4;21699:1;21692:15;21730:4;21727:1;21720:15;21613:132;-1:-1:-1;21759:9:1;;21557:217::o;21779:422::-;21868:1;21911:5;21868:1;21925:270;21946:7;21936:8;21933:21;21925:270;;;22005:4;22001:1;21997:6;21993:17;21987:4;21984:27;21981:53;;;22014:18;;:::i;:::-;22064:7;22054:8;22050:22;22047:55;;;22084:16;;;;22047:55;22163:22;;;;22123:15;;;;21925:270;;;21929:3;21779:422;;;;;:::o;22206:140::-;22264:5;22293:47;22334:4;22324:8;22320:19;22314:4;22400:5;22430:8;22420:80;;-1:-1:-1;22471:1:1;22485:5;;22420:80;22519:4;22509:76;;-1:-1:-1;22556:1:1;22570:5;;22509:76;22601:4;22619:1;22614:59;;;;22687:1;22682:130;;;;22594:218;;22614:59;22644:1;22635:10;;22658:5;;;22682:130;22719:3;22709:8;22706:17;22703:43;;;22726:18;;:::i;:::-;-1:-1:-1;;22782:1:1;22768:16;;22797:5;;22594:218;;22896:2;22886:8;22883:16;22877:3;22871:4;22868:13;22864:36;22858:2;22848:8;22845:16;22840:2;22834:4;22831:12;22827:35;22824:77;22821:159;;;-1:-1:-1;22933:19:1;;;22965:5;;22821:159;23012:34;23037:8;23031:4;23012:34;:::i;:::-;23082:6;23078:1;23074:6;23070:19;23061:7;23058:32;23055:58;;;23093:18;;:::i;:::-;23131:20;;22351:806;-1:-1:-1;;;22351:806:1:o;23162:168::-;23202:7;23268:1;23264;23260:6;23256:14;23253:1;23250:21;23245:1;23238:9;23231:17;23227:45;23224:71;;;23275:18;;:::i;:::-;-1:-1:-1;23315:9:1;;23162:168::o;23335:125::-;23375:4;23403:1;23400;23397:8;23394:34;;;23408:18;;:::i;:::-;-1:-1:-1;23445:9:1;;23335:125::o;23465:258::-;23537:1;23547:113;23561:6;23558:1;23555:13;23547:113;;;23637:11;;;23631:18;23618:11;;;23611:39;23583:2;23576:10;23547:113;;;23678:6;23675:1;23672:13;23669:48;;;23713:1;23704:6;23699:3;23695:16;23688:27;23669:48;;23465:258;;;:::o;23728:136::-;23767:3;23795:5;23785:39;;23804:18;;:::i;:::-;-1:-1:-1;;;23840:18:1;;23728:136::o;23869:135::-;23908:3;-1:-1:-1;;23929:17:1;;23926:43;;;23949:18;;:::i;:::-;-1:-1:-1;23996:1:1;23985:13;;23869:135::o;24009:127::-;24070:10;24065:3;24061:20;24058:1;24051:31;24101:4;24098:1;24091:15;24125:4;24122:1;24115:15;24141:127;24202:10;24197:3;24193:20;24190:1;24183:31;24233:4;24230:1;24223:15;24257:4;24254:1;24247:15;24273:127;24334:10;24329:3;24325:20;24322:1;24315:31;24365:4;24362:1;24355:15;24389:4;24386:1;24379:15;24405:127;24466:10;24461:3;24457:20;24454:1;24447:31;24497:4;24494:1;24487:15;24521:4;24518:1;24511:15;24537:118;24623:5;24616:13;24609:21;24602:5;24599:32;24589:60;;24645:1;24642;24635:12

Swarm Source

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