contract Ownable {
        address internal _owner;
        address internal _newOwner;

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


        /**
         * @dev Initializes the contract setting the deployer as the initial owner.
         */
        constructor () internal {
            _owner = msg.sender;
            emit OwnershipTransferred(address(0), _owner);
        }

        /**
         * @dev Returns the addresses of the current and new owner.
         */
        function owner() public view returns (address currentOwner, address newOwner) {
            currentOwner = _owner;
            newOwner = _newOwner;
        }

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

        /**
         * @dev Returns true if the caller is the current owner.
         */
        function isOwner(address account) public view returns (bool) {
            return account == _owner;
        }

        /**
         * @dev Transfers ownership of the contract to a new account (`newOwner`).
         *
         * IMPORTANT: Need to run {acceptOwnership} by the new owner.
         */
        function _transferOwnership(address newOwner) internal {
            require(newOwner != address(0), "Ownable: new owner is the zero address");

            emit OwnershipTransferred(_owner, newOwner);
            _newOwner = newOwner;
        }

        /**
         * @dev Transfers ownership of the contract to a new account (`newOwner`).
         *
         * Can only be called by the current owner.
         */
        function transferOwnership(address newOwner) public onlyOwner {
            _transferOwnership(newOwner);
        }

        /**
         * @dev Accept ownership of the contract.
         *
         * Can only be called by the new owner.
         */
        function acceptOwnership() public {
            require(msg.sender == _newOwner, "Ownable: caller is not the new owner address");
            require(msg.sender != address(0), "Ownable: caller is the zero address");

            emit OwnershipAccepted(_owner, msg.sender);
            _owner = msg.sender;
            _newOwner = address(0);
        }

        /**
         * @dev Rescue compatible ERC20 Token
         *
         * Can only be called by the current owner.
         */
        function rescueTokens(address tokenAddr, address recipient, uint256 amount) external onlyOwner {
            IERC20 _token = IERC20(tokenAddr);
            require(recipient != address(0), "Rescue: recipient is the zero address");
            uint256 balance = _token.balanceOf(address(this));

            require(balance >= amount, "Rescue: amount exceeds balance");
            _token.transfer(recipient, amount);
        }

        /**
         * @dev Withdraw Ether
         *
         * Can only be called by the current owner.
         */
        function withdrawEther(address payable recipient, uint256 amount) external onlyOwner {
            require(recipient != address(0), "Withdraw: recipient is the zero address");

            uint256 balance = address(this).balance;

            require(balance >= amount, "Withdraw: amount exceeds balance");
            recipient.transfer(amount);
        }
    }
/**
 * @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.
 */
function acceptOwnership() public {
    require(msg.sender == _newOwner, "Ownable: caller is not the new owner address");
    require(msg.sender != address(0), "Ownable: caller is the zero address");

    emit OwnershipAccepted(_owner, msg.sender);
    _owner = msg.sender;
    _newOwner = address(0);
}

/**
 * @dev Accept ownership of the contract.
 *
 * Can only be called by the new owner.
 */