ETH Price: $3,475.26 (+0.75%)
Gas: 6 Gwei

Token

MarshelleInu (ELLE)
 

Overview

Max Total Supply

1,000,000,000 ELLE

Holders

107

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
0 ELLE

Value
$0.00
0x79ced82968abe262be509cf5bd4b42bfd7f02919
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
MarshelleInu

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

//SPDX-License-Identifier: MIT

// File: contracts/MarshelleErrors.sol


pragma solidity ^0.8.17;

error InvalidSwapTokenAmount(
    string errorMsg
);
error InvalidMaxTradeAmount(
    string errorMsg
);
error InvalidMaxWalletAmount(
    string errorMsg
);
error InvalidTotalFees(
    string errorMsg
);
error InvalidAutomatedMarketMakerPair(
    address pair,
    string errorMsg
);
error TransferFromZeroAddress(
    address from,
    address to
);
error TransferError(string errorMsg);
error InvalidAntibot(string errorMsg);
error InvalidMultiBuy(string errorMsg);
error TradingNotActive(string errorMsg);
error MaxWalletExceeded(string errorMsg);
error MaxTransactionExceeded(string errorMsg);

// File: contracts/IterableMapping.sol

pragma solidity ^0.8.17;
library IterableMapping {
    // Iterable mapping from address to uint;
    struct Map {
        address[] keys;
        mapping(address => uint) values;
        mapping(address => uint) indexOf;
        mapping(address => bool) inserted;
    }
 
    function get(Map storage map, address key) internal view returns (uint) {
        return map.values[key];
    }
 
    function getIndexOfKey(Map storage map, address key) internal view returns (int) {
        if(!map.inserted[key]) {
            return -1;
        }
        return int(map.indexOf[key]);
    }
 
    function getKeyAtIndex(Map storage map, uint index) internal view returns (address) {
        return map.keys[index];
    }
 
 
 
    function size(Map storage map) internal view returns (uint) {
        return map.keys.length;
    }
 
    function set(Map storage map, address key, uint val) internal {
        if (map.inserted[key]) {
            map.values[key] = val;
        } else {
            map.inserted[key] = true;
            map.values[key] = val;
            map.indexOf[key] = map.keys.length;
            map.keys.push(key);
        }
    }
 
    function remove(Map storage map, address key) internal {
        if (!map.inserted[key]) {
            return;
        }
 
        delete map.inserted[key];
        delete map.values[key];
 
        uint index = map.indexOf[key];
        uint lastIndex = map.keys.length - 1;
        address lastKey = map.keys[lastIndex];
 
        map.indexOf[lastKey] = index;
        delete map.indexOf[key];
 
        map.keys[index] = lastKey;
        map.keys.pop();
    }
}
// File: contracts/IUniswapV2Factory.sol


pragma solidity ^0.8.17;

interface IUniswapV2Factory {
    
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);
 
    function feeTo() external view returns (address);

    function feeToSetter() external view returns (address);
 
    function getPair(address tokenA, address tokenB) external view returns (address pair);

    function allPairs(uint) external view returns (address pair);
    
    function allPairsLength() external view returns (uint);
 
    function createPair(address tokenA, address tokenB) external returns (address pair);
 
    function setFeeTo(address) external;
 
    function setFeeToSetter(address) external;
}
 



// File: contracts/IUniswapV2Pair.sol

pragma solidity ^0.8.17;


interface IUniswapV2Pair {
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
    event Transfer(address indexed from, address indexed to, uint256 value);

    function name() external pure returns (string memory);

    function symbol() external pure returns (string memory);

    function decimals() external pure returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function PERMIT_TYPEHASH() external pure returns (bytes32);

    function nonces(address owner) external view returns (uint256);

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    event Mint(address indexed sender, uint256 amount0, uint256 amount1);
    event Burn(
        address indexed sender,
        uint256 amount0,
        uint256 amount1,
        address indexed to
    );
    event Swap(
        address indexed sender,
        uint256 amount0In,
        uint256 amount1In,
        uint256 amount0Out,
        uint256 amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint256);

    function factory() external view returns (address);

    function token0() external view returns (address);

    function token1() external view returns (address);

    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast
        );

    function price0CumulativeLast() external view returns (uint256);

    function price1CumulativeLast() external view returns (uint256);

    function kLast() external view returns (uint256);

    function mint(address to) external returns (uint256 liquidity);

    function burn(address to)
        external
        returns (uint256 amount0, uint256 amount1);

    function swap(
        uint256 amount0Out,
        uint256 amount1Out,
        address to,
        bytes calldata data
    ) external;

    function skim(address to) external;

    function sync() external;

    function initialize(address, address) external;
}

////// src/IUniswapV2Router02.sol
/* pragma solidity 0.8.10; */
/* pragma experimental ABIEncoderV2; */

interface IUniswapV2Router02 {
    function factory() external pure returns (address);

    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    )
        external
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        );

    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable;

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;
}
// File: contracts/IDividendPayingTokenOptional.sol



pragma solidity ^0.8.7;


/// @title Dividend-Paying Token Optional Interface
/// @author Roger Wu (https://github.com/roger-wu)
/// @dev OPTIONAL functions for a dividend-paying token contract.
interface IDividendPayingTokenOptional {
  /// @notice View the amount of dividend in wei that an address can withdraw.
  /// @param _owner The address of a token holder.
  /// @return The amount of dividend in wei that `_owner` can withdraw.
  function withdrawableDividendOf(address _owner) external view returns(uint256);

  /// @notice View the amount of dividend in wei that an address has withdrawn.
  /// @param _owner The address of a token holder.
  /// @return The amount of dividend in wei that `_owner` has withdrawn.
  function withdrawnDividendOf(address _owner) external view returns(uint256);

  /// @notice View the amount of dividend in wei that an address has earned in total.
  /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner)
  /// @param _owner The address of a token holder.
  /// @return The amount of dividend in wei that `_owner` has earned in total.
  function accumulativeDividendOf(address _owner) external view returns(uint256);
}
// File: contracts/IDividendPayingToken.sol



pragma solidity ^0.8.7;


/// @title Dividend-Paying Token Interface
/// @dev An interface for a dividend-paying token contract.
interface IDividendPayingToken {
  /// @notice View the amount of dividend in wei that an address can withdraw.
  /// @param _owner The address of a token holder.
  /// @return The amount of dividend in wei that `_owner` can withdraw.
  function dividendOf(address _owner) external view returns(uint256);

  /// @notice Distributes ether to token holders as dividends.
  /// @dev SHOULD distribute the paid ether to token holders as dividends.
  ///  SHOULD NOT directly transfer ether to token holders in this function.
  ///  MUST emit a `DividendsDistributed` event when the amount of distributed ether is greater than 0.
  function distributeDividends() external payable;

  /// @notice Withdraws the ether distributed to the sender.
  /// @dev SHOULD transfer `dividendOf(msg.sender)` wei to `msg.sender`, and `dividendOf(msg.sender)` SHOULD be 0 after the transfer.
  ///  MUST emit a `DividendWithdrawn` event if the amount of ether transferred is greater than 0.
  function withdrawDividend() external;

  /// @dev This event MUST emit when ether is distributed to token holders.
  /// @param from The address which sends ether to this contract.
  /// @param weiAmount The amount of distributed ether in wei.
  event DividendsDistributed(
    address indexed from,
    uint256 weiAmount
  );

  /// @dev This event MUST emit when an address withdraws their dividend.
  /// @param to The address which withdraws ether from this contract.
  /// @param weiAmount The amount of withdrawn ether in wei.
  event DividendWithdrawn(
    address indexed to,
    uint256 weiAmount
  );
}
// File: contracts/SafeMathInt.sol

pragma solidity ^0.8.17;

library SafeMathInt {
  function mul(int256 a, int256 b) internal pure returns (int256) {
    // Prevent overflow when multiplying INT256_MIN with -1
    // https://github.com/RequestNetwork/requestNetwork/issues/43
    require(!(a == - 2**255 && b == -1) && !(b == - 2**255 && a == -1));
 
    int256 c = a * b;
    require((b == 0) || (c / b == a));
    return c;
  }
 
  function div(int256 a, int256 b) internal pure returns (int256) {
    // Prevent overflow when dividing INT256_MIN by -1
    // https://github.com/RequestNetwork/requestNetwork/issues/43
    require(!(a == - 2**255 && b == -1) && (b > 0));
 
    return a / b;
  }
 
  function sub(int256 a, int256 b) internal pure returns (int256) {
    require((b >= 0 && a - b <= a) || (b < 0 && a - b > a));
 
    return a - b;
  }
 
  function add(int256 a, int256 b) internal pure returns (int256) {
    int256 c = a + b;
    require((b >= 0 && c >= a) || (b < 0 && c < a));
    return c;
  }
 
  function toUint256Safe(int256 a) internal pure returns (uint256) {
    require(a >= 0);
    return uint256(a);
  }
}
// File: contracts/SafeMathUint.sol

pragma solidity ^0.8.17;

/**
 * @title SafeMathUint
 * @dev Math operations with safety checks that revert on error
 */
library SafeMathUint {
  function toInt256Safe(uint256 a) internal pure returns (int256) {
    int256 b = int256(a);
    require(b >= 0);
    return b;
  }
}
// File: @openzeppelin/contracts/utils/math/SafeMath.sol


// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: contracts/IUniswapV2Router.sol


pragma solidity ^0.8.17;

interface IUniswapV2Router {
    function factory() external pure returns (address);

    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    )
        external
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        );

    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable;

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;
}
// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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 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 `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, 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 `from` to `to` 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 from,
        address to,
        uint256 amount
    ) external returns (bool);
}

// File: @openzeppelin/contracts/interfaces/IERC20.sol


// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)

pragma solidity ^0.8.0;


// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;


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

// 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/token/ERC20/ERC20.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;




/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        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);
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

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


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

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

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

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

// File: contracts/DividendPayingToken.sol



pragma solidity ^0.8.17;








/// @title Dividend-Paying Token
/// @dev A mintable ERC20 token that allows anyone to pay and distribute ether
///  to token holders as dividends and allows token holders to withdraw their dividends.
///  Reference: the source code of PoWH3D: https://etherscan.io/address/0xB3775fB83F7D12A36E0475aBdD1FCA35c091efBe#code
contract DividendPayingToken is ERC20, IDividendPayingToken, IDividendPayingTokenOptional, Ownable {
  using SafeMath for uint256;
  using SafeMathUint for uint256;
  using SafeMathInt for int256;

  // With `magnitude`, we can properly distribute dividends even if the amount of received ether is small.
  // For more discussion about choosing the value of `magnitude`,
  //  see https://github.com/ethereum/EIPs/issues/1726#issuecomment-472352728
  uint256 constant internal magnitude = 2**128;

  uint256 internal magnifiedDividendPerShare;

  // About dividendCorrection:
  // If the token balance of a `_user` is never changed, the dividend of `_user` can be computed with:
  //   `dividendOf(_user) = dividendPerShare * balanceOf(_user)`.
  // When `balanceOf(_user)` is changed (via minting/burning/transferring tokens),
  //   `dividendOf(_user)` should not be changed,
  //   but the computed value of `dividendPerShare * balanceOf(_user)` is changed.
  // To keep the `dividendOf(_user)` unchanged, we add a correction term:
  //   `dividendOf(_user) = dividendPerShare * balanceOf(_user) + dividendCorrectionOf(_user)`,
  //   where `dividendCorrectionOf(_user)` is updated whenever `balanceOf(_user)` is changed:
  //   `dividendCorrectionOf(_user) = dividendPerShare * (old balanceOf(_user)) - (new balanceOf(_user))`.
  // So now `dividendOf(_user)` returns the same value before and after `balanceOf(_user)` is changed.
  mapping(address => int256) internal magnifiedDividendCorrections;
  mapping(address => uint256) internal withdrawnDividends;
  mapping(address => bool) internal _isAuth;

  address public dividendToken;

  uint256 public totalDividendsDistributed;

  constructor(string memory _name, string memory _symbol, address _dividendToken) ERC20(_name, _symbol) {
    dividendToken = _dividendToken;
    _isAuth[msg.sender] = true;
  }

  /// @dev Distributes dividends whenever ether is paid to this contract.
  receive() external payable {
    distributeDividends();
  }

  /// @notice Distributes ether to token holders as dividends.
  /// @dev It reverts if the total supply of tokens is 0.
  /// It emits the `DividendsDistributed` event if the amount of received ether is greater than 0.
  /// About undistributed ether:
  ///   In each distribution, there is a small amount of ether not distributed,
  ///     the magnified amount of which is
  ///     `(msg.value * magnitude) % totalSupply()`.
  ///   With a well-chosen `magnitude`, the amount of undistributed ether
  ///     (de-magnified) in a distribution can be less than 1 wei.
  ///   We can actually keep track of the undistributed ether in a distribution
  ///     and try to distribute it in the next distribution,
  ///     but keeping track of such data on-chain costs much more than
  ///     the saved ether, so we don't do that.
  function distributeDividends() public override payable {
    require(totalSupply() > 0);

    if (msg.value > 0) {
      magnifiedDividendPerShare = magnifiedDividendPerShare.add(
        (msg.value).mul(magnitude) / totalSupply()
      );
      emit DividendsDistributed(msg.sender, msg.value);

      totalDividendsDistributed = totalDividendsDistributed.add(msg.value);
    }
  }


  
  function distributeTokenDividends(uint256 amount) public onlyOwner {
    require(totalSupply() > 0);

    if (amount > 0) {
      magnifiedDividendPerShare = magnifiedDividendPerShare.add(
        (amount).mul(magnitude) / totalSupply()
      );
      emit DividendsDistributed(msg.sender, amount);

      totalDividendsDistributed = totalDividendsDistributed.add(amount);
    }
  }


  /// @notice Withdraws the ether distributed to the sender.
  /// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0.
  function withdrawDividend() public virtual override {
    _withdrawDividendOfUser(payable(msg.sender));
  }

  /// @notice Withdraws the ether distributed to the sender.
  /// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0.
  function _withdrawDividendOfUser(address payable user) internal returns (uint256) {
    uint256 _withdrawableDividend = withdrawableDividendOf(user);
    if (_withdrawableDividend > 0) {
      withdrawnDividends[user] = withdrawnDividends[user].add(_withdrawableDividend);
      emit DividendWithdrawn(user, _withdrawableDividend);
      (bool success,) = user.call{value: _withdrawableDividend, gas: 3000}("");

      if(!success) {
        withdrawnDividends[user] = withdrawnDividends[user].sub(_withdrawableDividend);
        return 0;
      }

      return _withdrawableDividend;
    }

    return 0;
  }


  /// @notice View the amount of dividend in wei that an address can withdraw.
  /// @param _owner The address of a token holder.
  /// @return The amount of dividend in wei that `_owner` can withdraw.
  function dividendOf(address _owner) public view override returns(uint256) {
    return withdrawableDividendOf(_owner);
  }

  /// @notice View the amount of dividend in wei that an address can withdraw.
  /// @param _owner The address of a token holder.
  /// @return The amount of dividend in wei that `_owner` can withdraw.
  function withdrawableDividendOf(address _owner) public view override returns(uint256) {
    return accumulativeDividendOf(_owner).sub(withdrawnDividends[_owner]);
  }

  /// @notice View the amount of dividend in wei that an address has withdrawn.
  /// @param _owner The address of a token holder.
  /// @return The amount of dividend in wei that `_owner` has withdrawn.
  function withdrawnDividendOf(address _owner) public view override returns(uint256) {
    return withdrawnDividends[_owner];
  }


  /// @notice View the amount of dividend in wei that an address has earned in total.
  /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner)
  /// = (magnifiedDividendPerShare * balanceOf(_owner) + magnifiedDividendCorrections[_owner]) / magnitude
  /// @param _owner The address of a token holder.
  /// @return The amount of dividend in wei that `_owner` has earned in total.
  function accumulativeDividendOf(address _owner) public view override returns(uint256) {
    return magnifiedDividendPerShare.mul(balanceOf(_owner)).toInt256Safe()
      .add(magnifiedDividendCorrections[_owner]).toUint256Safe() / magnitude;
  }


  /// @dev Set the address of the dividend token
  /// @param _dividendToken address of the dividend token being set
  function setDividendTokenAddress(address _dividendToken) external virtual onlyOwner{
      dividendToken = _dividendToken;
  }

    
  /// @dev Set Authorized accounts for calling external functionts
  /// @param account address of the account being authorized
  function setAuth(address account, bool status) external onlyOwner{
      _isAuth[account] = status;
  }

  /// @dev Internal function that transfer tokens from one address to another.
  /// Update magnifiedDividendCorrections to keep dividends unchanged.
  /// @param from The address to transfer from.
  /// @param to The address to transfer to.
  /// @param value The amount to be transferred.
  function _transfer(address from, address to, uint256 value) internal virtual override {
    require(false);

    int256 _magCorrection = magnifiedDividendPerShare.mul(value).toInt256Safe();
    magnifiedDividendCorrections[from] = magnifiedDividendCorrections[from].add(_magCorrection);
    magnifiedDividendCorrections[to] = magnifiedDividendCorrections[to].sub(_magCorrection);
  }

  /// @dev Internal function that mints tokens to an account.
  /// Update magnifiedDividendCorrections to keep dividends unchanged.
  /// @param account The account that will receive the created tokens.
  /// @param value The amount that will be created.
  function _mint(address account, uint256 value) internal override {
    super._mint(account, value);

    magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account]
      .sub( (magnifiedDividendPerShare.mul(value)).toInt256Safe() );
  }

  /// @dev Internal function that burns an amount of the token of a given account.
  /// Update magnifiedDividendCorrections to keep dividends unchanged.
  /// @param account The account whose tokens will be burnt.
  /// @param value The amount that will be burnt.
  function _burn(address account, uint256 value) internal override {
    super._burn(account, value);

    magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account]
      .add( (magnifiedDividendPerShare.mul(value)).toInt256Safe() );
  }

  function _setBalance(address account, uint256 newBalance) internal {
    uint256 currentBalance = balanceOf(account);

    if(newBalance > currentBalance) {
      uint256 mintAmount = newBalance.sub(currentBalance);
      _mint(account, mintAmount);
    } else if(newBalance < currentBalance) {
      uint256 burnAmount = currentBalance.sub(newBalance);
      _burn(account, burnAmount);
    }
  }
}
// File: contracts/MarshelleInuDividendTracker.sol

pragma solidity ^0.8.17;






contract MarshelleInuDividendTracker is DividendPayingToken {
    using SafeMath for uint256;
    using SafeMathInt for int256;
    using IterableMapping for IterableMapping.Map;
 
    IterableMapping.Map private tokenHoldersMap;
    uint256 public lastProcessedIndex;
 
    mapping (address => bool) public excludedFromDividends;
 
    mapping (address => uint256) public lastClaimTimes;
 
    uint256 public claimWait;
    uint256 public minimumTokenBalanceForDividends;

    

    event ExcludeFromDividends(address indexed account);
    event ClaimWaitUpdated(
        uint256 indexed newValue, 
        uint256 indexed oldValue
    );
 
    event Claim(
        address indexed account, 
        uint256 amount, 
        bool indexed automatic
    );
 
    constructor(address _dividentToken) DividendPayingToken("MarshelleInu_Tracker", "MarshelleInu_Tracker",_dividentToken) {
    	claimWait = 60;
        minimumTokenBalanceForDividends = 1_000_0 * (10**18);
    }
 
    function _transfer(address, address, uint256) pure internal override {
        require(false, "MarshelleInu_Tracker: No transfers allowed");
    }
 
    function withdrawDividend() pure public override {
        require(false, "MarshelleInu_Tracker: withdrawDividend disabled. Use the 'claim' function on the main MarshelleInu contract.");
    }
 
    function setDividendTokenAddress(address newToken) external override onlyOwner {
      dividendToken = newToken;
    }


    function updateMinimumTokenBalanceForDividends(uint256 _newMinimumBalance) external onlyOwner {
        require(_newMinimumBalance != minimumTokenBalanceForDividends, "New mimimum balance for dividend cannot be same as current minimum balance");
        minimumTokenBalanceForDividends = _newMinimumBalance * (10**9);
    }


 
    function excludeFromDividends(address account) external onlyOwner {
    	require(!excludedFromDividends[account],"Address already excluded from dividends");
    	excludedFromDividends[account] = true;
 
    	_setBalance(account, 0);
    	tokenHoldersMap.remove(account);
 
    	emit ExcludeFromDividends(account);
    }
    function includeInDividends(address account) external onlyOwner {
        excludedFromDividends[account] = false;
    }
 
    function updateClaimWait(uint256 newClaimWait) external onlyOwner {
        require(newClaimWait >= 3600 && newClaimWait <= 86400, "MarshelleInu_Tracker: claimWait must be updated to between 1 and 24 hours");
        require(newClaimWait != claimWait, "MarshelleInu_Tracker: Cannot update claimWait to same value");
        emit ClaimWaitUpdated(newClaimWait, claimWait);
        claimWait = newClaimWait;
    }
 
    function getLastProcessedIndex() external view returns(uint256) {
    	return lastProcessedIndex;
    }
 
    function getNumberOfTokenHolders() external view returns(uint256) {
        return tokenHoldersMap.keys.length;
    }
 
 
    function getAccount(address _account)
        public view returns (
            address account,
            int256 index,
            int256 iterationsUntilProcessed,
            uint256 withdrawableDividends,
            uint256 totalDividends,
            uint256 lastClaimTime,
            uint256 nextClaimTime,
            uint256 secondsUntilAutoClaimAvailable) {
        account = _account;
 
        index = tokenHoldersMap.getIndexOfKey(account);
 
        iterationsUntilProcessed = -1;
 
        if(index >= 0) {
            if(uint256(index) > lastProcessedIndex) {
                iterationsUntilProcessed = index.sub(int256(lastProcessedIndex));
            }
            else {
                uint256 processesUntilEndOfArray = tokenHoldersMap.keys.length > lastProcessedIndex ?
                                                        tokenHoldersMap.keys.length.sub(lastProcessedIndex) :
                                                        0;
 
 
                iterationsUntilProcessed = index.add(int256(processesUntilEndOfArray));
            }
        }
 
 
        withdrawableDividends = withdrawableDividendOf(account);
        totalDividends = accumulativeDividendOf(account);
 
        lastClaimTime = lastClaimTimes[account];
 
        nextClaimTime = lastClaimTime > 0 ?
                                    lastClaimTime.add(claimWait) :
                                    0;
 
        secondsUntilAutoClaimAvailable = nextClaimTime > block.timestamp ?
                                                    nextClaimTime.sub(block.timestamp) :
                                                    0;
    }
 
    function getAccountAtIndex(uint256 index)
        public view returns (
            address,
            int256,
            int256,
            uint256,
            uint256,
            uint256,
            uint256,
            uint256) {
    	if(index >= tokenHoldersMap.size()) {
            return (0x0000000000000000000000000000000000000000, -1, -1, 0, 0, 0, 0, 0);
        }
 
        address account = tokenHoldersMap.getKeyAtIndex(index);
 
        return getAccount(account);
    }
 
    function canAutoClaim(uint256 lastClaimTime) private view returns (bool) {
    	if(lastClaimTime > block.timestamp)  {
    		return false;
    	}
 
    	return block.timestamp.sub(lastClaimTime) >= claimWait;
    }
 
    function setBalance(
        address payable account, 
        uint256 newBalance
    ) external onlyOwner {
    	if(excludedFromDividends[account]) {
    		return;
    	}
 
    	if(newBalance >= minimumTokenBalanceForDividends) {
            _setBalance(account, newBalance);
    		tokenHoldersMap.set(account, newBalance);
    	}
    	else {
            _setBalance(account, 0);
    		tokenHoldersMap.remove(account);
    	}
 
    	processAccount(account, true);
    }
 
    function process(uint256 gas) public returns (uint256, uint256, uint256) {
    	uint256 numberOfTokenHolders = tokenHoldersMap.keys.length;
 
    	if(numberOfTokenHolders == 0) {
    		return (0, 0, lastProcessedIndex);
    	}
 
    	uint256 _lastProcessedIndex = lastProcessedIndex;
 
    	uint256 gasUsed = 0;
 
    	uint256 gasLeft = gasleft();
 
    	uint256 iterations = 0;
    	uint256 claims = 0;
 
    	while(gasUsed < gas && iterations < numberOfTokenHolders) {
    		_lastProcessedIndex++;
 
    		if(_lastProcessedIndex >= tokenHoldersMap.keys.length) {
    			_lastProcessedIndex = 0;
    		}
 
    		address account = tokenHoldersMap.keys[_lastProcessedIndex];
 
    		if(canAutoClaim(lastClaimTimes[account])) {
    			if(processAccount(payable(account), true)) {
    				claims++;
    			}
    		}
 
    		iterations++;
 
    		uint256 newGasLeft = gasleft();
 
    		if(gasLeft > newGasLeft) {
    			gasUsed = gasUsed.add(gasLeft.sub(newGasLeft));
    		}
 
    		gasLeft = newGasLeft;
    	}
 
    	lastProcessedIndex = _lastProcessedIndex;
 
    	return (iterations, claims, lastProcessedIndex);
    }
 
    function processAccount(
        address payable account, 
        bool automatic
    ) public onlyOwner returns (bool) {

        uint256 amount = _withdrawDividendOfUser(account);
 
    	if(amount > 0) {
    		lastClaimTimes[account] = block.timestamp;
            emit Claim(account, amount, automatic);
    		return true;
    	}
 
    	return false;
    }
}

// File: contracts/MarshelleInu.sol


pragma solidity ^0.8.17;

/*****
 *   ,---.    ,---.   ____    .-------.       .-'''-. .---.  .---.     .-''-.    .---.     .---.       .-''-.          .-./`) ,---.   .--.  ___    _
 *   |    \  /    | .'  __ `. |  _ _   \     / _     \|   |  |_ _|   .'_ _   \   | ,_|     | ,_|     .'_ _   \         \ .-.')|    \  |  |.'   |  | |
 *   |  ,  \/  ,  |/   '  \  \| ( ' )  |    (`' )/`--'|   |  ( ' )  / ( ` )   ',-./  )   ,-./  )    / ( ` )   '        / `-' \|  ,  \ |  ||   .'  | |
 *   |  |\_   /|  ||___|  /  ||(_ o _) /   (_ o _).   |   '-(_{;}_). (_ o _)  |\  '_ '`) \  '_ '`) . (_ o _)  |         `-'`"`|  |\_ \|  |.'  '_  | |
 *   |  _( )_/ |  |   _.-`   || (_,_).' __  (_,_). '. |      (_,_) |  (_,_)___| > (_)  )  > (_)  ) |  (_,_)___|         .---. |  _( )_\  |'   ( \.-.|
 *   | (_ o _) |  |.'   _    ||  |\ \  |  |.---.  \  :| _ _--.   | '  \   .---.(  .  .-' (  .  .-' '  \   .---.         |   | | (_ o _)  |' (`. _` /|
 *   |  (_,_)  |  ||  _( )_  ||  | \ `'   /\    `-'  ||( ' ) |   |  \  `-'    / `-'`-'|___`-'`-'|___\  `-'    /         |   | |  (_,_)\  || (_ (_) _)
 *   |  |      |  |\ (_ o _) /|  |  \    /  \       / (_{;}_)|   |   \       /   |        \|        \\       /          |   | |  |    |  | \ /  . \ /
 *   '--'      '--' '.(_,_).' ''-'   `'-'    `-...-'  '(_,_) '---'    `'-..-'    `--------``--------` `'-..-'           '---' '--'    '--'  ``-'`-''
 *****/










contract MarshelleInu  is ERC20, Ownable {
    using SafeMath for uint256;

    IUniswapV2Router private uniswapV2Router;
    MarshelleInuDividendTracker public marshelleInuDividendTracker;
    
    address private uniswapV2Pair;
    address public constant deadAddress = address(0xdead);
    address public MRI = address(0x0913dDAE242839f8995c0375493f9a1A3Bddc977);
    address public marketingWallet = address(0x4EB85dA43eb3587E21294d4d5a6922892CF12658);
    address public devWallet = address(0x721a025a1dA21C22Cc811E3117053939D31047Ce);

    // boolean
    bool private isSwapping;
    bool swapAndLiquifyEnabled;
    bool public ProcessDividendStatus;
    // uint
    uint256 public _totalSupply;
    uint256 public maxBuyTxAmount;
    uint256 public maxSellTxAmount;
    uint256 public maxWalletAmount;
    uint256 public swapAndLiquifyThreshold;
    uint256 public tradingEnabledAt;

    uint256 private buyTotalFees;
    uint256 private buyMarketingFee;
    uint256 private buyDevFee;
    uint256 private buyLiquidityFee;
    uint256 private buyReflectionsFee;

    uint256 private sellTotalFees;
    uint256 private sellMarketingFee;
    uint256 private sellDevFee;
    uint256 private sellLiquidityFee;
    uint256 private sellReflectionsFee;


    uint256 private tokensForMarketing;
    uint256 private tokensForDev;
    uint256 private tokensForLiquidity;
    uint256 private tokensForReflections;

    uint256 public gasForProcessing = 300000;

    // mappings
    mapping(address => bool) public _isExcludedFromFees;
    mapping(address => bool) public _isExcludedFromMaxTrade;
    mapping(address => bool) public _isExcludedFromMaxWallet;
    mapping(address => bool) public automatedMarketMakerPairs;
  //  mapping(address => bool) public presaleAcc;


    event UpdateBuyFees(
        uint256 buyTotalFees,
        uint256 buyMarketingFee,
        uint256 buyDevFee,
        uint256 buyLiquidityFee,
        uint256 buyReflectionsFee
    );
    event UpdateSellFees(
        uint256 sellTotalFees,
        uint256 sellMarketingFee,
        uint256 sellDevFee,
        uint256 sellLiquidityFee,
        uint256 sellReflectionsFee
    );
    event UpdateUniswapV2Router(
        address indexed newRouter,
        address indexed oldRouter
    );
    event ExcludeFromFees(address indexed account, bool isExcluded);
    event ExcludeFromMaxTrade(address indexed account, bool isExcluded);
    event ExcludeFromMaxWallet(address indexed account, bool isExcluded);
    event SetAutomatedMarketMakerPair(
        address indexed pair,
        bool indexed status
    );
    event UpdateDevWallet(address indexed newWallet, address indexed oldWallet);
    event UpdateMarketingWallet(
        address indexed newWallet,
        address indexed oldWallet
    );
    event UpdateDividendToken(address indexed oldDividendToken, address indexed newDividendToken);
    event IncludeInDividends(address indexed wallet);
    event ExcludeFromDividends(address indexed wallet);
    event UpdateDividendTracker(
        address oldDividendTracker,
        address newDividendTracker
    );
    event UpdateDividendAddress(
        address oldDividendAddress,
        address newDividendAddress
    );
    event UpdateSwapAndLiquify(bool enabled);
    event UpadateDividendEnabled(bool enabled);
    event SwapAndLiquify(
        uint256 tokensSwapped,
        uint256 ethReceived,
        uint256 tokensIntoLiquidity
    );
    event SendDividends(uint256 tokensSwapped, uint256 amount);
    event ProcessedDividendTracker(
        uint256 iterations,
        uint256 claims,
        uint256 lastProcessedIndex,
        bool indexed automatic,
        uint256 gas,
        address indexed processor
    );

    constructor() ERC20("MarshelleInu", "ELLE") {
        IUniswapV2Router _uniswapV2Router = IUniswapV2Router(
            0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D  
        );

        uniswapV2Router = _uniswapV2Router;

        uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
            .createPair(address(this), _uniswapV2Router.WETH());

        _initializeVariables();

        /*
            _mint is an internal function in ERC20.sol that is only called here,
            and CANNOT be called ever again
        */
        _mint(msg.sender, _totalSupply);
    }

    receive() external payable {}

    // initialize state variables at deploy
    function _initializeVariables() private {
        _isExcludedFromFees[uniswapV2Pair] = true;

        _isExcludedFromMaxTrade[uniswapV2Pair] = true;
        _isExcludedFromMaxWallet[uniswapV2Pair] = true;
        automatedMarketMakerPairs[uniswapV2Pair] = true;

        // exclude from paying fees or having max transaction amount
        _isExcludedFromFees[owner()] = true;
        _isExcludedFromFees[address(this)] = true;
        _isExcludedFromFees[deadAddress] = true;

        _isExcludedFromMaxTrade[owner()] = true;
        _isExcludedFromMaxTrade[address(this)] = true;
        _isExcludedFromMaxTrade[deadAddress] = true;
        _isExcludedFromMaxWallet[owner()] = true;
     //   _isExcludedFromMaxWallet[address(Oxdead)] = true;
        _isExcludedFromMaxWallet[address(this)] = true;
        marshelleInuDividendTracker = new MarshelleInuDividendTracker(MRI);
        marshelleInuDividendTracker.setAuth(owner(), true);
//        _allowances[address(this)][address(uniswapV2Router)] = uint256(-1);
    //    _allowances[address(this)][address(router)] = uint256(-1);

        marshelleInuDividendTracker.excludeFromDividends(address(marshelleInuDividendTracker));
        marshelleInuDividendTracker.excludedFromDividends(address(this));
        marshelleInuDividendTracker.excludedFromDividends(address(uniswapV2Router));        
        marshelleInuDividendTracker.excludedFromDividends(deadAddress);
        marshelleInuDividendTracker.excludedFromDividends(owner());

 //       presaleAcc[owner()] = true;
        _totalSupply = 1_000_000_000 * 1e18;
        maxBuyTxAmount = 20_000_000 * 1e18; // 2% of total supply
        maxSellTxAmount = 10_000_000 * 1e18; // 1% of total supply
        maxWalletAmount = 20_000_000 * 1e18; // 2% of total supply
        swapAndLiquifyThreshold = (_totalSupply * 2) / 10000; // 0.02% contarct swap

        buyMarketingFee = 3;
        buyDevFee = 1;
        buyLiquidityFee = 2;
        buyReflectionsFee = 2;
        buyTotalFees =
            buyMarketingFee +
            buyDevFee +
            buyLiquidityFee +
            buyReflectionsFee;

        sellMarketingFee = 7;
        sellDevFee = 1;
        sellLiquidityFee = 2;
        sellReflectionsFee = 2;
        sellTotalFees =
            sellMarketingFee +
            sellDevFee +
            sellLiquidityFee +
            sellReflectionsFee;

        ProcessDividendStatus = true;
        marketingWallet = deadAddress;
        devWallet = deadAddress;
    }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal override {
        //tx utility vars
        //        uint256 trade_type = 0;

        bool overSwapThreshold = balanceOf(address(this)) >=
            swapAndLiquifyThreshold;


        if (!isSwapping) {
            // not a contract swap

            if (automatedMarketMakerPairs[from]) {
                //buy transaction

                if (!_isExcludedFromMaxTrade[to]) {
                    // tx limit
                    if (amount > maxBuyTxAmount)
                        revert TransferError("Exceeded max buy TxAmount");
                }

                if (!_isExcludedFromMaxWallet[to]) {
                    // wallet limit
                    if (balanceOf(to) + amount > maxWalletAmount)
                        revert TransferError("Exceeded max buy TxAmount");
                }

                // takeFees - buy
                if (buyTotalFees > 0 && !_isExcludedFromFees[to]) {
                    uint256 txFees = (amount * buyTotalFees) / 100;
                    amount -= txFees;
                    tokensForMarketing +=
                        (txFees * buyMarketingFee) /
                        buyTotalFees;
                    tokensForDev += (txFees * buyDevFee) / buyTotalFees;
                    tokensForLiquidity +=
                        (txFees * buyLiquidityFee) /
                        buyTotalFees;
                    tokensForReflections +=
                        (txFees * buyReflectionsFee) /
                        buyTotalFees;
                    super._transfer(from, address(this), txFees);
                }
            } else if (automatedMarketMakerPairs[to]) {
                //sell transaction
                if (
                    swapAndLiquifyEnabled &&
                    sellTotalFees > 0 &&
                    overSwapThreshold
                ) swapBack();   

                if (!_isExcludedFromMaxTrade[from]) {
                    if (amount > maxSellTxAmount)
                        revert TransferError("Exceeded max sell TxAmount");
                }
                // check whether to sell from the contract
                
            // takefees - sell
            if (sellTotalFees > 0 && !_isExcludedFromFees[from]) {
                uint256 txFees = (amount * sellTotalFees) / 100;
                amount -= txFees;
                tokensForMarketing +=
                    (txFees * sellMarketingFee) /
                    sellTotalFees;
                tokensForDev += (txFees * sellDevFee) / sellTotalFees;
                tokensForLiquidity +=
                    (txFees * sellLiquidityFee) /
                    sellTotalFees;
                tokensForReflections +=
                    (txFees * sellReflectionsFee) /
                    sellTotalFees;

                super._transfer(from, address(this), txFees);
            }
        }
        }

        // transfer tokens erc20 standard
        super._transfer(from, to, amount);

        //set dividends
        try
            marshelleInuDividendTracker.setBalance(payable(from), balanceOf(from))
        {} catch {}
        try
            marshelleInuDividendTracker.setBalance(payable(to), balanceOf(to))
        {} catch {}
        // auto-claims one time per transaction
        if (!isSwapping && ProcessDividendStatus) {
            uint256 gas = gasForProcessing;

            try marshelleInuDividendTracker.process(gas) returns (
                uint256 iterations,
                uint256 claims,
                uint256 lastProcessedIndex
            ) {
                emit ProcessedDividendTracker(
                    iterations,
                    claims,
                    lastProcessedIndex,
                    true,
                    gas,
                    tx.origin
                );
            } catch {}
        }
    }


    function swapTokensForETH(uint256 tokenAmount) private {
        // generate the uniswap pair path of token -> weth
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = uniswapV2Router.WETH();

        _approve(address(this), address(uniswapV2Router), tokenAmount);

        // make the swap
        uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            0, // accept any amount of ETH
            path,
            address(this),
            block.timestamp
        );
    }

    function addLiquidity(uint256 tokenAmount, uint256 ethAmount) private {
        // approve token transfer to cover all possible scenarios
        _approve(address(this), address(uniswapV2Router), tokenAmount);

        // add the liquidity
        uniswapV2Router.addLiquidityETH{value: ethAmount}(
            address(this),
            tokenAmount,
            0, // slippage is unavoidable
            0, // slippage is unavoidable
            deadAddress,
            block.timestamp
        );
    }

    function swapETHForMRI(uint256 ethAmount) private {

        if(ethAmount > 0){
            address[] memory path = new address[](2);
            path[0] = uniswapV2Router.WETH();
            path[1] = MRI;
            
            uniswapV2Router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: ethAmount}(
                0,
                path,
                address(this),
                block.timestamp
            );
        }
    }

    function swapBack() private {
        isSwapping = true; 
        uint256 contractBalance = balanceOf(address(this));

        uint256 totalTokens = tokensForDev +
            tokensForMarketing +
            tokensForLiquidity +
            tokensForReflections;
            
        bool success;
        uint256 swapBalance;
        if (contractBalance == 0 || totalTokens == 0) {
            return;
        }

        if(totalTokens > swapAndLiquifyThreshold){
            // never swap more than the threshold
            swapBalance = swapAndLiquifyThreshold;
        } else{
            swapBalance = totalTokens;
        }
        
        // Halve the amount of liquidity tokens

        uint256 liquidityTokens = (swapBalance * tokensForLiquidity) /
            totalTokens /
            2;
        uint256 amountToSwapForETH = swapBalance - liquidityTokens;

        uint256 initialETHBalance = address(this).balance;

        swapTokensForETH(amountToSwapForETH);

        uint256 ethBalance = address(this).balance - initialETHBalance;

        uint256 ethForDev = (ethBalance * tokensForDev) / totalTokens;

        uint256 ethForLiquidity = (ethBalance * tokensForLiquidity) /
            totalTokens;

        uint256 ethForReflections = (ethBalance * tokensForReflections) /
            totalTokens;

        (success, ) = address(devWallet).call{value: ethForDev}("");

        if (liquidityTokens > 0 && ethForLiquidity > 0) {
            addLiquidity(liquidityTokens, ethForLiquidity);
            emit SwapAndLiquify(
                amountToSwapForETH,
                ethForLiquidity,
                tokensForLiquidity
            );
        }

        swapETHForMRI(ethForReflections);

        uint256 tokenBalance = IERC20(MRI).balanceOf(address(this));
        success = IERC20(MRI).transfer(
            address(marshelleInuDividendTracker),
            tokenBalance
        );

        if (success) {
            marshelleInuDividendTracker.distributeTokenDividends(tokenBalance);
            emit SendDividends(tokenBalance, ethForReflections);
        }

        (success, ) = address(marketingWallet).call{
            value: address(this).balance
        }("");

        contractBalance = balanceOf(address(this));

        tokensForLiquidity =
            (contractBalance * sellLiquidityFee) /
            sellTotalFees;
        tokensForMarketing =
            (contractBalance * sellMarketingFee) /
            sellTotalFees;
        tokensForDev = (contractBalance * sellDevFee) / sellTotalFees;
        tokensForReflections =
            (contractBalance * sellReflectionsFee) /
            sellTotalFees;

        isSwapping = false;
    }    

    function manualSwapBack() external onlyOwner{
        if(balanceOf(address(this)) > 0 )
            swapBack();       
    }
    

    function claim() external {
        marshelleInuDividendTracker.processAccount(payable(msg.sender), false);
    }

    /////////////////////////////////////////////////////////////////////////////////////
    ///// Setter functions
    /////////////////////////////////////////////////////////////////////////////////////



    /**
     * @dev Change the threshold for making the contract sell and adding liquidity
     * @param newThreshold : new
     */
    function updateSwapTokensAtAmount(uint256 newThreshold)
        external
        onlyOwner
        returns (bool)
    {
        if (newThreshold < (totalSupply() * 1) / 100000)
            revert InvalidSwapTokenAmount(
                "Swap amount cannot be lower than 0.001% total supply."
            );
    if (newThreshold > (totalSupply() * 1) / 1000)
            revert InvalidSwapTokenAmount(
                "Swap amount cannot be higher than 0.1% total supply."
            );
        swapAndLiquifyThreshold = newThreshold;
        return true;
    }

    function updateMaxTxnAmount(uint256 newMaxBuy, uint256 newMaxSell)
        external
        onlyOwner
    {
        if (newMaxBuy < ((totalSupply() * 5) / 1000) / 1e18)
            revert InvalidMaxTradeAmount(
                "Cannot set max buy lower than 0.5%"
            );
        if (newMaxSell < ((totalSupply() * 5) / 1000) / 1e18)
            revert InvalidMaxTradeAmount(
                "Cannot set max sell lower than 0.5%"
            );

        maxBuyTxAmount = newMaxBuy * (10**18);
        maxSellTxAmount = newMaxSell * (10**18);
    }

    function updateMaxWalletAmount(uint256 newMaxWallet) external onlyOwner {
        if (newMaxWallet < ((totalSupply() * 5) / 1000) / 1e18)
            revert InvalidMaxWalletAmount(
                "Cannot set maxWallet lower than 0.5%"
            );
        maxWalletAmount = newMaxWallet * (10**18);
    }

    function excludeFromMaxWallet(address account, bool isExcluded)
        external
        onlyOwner
    {
        _isExcludedFromMaxWallet[account] = isExcluded;
        emit ExcludeFromMaxWallet(account, isExcluded);
    }

    function excludeFromMaxTrade(address account, bool isExcluded)
        external
        onlyOwner
    {
        _isExcludedFromMaxTrade[account] = isExcluded;
        emit ExcludeFromMaxTrade(account, isExcluded);
    }

    function excludeFromFees(address account, bool isExcluded)
        external
        onlyOwner
    {
        _isExcludedFromFees[account] = isExcluded;
        emit ExcludeFromFees(account, isExcluded);
    }

    function setAutomatedMarketMakerPair(address pair, bool status)
        external
        onlyOwner
    {
        automatedMarketMakerPairs[pair] = status;
        emit SetAutomatedMarketMakerPair(pair, status);
    }

    function updateBuyFees(
        uint256 _buyMarketingFee,
        uint256 _buyDevFee,
        uint256 _buyLiquidityFee,
        uint256 _buyReflectionsFee
    ) external onlyOwner {
        buyMarketingFee = _buyMarketingFee;
        buyDevFee = _buyDevFee;
        buyLiquidityFee = _buyLiquidityFee;
        buyReflectionsFee = _buyReflectionsFee;
        buyTotalFees = 
            buyMarketingFee +
            buyDevFee +
            buyLiquidityFee +
            buyReflectionsFee;
        if (sellTotalFees + buyTotalFees > 25)
            revert InvalidTotalFees("Total Fees must be less than 25%");
        emit UpdateBuyFees(
            buyTotalFees,
            buyMarketingFee,
            buyDevFee,
            buyLiquidityFee,
            buyReflectionsFee
        );
    }

    function updateSellFees(
        uint256 _sellMarketingFee,
        uint256 _sellDevFee,
        uint256 _sellLiquidityFee,
        uint256 _sellReflectionsFee
    ) external onlyOwner {
        sellMarketingFee = _sellMarketingFee;
        sellDevFee = _sellDevFee;
        sellLiquidityFee = _sellLiquidityFee;
        sellReflectionsFee = _sellReflectionsFee;
        sellTotalFees =
            sellMarketingFee +
            sellDevFee +
            sellLiquidityFee +
            sellReflectionsFee;
        if (sellTotalFees + buyTotalFees > 25)
            revert InvalidTotalFees("Total Fees must be less than 25%");
        emit UpdateSellFees(
            sellTotalFees,
            sellMarketingFee,
            sellDevFee,
            sellLiquidityFee,
            sellReflectionsFee
        );
    }

    function setDevWallet (address payable _devWallet) external onlyOwner{
        address oldAddress = devWallet;
        devWallet = _devWallet;
        emit UpdateDevWallet(oldAddress, _devWallet);
    }

    function setMarketingWallet(address payable _marketingWallet) external onlyOwner{
        address oldAddress = marketingWallet;
        marketingWallet = _marketingWallet;
        emit UpdateMarketingWallet(oldAddress, _marketingWallet);
    }


    function setSwapAndLiquifyEnabled(
        bool _status
        ) external onlyOwner {
        
        swapAndLiquifyEnabled = _status;
    }

    /////////////////////////////////////////////////////////////////////////////////////
    //// dividend setters
    /////////////////////////////////////////////////////////////////////////////////////

    function processDividendTracker(uint256 gas) external {
        (
            uint256 iterations,
            uint256 claims,
            uint256 lastProcessedIndex
        ) = marshelleInuDividendTracker.process(gas);
        emit ProcessedDividendTracker(
            iterations,
            claims,
            lastProcessedIndex,
            false,
            gas,
            tx.origin
        );
    }

    function updateDividendAddress(address newDividendAddress)
        external
        onlyOwner
    {
        address oldAddress = MRI;
        MRI = newDividendAddress;
        marshelleInuDividendTracker.setDividendTokenAddress(newDividendAddress);
        emit UpdateDividendToken(oldAddress, MRI);
    }

    function updateDividendInclusion(address account, bool isIncluded) external onlyOwner {
        if(isIncluded){
            marshelleInuDividendTracker.includeInDividends(account);
            emit IncludeInDividends(account);
        } else{
            marshelleInuDividendTracker.excludeFromDividends(account);
            emit ExcludeFromDividends(account);
        }
    }

    /////////////////////////////////////////////////////////////////////////////////////
    ///// Getter functions
    /////////////////////////////////////////////////////////////////////////////////////

    function getLastProcessedIndex() external view returns (uint256) {
        return marshelleInuDividendTracker.getLastProcessedIndex();
    }

    function getNumberOfMarshelleDividendTokenHolders()
        external
        view
        returns (uint256)
    {
        return marshelleInuDividendTracker.getNumberOfTokenHolders();
    }

    function getNumberOfMarshelleDividends() external view returns (uint256) {
        return marshelleInuDividendTracker.totalSupply();
    }

    function getClaimWait() external view returns (uint256) {
        return marshelleInuDividendTracker.claimWait();
    }

    function getTotalMarshelleDividendsDistributed()
        external
        view
        returns (uint256)
    {
        return marshelleInuDividendTracker.totalDividendsDistributed();
    }

    function withdrawableMarshelleDividendOf(address account)
        public
        view
        returns (uint256)
    {
        return marshelleInuDividendTracker.withdrawableDividendOf(account);
    }

    function marshelleInuDividendTokenBalanceOf(address account)
        public
        view
        returns (uint256)
    {
        return marshelleInuDividendTracker.balanceOf(account);
    }

    function getAccountMarshelleDividendsInfo(address account)
        external
        view
        returns (
            address,
            int256,
            int256,
            uint256,
            uint256,
            uint256,
            uint256,
            uint256
        )
    {
        return marshelleInuDividendTracker.getAccount(account);
    }

    function getAccountMarshelleDividendsInfoAtIndex(uint256 index)
        external
        view
        returns (
            address,
            int256,
            int256,
            uint256,
            uint256,
            uint256,
            uint256,
            uint256
        )
    {
        return marshelleInuDividendTracker.getAccountAtIndex(index);
    }

    function getBuyFees()
        external
        view
        returns (
            uint256 _buyMarketingFee,
            uint256 _buyDevFee,
            uint256 _buyLiquidityFee,
            uint256 _buyReflectionsFee
        )
    {
        return (buyMarketingFee, 
                buyDevFee, 
                buyLiquidityFee, 
                buyReflectionsFee);
    }

    function getSellFees()
        external
        view
        returns (
            uint256 _sellMarketingFee,
            uint256 _sellDevFee,
            uint256 _sellLiquidityFee,
            uint256 _sellReflectionFee
        )
    {
        return (
            sellMarketingFee,
            sellDevFee,
            sellLiquidityFee,
            sellReflectionsFee
        );
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"string","name":"errorMsg","type":"string"}],"name":"InvalidMaxTradeAmount","type":"error"},{"inputs":[{"internalType":"string","name":"errorMsg","type":"string"}],"name":"InvalidMaxWalletAmount","type":"error"},{"inputs":[{"internalType":"string","name":"errorMsg","type":"string"}],"name":"InvalidSwapTokenAmount","type":"error"},{"inputs":[{"internalType":"string","name":"errorMsg","type":"string"}],"name":"InvalidTotalFees","type":"error"},{"inputs":[{"internalType":"string","name":"errorMsg","type":"string"}],"name":"TransferError","type":"error"},{"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":true,"internalType":"address","name":"wallet","type":"address"}],"name":"ExcludeFromDividends","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"ExcludeFromFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"ExcludeFromMaxTrade","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"ExcludeFromMaxWallet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"}],"name":"IncludeInDividends","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":false,"internalType":"uint256","name":"iterations","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"claims","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastProcessedIndex","type":"uint256"},{"indexed":true,"internalType":"bool","name":"automatic","type":"bool"},{"indexed":false,"internalType":"uint256","name":"gas","type":"uint256"},{"indexed":true,"internalType":"address","name":"processor","type":"address"}],"name":"ProcessedDividendTracker","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokensSwapped","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SendDividends","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pair","type":"address"},{"indexed":true,"internalType":"bool","name":"status","type":"bool"}],"name":"SetAutomatedMarketMakerPair","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":"tokensIntoLiquidity","type":"uint256"}],"name":"SwapAndLiquify","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":"bool","name":"enabled","type":"bool"}],"name":"UpadateDividendEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"buyTotalFees","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"buyMarketingFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"buyDevFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"buyLiquidityFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"buyReflectionsFee","type":"uint256"}],"name":"UpdateBuyFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newWallet","type":"address"},{"indexed":true,"internalType":"address","name":"oldWallet","type":"address"}],"name":"UpdateDevWallet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldDividendAddress","type":"address"},{"indexed":false,"internalType":"address","name":"newDividendAddress","type":"address"}],"name":"UpdateDividendAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldDividendToken","type":"address"},{"indexed":true,"internalType":"address","name":"newDividendToken","type":"address"}],"name":"UpdateDividendToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldDividendTracker","type":"address"},{"indexed":false,"internalType":"address","name":"newDividendTracker","type":"address"}],"name":"UpdateDividendTracker","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newWallet","type":"address"},{"indexed":true,"internalType":"address","name":"oldWallet","type":"address"}],"name":"UpdateMarketingWallet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"sellTotalFees","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sellMarketingFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sellDevFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sellLiquidityFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sellReflectionsFee","type":"uint256"}],"name":"UpdateSellFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"UpdateSwapAndLiquify","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newRouter","type":"address"},{"indexed":true,"internalType":"address","name":"oldRouter","type":"address"}],"name":"UpdateUniswapV2Router","type":"event"},{"inputs":[],"name":"MRI","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ProcessDividendStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_isExcludedFromFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_isExcludedFromMaxTrade","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_isExcludedFromMaxWallet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_totalSupply","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":"","type":"address"}],"name":"automatedMarketMakerPairs","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deadAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","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":[],"name":"devWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"excludeFromFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"excludeFromMaxTrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"excludeFromMaxWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gasForProcessing","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getAccountMarshelleDividendsInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"int256","name":"","type":"int256"},{"internalType":"int256","name":"","type":"int256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getAccountMarshelleDividendsInfoAtIndex","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"int256","name":"","type":"int256"},{"internalType":"int256","name":"","type":"int256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBuyFees","outputs":[{"internalType":"uint256","name":"_buyMarketingFee","type":"uint256"},{"internalType":"uint256","name":"_buyDevFee","type":"uint256"},{"internalType":"uint256","name":"_buyLiquidityFee","type":"uint256"},{"internalType":"uint256","name":"_buyReflectionsFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getClaimWait","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastProcessedIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumberOfMarshelleDividendTokenHolders","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumberOfMarshelleDividends","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSellFees","outputs":[{"internalType":"uint256","name":"_sellMarketingFee","type":"uint256"},{"internalType":"uint256","name":"_sellDevFee","type":"uint256"},{"internalType":"uint256","name":"_sellLiquidityFee","type":"uint256"},{"internalType":"uint256","name":"_sellReflectionFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalMarshelleDividendsDistributed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[],"name":"manualSwapBack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"marketingWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"marshelleInuDividendTokenBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marshelleInuDividendTracker","outputs":[{"internalType":"contract MarshelleInuDividendTracker","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxBuyTxAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSellTxAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWalletAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"gas","type":"uint256"}],"name":"processDividendTracker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"bool","name":"status","type":"bool"}],"name":"setAutomatedMarketMakerPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_devWallet","type":"address"}],"name":"setDevWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_marketingWallet","type":"address"}],"name":"setMarketingWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_status","type":"bool"}],"name":"setSwapAndLiquifyEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapAndLiquifyThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradingEnabledAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","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":"uint256","name":"_buyMarketingFee","type":"uint256"},{"internalType":"uint256","name":"_buyDevFee","type":"uint256"},{"internalType":"uint256","name":"_buyLiquidityFee","type":"uint256"},{"internalType":"uint256","name":"_buyReflectionsFee","type":"uint256"}],"name":"updateBuyFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDividendAddress","type":"address"}],"name":"updateDividendAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"isIncluded","type":"bool"}],"name":"updateDividendInclusion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxBuy","type":"uint256"},{"internalType":"uint256","name":"newMaxSell","type":"uint256"}],"name":"updateMaxTxnAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxWallet","type":"uint256"}],"name":"updateMaxWalletAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sellMarketingFee","type":"uint256"},{"internalType":"uint256","name":"_sellDevFee","type":"uint256"},{"internalType":"uint256","name":"_sellLiquidityFee","type":"uint256"},{"internalType":"uint256","name":"_sellReflectionsFee","type":"uint256"}],"name":"updateSellFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newThreshold","type":"uint256"}],"name":"updateSwapTokensAtAmount","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"withdrawableMarshelleDividendOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

6080604052600980546001600160a01b0319908116730913ddae242839f8995c0375493f9a1a3bddc97717909155600a80548216734eb85da43eb3587e21294d4d5a6922892cf12658179055600b805490911673721a025a1da21c22cc811e3117053939d31047ce179055620493e06020553480156200007e57600080fd5b506040518060400160405280600c81526020016b4d61727368656c6c65496e7560a01b81525060405180604001604052806004815260200163454c4c4560e01b8152508160039081620000d2919062000a1a565b506004620000e1828262000a1a565b505050620000fe620000f8620002b760201b60201c565b620002bb565b600680546001600160a01b031916737a250d5630b4cf539739df2c5dacb4c659f2488d9081179091556040805163c45a015560e01b81529051829163c45a01559160048083019260209291908290030181865afa15801562000164573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200018a919062000ae6565b6001600160a01b031663c9c6539630836001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001d8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001fe919062000ae6565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af11580156200024c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000272919062000ae6565b600880546001600160a01b0319166001600160a01b03929092169190911790556200029c6200030d565b620002b033600c546200087b60201b60201c565b5062000bab565b3390565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600880546001600160a01b0390811660009081526021602081815260408084208054600160ff1991821681179092558754871686526022808552838720805483168417905588548816875260238086528488208054841685179055985488168752602485528387208054831684179055600580548916885295855283872080548316841790553080885284882080548416851790557fda90364631e387f138e7e413f1de75a8ecb4767574209ddf012729113dea45c08054841685179055865489168852908552838720805483168417905580875283872080548316841790557fb3dad1d3e53c1132e958712e36d3ff32b0d9b9088698eb172c6b4faa7ff6d22e80548316841790559454871686529690925280842080548716831790559183529181902080549094169091179092556009549151911690620004509062000968565b6001600160a01b039091168152602001604051809103906000f0801580156200047d573d6000803e3d6000fd5b50600780546001600160a01b0319166001600160a01b03929092169182179055630b44a218620004b56005546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260016024820152604401600060405180830381600087803b158015620004fe57600080fd5b505af115801562000513573d6000803e3d6000fd5b505060075460405163031e79db60e41b81526001600160a01b039091166004820181905292506331e79db09150602401600060405180830381600087803b1580156200055e57600080fd5b505af115801562000573573d6000803e3d6000fd5b5050600754604051634e7b827f60e01b81523060048201526001600160a01b039091169250634e7b827f9150602401602060405180830381865afa158015620005c0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005e6919062000b18565b50600754600654604051634e7b827f60e01b81526001600160a01b039182166004820152911690634e7b827f90602401602060405180830381865afa15801562000634573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200065a919062000b18565b50600754604051634e7b827f60e01b815261dead60048201526001600160a01b0390911690634e7b827f90602401602060405180830381865afa158015620006a6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620006cc919062000b18565b506007546001600160a01b0316634e7b827f620006f16005546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801562000736573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200075c919062000b18565b506b033b2e3c9fd0803ce8000000600c8190556a108b2a2c28029094000000600d8190556a084595161401484a000000600e55600f5561271090620007a390600262000b52565b620007af919062000b72565b6010556003601381905560016014819055600260158190556016819055918291620007da9162000b95565b620007e6919062000b95565b620007f2919062000b95565b60125560076018819055600160198190556002601a819055601b8190559182916200081d9162000b95565b62000829919062000b95565b62000835919062000b95565b601755600b8054600a80546001600160a01b03191661dead17905576010000000000000000000000000000000000000000dead600162ff000160a01b0319909116179055565b6001600160a01b038216620008d65760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640160405180910390fd5b8060026000828254620008ea919062000b95565b90915550506001600160a01b038216600090815260208190526040812080548392906200091990849062000b95565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b505050565b61240a8062003dd183390190565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620009a157607f821691505b602082108103620009c257634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200096357600081815260208120601f850160051c81016020861015620009f15750805b601f850160051c820191505b8181101562000a1257828155600101620009fd565b505050505050565b81516001600160401b0381111562000a365762000a3662000976565b62000a4e8162000a4784546200098c565b84620009c8565b602080601f83116001811462000a86576000841562000a6d5750858301515b600019600386901b1c1916600185901b17855562000a12565b600085815260208120601f198616915b8281101562000ab75788860151825594840194600190910190840162000a96565b508582101562000ad65787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006020828403121562000af957600080fd5b81516001600160a01b038116811462000b1157600080fd5b9392505050565b60006020828403121562000b2b57600080fd5b8151801515811462000b1157600080fd5b634e487b7160e01b600052601160045260246000fd5b808202811582820484141762000b6c5762000b6c62000b3c565b92915050565b60008262000b9057634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111562000b6c5762000b6c62000b3c565b6132168062000bbb6000396000f3fe6080604052600436106103905760003560e01c806395d89b41116101dc578063c2d84c4e11610102578063d851fd0d116100a0578063e7ad9fcd1161006f578063e7ad9fcd14610a8b578063ec7a661714610aab578063f2fde38b14610adb578063f3bc974014610afb57600080fd5b8063d851fd0d14610a10578063dd62ed3e14610a26578063e0bf7fd114610a46578063e7841ec014610a7657600080fd5b8063c646c019116100dc578063c646c01914610980578063d1d7d7ef146109a0578063d257b34f146109d0578063d2fcc001146109f057600080fd5b8063c2d84c4e1461092a578063c31fe80a1461094a578063c49b9a801461096057600080fd5b8063a87e5da41161017a578063ae51d9f511610149578063ae51d9f5146108a5578063b62496f5146108ba578063c0246668146108ea578063c18bc1951461090a57600080fd5b8063a87e5da414610839578063a9059cbb1461084f578063aa4bde281461086f578063ae146e851461088557600080fd5b80639c1b8af5116101b65780639c1b8af5146107ce578063a26579ad146107e4578063a457c2d7146107f9578063a511a1a51461081957600080fd5b806395d89b4114610778578063969097991461078d5780639a7a23d6146107ae57600080fd5b80633eaaf86b116102c1578063685fc5681161025f57806375f0a8741161022e57806375f0a874146107055780638886ecfb146107255780638da5cb5b1461073a5780638ea5220f1461075857600080fd5b8063685fc56814610692578063700bb191146106b057806370a08231146106d0578063715018a6146106f057600080fd5b80634e71d92d1161029b5780634e71d92d14610628578063515eb2841461063d5780635d098b381461065d57806366eb37851461067d57600080fd5b80633eaaf86b146105dd57806344b4a75b146105f35780634b1f17c31461061357600080fd5b806323b872dd1161032e578063313ce56711610308578063313ce5671461056157806339086b9b1461057d578063395093511461059d5780633e92088b146105bd57600080fd5b806323b872dd146104f357806327c8f835146105135780632e6ed7ef1461054157600080fd5b8063095ea7b31161036a578063095ea7b31461046257806311a582c31461049257806318160ddd146104b45780631f53ac02146104d357600080fd5b80630644e7571461039c57806306fdde03146103db57806307f149b4146103fd57600080fd5b3661039757005b600080fd5b3480156103a857600080fd5b506013546014546015546016545b6040805194855260208501939093529183015260608201526080015b60405180910390f35b3480156103e757600080fd5b506103f0610b11565b6040516103d29190612d88565b34801561040957600080fd5b5061041d610418366004612deb565b610ba3565b604080516001600160a01b0390991689526020890197909752958701949094526060860192909252608085015260a084015260c083015260e0820152610100016103d2565b34801561046e57600080fd5b5061048261047d366004612e0f565b610c3e565b60405190151581526020016103d2565b34801561049e57600080fd5b506104b26104ad366004612e3b565b610c58565b005b3480156104c057600080fd5b506002545b6040519081526020016103d2565b3480156104df57600080fd5b506104b26104ee366004612deb565b610db2565b3480156104ff57600080fd5b5061048261050e366004612e5d565b610e0c565b34801561051f57600080fd5b5061052961dead81565b6040516001600160a01b0390911681526020016103d2565b34801561054d57600080fd5b506104b261055c366004612e9e565b610e30565b34801561056d57600080fd5b50604051601281526020016103d2565b34801561058957600080fd5b506104b2610598366004612deb565b610f32565b3480156105a957600080fd5b506104826105b8366004612e0f565b610ff3565b3480156105c957600080fd5b50600954610529906001600160a01b031681565b3480156105e957600080fd5b506104c5600c5481565b3480156105ff57600080fd5b506104c561060e366004612deb565b611015565b34801561061f57600080fd5b506104c5611085565b34801561063457600080fd5b506104b26110f8565b34801561064957600080fd5b5061041d610658366004612ed0565b611170565b34801561066957600080fd5b506104b2610678366004612deb565b6111b2565b34801561068957600080fd5b506104b261120c565b34801561069e57600080fd5b50601854601954601a54601b546103b6565b3480156106bc57600080fd5b506104b26106cb366004612ed0565b61122f565b3480156106dc57600080fd5b506104c56106eb366004612deb565b611301565b3480156106fc57600080fd5b506104b261131c565b34801561071157600080fd5b50600a54610529906001600160a01b031681565b34801561073157600080fd5b506104c561132e565b34801561074657600080fd5b506005546001600160a01b0316610529565b34801561076457600080fd5b50600b54610529906001600160a01b031681565b34801561078457600080fd5b506103f0611378565b34801561079957600080fd5b50600b5461048290600160b01b900460ff1681565b3480156107ba57600080fd5b506104b26107c9366004612ef7565b611387565b3480156107da57600080fd5b506104c560205481565b3480156107f057600080fd5b506104c56113e3565b34801561080557600080fd5b50610482610814366004612e0f565b61142d565b34801561082557600080fd5b506104b2610834366004612ef7565b6114a8565b34801561084557600080fd5b506104c5600d5481565b34801561085b57600080fd5b5061048261086a366004612e0f565b6115e4565b34801561087b57600080fd5b506104c5600f5481565b34801561089157600080fd5b50600754610529906001600160a01b031681565b3480156108b157600080fd5b506104c56115f2565b3480156108c657600080fd5b506104826108d5366004612deb565b60246020526000908152604090205460ff1681565b3480156108f657600080fd5b506104b2610905366004612ef7565b61163c565b34801561091657600080fd5b506104b2610925366004612ed0565b6116a4565b34801561093657600080fd5b506104c5610945366004612deb565b611754565b34801561095657600080fd5b506104c560115481565b34801561096c57600080fd5b506104b261097b366004612f30565b611787565b34801561098c57600080fd5b506104b261099b366004612ef7565b6117ad565b3480156109ac57600080fd5b506104826109bb366004612deb565b60236020526000908152604090205460ff1681565b3480156109dc57600080fd5b506104826109eb366004612ed0565b61180d565b3480156109fc57600080fd5b506104b2610a0b366004612ef7565b61193e565b348015610a1c57600080fd5b506104c5600e5481565b348015610a3257600080fd5b506104c5610a41366004612f4d565b61199e565b348015610a5257600080fd5b50610482610a61366004612deb565b60216020526000908152604090205460ff1681565b348015610a8257600080fd5b506104c56119c9565b348015610a9757600080fd5b506104b2610aa6366004612e9e565b611a13565b348015610ab757600080fd5b50610482610ac6366004612deb565b60226020526000908152604090205460ff1681565b348015610ae757600080fd5b506104b2610af6366004612deb565b611b0c565b348015610b0757600080fd5b506104c560105481565b606060038054610b2090612f7b565b80601f0160208091040260200160405190810160405280929190818152602001828054610b4c90612f7b565b8015610b995780601f10610b6e57610100808354040283529160200191610b99565b820191906000526020600020905b815481529060010190602001808311610b7c57829003601f168201915b5050505050905090565b60075460405163fbcbc0f160e01b81526001600160a01b038381166004830152600092839283928392839283928392839291169063fbcbc0f1906024015b61010060405180830381865afa158015610bff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c239190612fb5565b97509750975097509750975097509750919395975091939597565b600033610c4c818585611b82565b60019150505b92915050565b610c60611ca6565b670de0b6b3a76400006103e8610c7560025490565b610c80906005613035565b610c8a919061304c565b610c94919061304c565b821015610cf45760405163d0179c8560e01b815260206004820152602260248201527f43616e6e6f7420736574206d617820627579206c6f776572207468616e20302e604482015261352560f01b60648201526084015b60405180910390fd5b670de0b6b3a76400006103e8610d0960025490565b610d14906005613035565b610d1e919061304c565b610d28919061304c565b811015610d845760405163d0179c8560e01b815260206004820152602360248201527f43616e6e6f7420736574206d61782073656c6c206c6f776572207468616e20306044820152622e352560e81b6064820152608401610ceb565b610d9682670de0b6b3a7640000613035565b600d55610dab81670de0b6b3a7640000613035565b600e555050565b610dba611ca6565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f923334f00a08147112838c5c41f68a92979493ae7af34177449883db5743427790600090a35050565b600033610e1a858285611d00565b610e25858585611d7a565b506001949350505050565b610e38611ca6565b60138490556014839055601582905560168190558082610e58858761306e565b610e62919061306e565b610e6c919061306e565b6012819055601754601991610e809161306e565b1115610ecf57604051637f20723d60e01b815260206004820181905260248201527f546f74616c2046656573206d757374206265206c657373207468616e203235256044820152606401610ceb565b60125460135460145460155460165460408051958652602086019490945292840191909152606083015260808201527f36f734ef6334bb46ffb96a53ac28a5f80f907b4e1edb3c8af6dd32ba6e57f8589060a0015b60405180910390a150505050565b610f3a611ca6565b600980546001600160a01b038381166001600160a01b031983168117909355600754604051633f1f3fe960e11b8152600481019490945291811692911690637e3e7fd290602401600060405180830381600087803b158015610f9b57600080fd5b505af1158015610faf573d6000803e3d6000fd5b50506009546040516001600160a01b03918216935090841691507fc50953975bfb7dc05da466bc18236bf737c11097c9cc7ef9d079bc7ed96f03ae90600090a35050565b600033610c4c818585611006838361199e565b611010919061306e565b611b82565b6007546040516370a0823160e01b81526001600160a01b03838116600483015260009216906370a08231906024015b602060405180830381865afa158015611061573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c529190613081565b600754604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa1580156110cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f39190613081565b905090565b60075460405163bc4c4b3760e01b8152336004820152600060248201526001600160a01b039091169063bc4c4b37906044016020604051808303816000875af1158015611149573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116d919061309a565b50565b600754604051635183d6fd60e01b81526004810183905260009182918291829182918291829182916001600160a01b0390911690635183d6fd90602401610be1565b6111ba611ca6565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907facf03c50dcf01e53e2775267d12acd0158d87c2f20fb84226837142693b36ae790600090a35050565b611214611ca6565b600061121f30611301565b111561122d5761122d6123af565b565b6007546040516001624d3b8760e01b0319815260048101839052600091829182916001600160a01b03169063ffb2c479906024016060604051808303816000875af1158015611282573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a691906130b7565b604080518481526020810184905290810182905260608101889052929550909350915032906000907fc864333d6121033635ab41b29ae52f10a22cf4438c3e4f1c4c68518feb2f8a989060800160405180910390a350505050565b6001600160a01b031660009081526020819052604090205490565b611324611ca6565b61122d600061280f565b600754604080516304ddf6ef60e11b815290516000926001600160a01b0316916309bbedde9160048083019260209291908290030181865afa1580156110cf573d6000803e3d6000fd5b606060048054610b2090612f7b565b61138f611ca6565b6001600160a01b038216600081815260246020526040808220805460ff191685151590811790915590519092917fffa9187bf1f18bf477bd0ea1bcbb64e93b6a98132473929edfce215cd9b16fab91a35050565b60075460408051631bc9e27b60e21b815290516000926001600160a01b031691636f2789ec9160048083019260209291908290030181865afa1580156110cf573d6000803e3d6000fd5b6000338161143b828661199e565b90508381101561149b5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610ceb565b610e258286868403611b82565b6114b0611ca6565b801561154d5760075460405163c0f306ef60e01b81526001600160a01b0384811660048301529091169063c0f306ef90602401600060405180830381600087803b1580156114fd57600080fd5b505af1158015611511573d6000803e3d6000fd5b50506040516001600160a01b03851692507f40a78dcf8526b72f2eaf598af1c7e49c8d5fc577f6c8f1bed887f3e4dfa289329150600090a25050565b60075460405163031e79db60e41b81526001600160a01b038481166004830152909116906331e79db090602401600060405180830381600087803b15801561159457600080fd5b505af11580156115a8573d6000803e3d6000fd5b50506040516001600160a01b03851692507fa878b31040b2e6d0a9a3d3361209db3908ba62014b0dca52adbaee451d128b259150600090a25050565b600033610c4c818585611d7a565b600754604080516342d359d760e11b815290516000926001600160a01b0316916385a6b3ae9160048083019260209291908290030181865afa1580156110cf573d6000803e3d6000fd5b611644611ca6565b6001600160a01b038216600081815260216020908152604091829020805460ff191685151590811790915591519182527f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df791015b60405180910390a25050565b6116ac611ca6565b670de0b6b3a76400006103e86116c160025490565b6116cc906005613035565b6116d6919061304c565b6116e0919061304c565b81101561173c57604051634d8a090560e01b8152602060048201526024808201527f43616e6e6f7420736574206d617857616c6c6574206c6f776572207468616e20604482015263302e352560e01b6064820152608401610ceb565b61174e81670de0b6b3a7640000613035565b600f5550565b6007546040516302a2e74960e61b81526001600160a01b038381166004830152600092169063a8b9d24090602401611044565b61178f611ca6565b600b8054911515600160a81b0260ff60a81b19909216919091179055565b6117b5611ca6565b6001600160a01b038216600081815260226020908152604091829020805460ff191685151590811790915591519182527fbbba3cea579dbad4552c9ff73eabdce62821f125571c096df83e2116e438567c9101611698565b6000611817611ca6565b620186a061182460025490565b61182f906001613035565b611839919061304c565b8210156118a75760405163dcd85d8f60e01b815260206004820152603560248201527f5377617020616d6f756e742063616e6e6f74206265206c6f776572207468616e60448201527410181718181892903a37ba30b61039bab838363c9760591b6064820152608401610ceb565b6103e86118b360025490565b6118be906001613035565b6118c8919061304c565b8211156119355760405163dcd85d8f60e01b815260206004820152603460248201527f5377617020616d6f756e742063616e6e6f742062652068696768657220746861604482015273371018171892903a37ba30b61039bab838363c9760611b6064820152608401610ceb565b50601055600190565b611946611ca6565b6001600160a01b038216600081815260236020908152604091829020805460ff191685151590811790915591519182527f4a8452f723db48bf05f301f94d62a2cf7a72976cde77d83e3646584858b8f4b29101611698565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6007546040805163039e107b60e61b815290516000926001600160a01b03169163e7841ec09160048083019260209291908290030181865afa1580156110cf573d6000803e3d6000fd5b611a1b611ca6565b60188490556019839055601a829055601b8190558082611a3b858761306e565b611a45919061306e565b611a4f919061306e565b6017819055601254601991611a64919061306e565b1115611ab357604051637f20723d60e01b815260206004820181905260248201527f546f74616c2046656573206d757374206265206c657373207468616e203235256044820152606401610ceb565b601754601854601954601a54601b5460408051958652602086019490945292840191909152606083015260808201527fa047973ee053932e622d31fe5ab89f310d1c9c947ac06a81f382d0d3df2b11029060a001610f24565b611b14611ca6565b6001600160a01b038116611b795760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ceb565b61116d8161280f565b6001600160a01b038316611be45760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610ceb565b6001600160a01b038216611c455760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610ceb565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6005546001600160a01b0316331461122d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ceb565b6000611d0c848461199e565b90506000198114611d745781811015611d675760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610ceb565b611d748484848403611b82565b50505050565b6000601054611d8830611301565b600b549111159150600160a01b900460ff166121cc576001600160a01b03841660009081526024602052604090205460ff1615611fde576001600160a01b03831660009081526022602052604090205460ff16611e2e57600d54821115611e2e57604051631e30f57d60e31b8152602060048201526019602482015278115e18d959591959081b585e08189d5e48151e105b5bdd5b9d603a1b6044820152606401610ceb565b6001600160a01b03831660009081526023602052604090205460ff16611eb057600f5482611e5b85611301565b611e65919061306e565b1115611eb057604051631e30f57d60e31b8152602060048201526019602482015278115e18d959591959081b585e08189d5e48151e105b5bdd5b9d603a1b6044820152606401610ceb565b6000601254118015611edb57506001600160a01b03831660009081526021602052604090205460ff16155b15611fd9576000606460125484611ef29190613035565b611efc919061304c565b9050611f0881846130e5565b925060125460135482611f1b9190613035565b611f25919061304c565b601c6000828254611f36919061306e565b9091555050601254601454611f4b9083613035565b611f55919061304c565b601d6000828254611f66919061306e565b9091555050601254601554611f7b9083613035565b611f85919061304c565b601e6000828254611f96919061306e565b9091555050601254601654611fab9083613035565b611fb5919061304c565b601f6000828254611fc6919061306e565b90915550611fd79050853083612861565b505b6121cc565b6001600160a01b03831660009081526024602052604090205460ff16156121cc57600b54600160a81b900460ff16801561201a57506000601754115b80156120235750805b15612030576120306123af565b6001600160a01b03841660009081526022602052604090205460ff166120a357600e548211156120a357604051631e30f57d60e31b815260206004820152601a60248201527f4578636565646564206d61782073656c6c205478416d6f756e740000000000006044820152606401610ceb565b60006017541180156120ce57506001600160a01b03841660009081526021602052604090205460ff16155b156121cc5760006064601754846120e59190613035565b6120ef919061304c565b90506120fb81846130e5565b92506017546018548261210e9190613035565b612118919061304c565b601c6000828254612129919061306e565b909155505060175460195461213e9083613035565b612148919061304c565b601d6000828254612159919061306e565b9091555050601754601a5461216e9083613035565b612178919061304c565b601e6000828254612189919061306e565b9091555050601754601b5461219e9083613035565b6121a8919061304c565b601f60008282546121b9919061306e565b909155506121ca9050853083612861565b505b6121d7848484612861565b6007546001600160a01b031663e30443bc856121f281611301565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561223857600080fd5b505af1925050508015612249575060015b506007546001600160a01b031663e30443bc8461226581611301565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156122ab57600080fd5b505af19250505080156122bc575060015b50600b54600160a01b900460ff161580156122e05750600b54600160b01b900460ff165b15611d74576020546007546040516001624d3b8760e01b03198152600481018390526001600160a01b039091169063ffb2c479906024016060604051808303816000875af1925050508015612352575060408051601f3d908101601f1916820190925261234f918101906130b7565b60015b156123a85760408051848152602081018490529081018290526060810185905232906001907fc864333d6121033635ab41b29ae52f10a22cf4438c3e4f1c4c68518feb2f8a989060800160405180910390a35050505b5050505050565b600b805460ff60a01b1916600160a01b17905560006123cd30611301565b90506000601f54601e54601c54601d546123e7919061306e565b6123f1919061306e565b6123fb919061306e565b905060008083158061240b575082155b156124165750505050565b601054831115612429575060105461242c565b50815b6000600284601e548461243f9190613035565b612449919061304c565b612453919061304c565b9050600061246182846130e5565b90504761246d82612a2f565b600061247982476130e5565b9050600087601d548361248c9190613035565b612496919061304c565b9050600088601e54846124a99190613035565b6124b3919061304c565b9050600089601f54856124c69190613035565b6124d0919061304c565b600b546040519192506001600160a01b0316908490600081818185875af1925050503d806000811461251e576040519150601f19603f3d011682016040523d82523d6000602084013e612523565b606091505b509099505086158015906125375750600082115b1561258a576125468783612b89565b601e54604080518881526020810185905280820192909252517f17bbfb9a6069321b6ded73bd96327c9e6b7212a5cd51ff219cd61370acafb5619181900360600190a15b61259381612c34565b6009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156125dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126009190613081565b60095460075460405163a9059cbb60e01b81526001600160a01b03918216600482015260248101849052929350169063a9059cbb906044016020604051808303816000875af1158015612657573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061267b919061309a565b9950891561271c5760075460405163b0c7ce3760e01b8152600481018390526001600160a01b039091169063b0c7ce3790602401600060405180830381600087803b1580156126c957600080fd5b505af11580156126dd573d6000803e3d6000fd5b505060408051848152602081018690527f80195cc573b02cc48460cbca6e6e4cc85ddb91959d946e1c3025ea3d87942dc3935001905060405180910390a15b600a546040516001600160a01b03909116904790600081818185875af1925050503d8060008114612769576040519150601f19603f3d011682016040523d82523d6000602084013e61276e565b606091505b5050809a505061277d30611301565b9b50601754601a548d6127909190613035565b61279a919061304c565b601e556017546018546127ad908e613035565b6127b7919061304c565b601c556017546019546127ca908e613035565b6127d4919061304c565b601d55601754601b546127e7908e613035565b6127f1919061304c565b601f555050600b805460ff60a01b1916905550505050505050505050565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0383166128c55760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610ceb565b6001600160a01b0382166129275760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610ceb565b6001600160a01b0383166000908152602081905260409020548181101561299f5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610ceb565b6001600160a01b038085166000908152602081905260408082208585039055918516815290812080548492906129d690849061306e565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612a2291815260200190565b60405180910390a3611d74565b6040805160028082526060820183526000926020830190803683370190505090503081600081518110612a6457612a646130f8565b6001600160a01b03928316602091820292909201810191909152600654604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa158015612abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ae1919061310e565b81600181518110612af457612af46130f8565b6001600160a01b039283166020918202929092010152600654612b1a9130911684611b82565b60065460405163791ac94760e01b81526001600160a01b039091169063791ac94790612b5390859060009086903090429060040161316f565b600060405180830381600087803b158015612b6d57600080fd5b505af1158015612b81573d6000803e3d6000fd5b505050505050565b600654612ba19030906001600160a01b031684611b82565b60065460405163f305d71960e01b815230600482015260248101849052600060448201819052606482015261dead60848201524260a48201526001600160a01b039091169063f305d71990839060c40160606040518083038185885af1158015612c0f573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906123a891906130b7565b801561116d576040805160028082526060820183526000926020830190803683375050600654604080516315ab88c960e31b815290519394506001600160a01b039091169263ad5c4648925060048083019260209291908290030181865afa158015612ca4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cc8919061310e565b81600081518110612cdb57612cdb6130f8565b6001600160a01b039283166020918202929092010152600954825191169082906001908110612d0c57612d0c6130f8565b6001600160a01b03928316602091820292909201015260065460405163b6f9de9560e01b815291169063b6f9de95908490612d52906000908690309042906004016131ab565b6000604051808303818588803b158015612d6b57600080fd5b505af1158015612d7f573d6000803e3d6000fd5b50505050505050565b600060208083528351808285015260005b81811015612db557858101830151858201604001528201612d99565b506000604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b038116811461116d57600080fd5b600060208284031215612dfd57600080fd5b8135612e0881612dd6565b9392505050565b60008060408385031215612e2257600080fd5b8235612e2d81612dd6565b946020939093013593505050565b60008060408385031215612e4e57600080fd5b50508035926020909101359150565b600080600060608486031215612e7257600080fd5b8335612e7d81612dd6565b92506020840135612e8d81612dd6565b929592945050506040919091013590565b60008060008060808587031215612eb457600080fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215612ee257600080fd5b5035919050565b801515811461116d57600080fd5b60008060408385031215612f0a57600080fd5b8235612f1581612dd6565b91506020830135612f2581612ee9565b809150509250929050565b600060208284031215612f4257600080fd5b8135612e0881612ee9565b60008060408385031215612f6057600080fd5b8235612f6b81612dd6565b91506020830135612f2581612dd6565b600181811c90821680612f8f57607f821691505b602082108103612faf57634e487b7160e01b600052602260045260246000fd5b50919050565b600080600080600080600080610100898b031215612fd257600080fd5b8851612fdd81612dd6565b809850506020890151965060408901519550606089015194506080890151935060a0890151925060c0890151915060e089015190509295985092959890939650565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610c5257610c5261301f565b60008261306957634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115610c5257610c5261301f565b60006020828403121561309357600080fd5b5051919050565b6000602082840312156130ac57600080fd5b8151612e0881612ee9565b6000806000606084860312156130cc57600080fd5b8351925060208401519150604084015190509250925092565b81810381811115610c5257610c5261301f565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561312057600080fd5b8151612e0881612dd6565b600081518084526020808501945080840160005b838110156131645781516001600160a01b03168752958201959082019060010161313f565b509495945050505050565b85815284602082015260a06040820152600061318e60a083018661312b565b6001600160a01b0394909416606083015250608001529392505050565b8481526080602082015260006131c4608083018661312b565b6001600160a01b0394909416604083015250606001529291505056fea2646970667358221220dcba0c5baed83de0f8acdeaa02765a0eff7bf3690997c17062b2c6b97a604e9c64736f6c6343000811003360806040523480156200001157600080fd5b506040516200240a3803806200240a833981016040819052620000349162000164565b60408051808201825260148082527f4d61727368656c6c65496e755f547261636b657200000000000000000000000060208084018290528451808601909552918452908301529082828260036200008c83826200023b565b5060046200009b82826200023b565b505050620000b8620000b26200010e60201b60201c565b62000112565b600a80546001600160a01b0319166001600160a01b03929092169190911790555050336000908152600960205260409020805460ff1916600117905550603c60135569021e19e0c9bab240000060145562000307565b3390565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602082840312156200017757600080fd5b81516001600160a01b03811681146200018f57600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620001c157607f821691505b602082108103620001e257634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200023657600081815260208120601f850160051c81016020861015620002115750805b601f850160051c820191505b8181101562000232578281556001016200021d565b5050505b505050565b81516001600160401b0381111562000257576200025762000196565b6200026f81620002688454620001ac565b84620001e8565b602080601f831160018114620002a757600084156200028e5750858301515b600019600386901b1c1916600185901b17855562000232565b600085815260208120601f198616915b82811015620002d857888601518255948401946001909101908401620002b7565b5085821015620002f75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6120f380620003176000396000f3fe60806040526004361061024a5760003560e01c8063715018a611610139578063b0c7ce37116100b6578063e30443bc1161007a578063e30443bc1461070c578063e7841ec01461072c578063e98030c714610741578063f2fde38b14610761578063fbcbc0f114610781578063ffb2c479146107a157600080fd5b8063b0c7ce3714610676578063bc4c4b3714610696578063be10b614146106b6578063c0f306ef146106cc578063dd62ed3e146106ec57600080fd5b806395d89b41116100fd57806395d89b41146105cb578063a457c2d7146105e0578063a8b9d24014610600578063a9059cbb14610620578063aafd847a1461064057600080fd5b8063715018a6146105425780637e3e7fd21461055757806385a6b3ae146105775780638da5cb5b1461058d57806391b89fba146105ab57600080fd5b806327ce0147116101c75780634e7b827f1161018b5780634e7b827f1461044c5780635183d6fd1461047c5780636a474002146104e15780636f2789ec146104f657806370a082311461050c57600080fd5b806327ce0147146103ba5780633009a609146103da578063313ce567146103f057806331e79db01461040c578063395093511461042c57600080fd5b80630dcb2e891161020e5780630dcb2e89146103005780631582358e1461032057806318160ddd14610358578063226cfa3d1461036d57806323b872dd1461039a57600080fd5b806303c833021461025e57806306fdde0314610266578063095ea7b31461029157806309bbedde146102c15780630b44a218146102e057600080fd5b36610259576102576107dc565b005b600080fd5b6102576107dc565b34801561027257600080fd5b5061027b61086f565b6040516102889190611df8565b60405180910390f35b34801561029d57600080fd5b506102b16102ac366004611e5b565b610901565b6040519015158152602001610288565b3480156102cd57600080fd5b50600c545b604051908152602001610288565b3480156102ec57600080fd5b506102576102fb366004611e9c565b61091b565b34801561030c57600080fd5b5061025761031b366004611ed1565b61094e565b34801561032c57600080fd5b50600a54610340906001600160a01b031681565b6040516001600160a01b039091168152602001610288565b34801561036457600080fd5b506002546102d2565b34801561037957600080fd5b506102d2610388366004611eea565b60126020526000908152604090205481565b3480156103a657600080fd5b506102b16103b5366004611f07565b6109f9565b3480156103c657600080fd5b506102d26103d5366004611eea565b610a1d565b3480156103e657600080fd5b506102d260105481565b3480156103fc57600080fd5b5060405160128152602001610288565b34801561041857600080fd5b50610257610427366004611eea565b610a79565b34801561043857600080fd5b506102b1610447366004611e5b565b610b6a565b34801561045857600080fd5b506102b1610467366004611eea565b60116020526000908152604090205460ff1681565b34801561048857600080fd5b5061049c610497366004611ed1565b610b8c565b604080516001600160a01b0390991689526020890197909752958701949094526060860192909252608085015260a084015260c083015260e082015261010001610288565b3480156104ed57600080fd5b50610257610bfb565b34801561050257600080fd5b506102d260135481565b34801561051857600080fd5b506102d2610527366004611eea565b6001600160a01b031660009081526020819052604090205490565b34801561054e57600080fd5b50610257610ca4565b34801561056357600080fd5b50610257610572366004611eea565b610cb6565b34801561058357600080fd5b506102d2600b5481565b34801561059957600080fd5b506005546001600160a01b0316610340565b3480156105b757600080fd5b506102d26105c6366004611eea565b610ce0565b3480156105d757600080fd5b5061027b610ceb565b3480156105ec57600080fd5b506102b16105fb366004611e5b565b610cfa565b34801561060c57600080fd5b506102d261061b366004611eea565b610d75565b34801561062c57600080fd5b506102b161063b366004611e5b565b610da1565b34801561064c57600080fd5b506102d261065b366004611eea565b6001600160a01b031660009081526008602052604090205490565b34801561068257600080fd5b50610257610691366004611ed1565b610daf565b3480156106a257600080fd5b506102b16106b1366004611e9c565b610e38565b3480156106c257600080fd5b506102d260145481565b3480156106d857600080fd5b506102576106e7366004611eea565b610ec3565b3480156106f857600080fd5b506102d2610707366004611f48565b610eec565b34801561071857600080fd5b50610257610727366004611e5b565b610f17565b34801561073857600080fd5b506010546102d2565b34801561074d57600080fd5b5061025761075c366004611ed1565b610f8a565b34801561076d57600080fd5b5061025761077c366004611eea565b6110d5565b34801561078d57600080fd5b5061049c61079c366004611eea565b61114b565b3480156107ad57600080fd5b506107c16107bc366004611ed1565b611234565b60408051938452602084019290925290820152606001610288565b60006107e760025490565b116107f157600080fd5b341561086d5761082461080360025490565b61081134600160801b611351565b61081b9190611f97565b60065490611364565b60065560405134815233907fa493a9229478c3fcd73f66d2cdeb7f94fd0f341da924d1054236d784541165119060200160405180910390a2600b546108699034611364565b600b555b565b60606003805461087e90611fb9565b80601f01602080910402602001604051908101604052809291908181526020018280546108aa90611fb9565b80156108f75780601f106108cc576101008083540402835291602001916108f7565b820191906000526020600020905b8154815290600101906020018083116108da57829003601f168201915b5050505050905090565b60003361090f818585611370565b60019150505b92915050565b610923611494565b6001600160a01b03919091166000908152600960205260409020805460ff1916911515919091179055565b610956611494565b60145481036109e55760405162461bcd60e51b815260206004820152604a60248201527f4e6577206d696d696d756d2062616c616e636520666f72206469766964656e6460448201527f2063616e6e6f742062652073616d652061732063757272656e74206d696e696d606482015269756d2062616c616e636560b01b608482015260a4015b60405180910390fd5b6109f381633b9aca00611ff3565b60145550565b600033610a078582856114ee565b610a12858585611568565b506001949350505050565b6001600160a01b03811660009081526007602090815260408083205491839052822054600654600160801b92610a6f92610a6a92610a6491610a5f9190611351565b6115c3565b906115d3565b611611565b6109159190611f97565b610a81611494565b6001600160a01b03811660009081526011602052604090205460ff1615610afa5760405162461bcd60e51b815260206004820152602760248201527f4164647265737320616c7265616479206578636c756465642066726f6d206469604482015266766964656e647360c81b60648201526084016109dc565b6001600160a01b0381166000908152601160205260408120805460ff19166001179055610b28908290611624565b610b33600c82611683565b6040516001600160a01b038216907fa878b31040b2e6d0a9a3d3361209db3908ba62014b0dca52adbaee451d128b2590600090a250565b60003361090f818585610b7d8383610eec565b610b87919061200a565b611370565b600080600080600080600080610ba1600c5490565b8910610bc6575060009650600019955085945086935083925082915081905080610bf0565b6000610bd3600c8b6117be565b9050610bde8161114b565b98509850985098509850985098509850505b919395975091939597565b60405162461bcd60e51b815260206004820152606c60248201527f4d61727368656c6c65496e755f547261636b65723a207769746864726177446960448201527f766964656e642064697361626c65642e20557365207468652027636c61696d2760648201527f2066756e6374696f6e206f6e20746865206d61696e204d61727368656c6c654960848201526b373a9031b7b73a3930b1ba1760a11b60a482015260c4016109dc565b610cac611494565b61086d60006117f1565b610cbe611494565b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b600061091582610d75565b60606004805461087e90611fb9565b60003381610d088286610eec565b905083811015610d685760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016109dc565b610a128286868403611370565b6001600160a01b03811660009081526008602052604081205461091590610d9b84610a1d565b90611843565b60003361090f818585611568565b610db7611494565b6000610dc260025490565b11610dcc57600080fd5b8015610e3557610dec610dde60025490565b61081183600160801b611351565b60065560405181815233907fa493a9229478c3fcd73f66d2cdeb7f94fd0f341da924d1054236d784541165119060200160405180910390a2600b54610e319082611364565b600b555b50565b6000610e42611494565b6000610e4d8461184f565b90508015610eb9576001600160a01b038416600081815260126020526040908190204290555184151591907fa2c38e2d2fb7e3e1912d937fd1ca11ed6d51864dee4cfa7a7bf02becd7acf09290610ea79085815260200190565b60405180910390a36001915050610915565b5060009392505050565b610ecb611494565b6001600160a01b03166000908152601160205260409020805460ff19169055565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610f1f611494565b6001600160a01b03821660009081526011602052604090205460ff16610f86576014548110610f6357610f528282611624565b610f5e600c8383611995565b610f79565b610f6e826000611624565b610f79600c83611683565b610f84826001610e38565b505b5050565b610f92611494565b610e108110158015610fa75750620151808111155b61102b5760405162461bcd60e51b815260206004820152604960248201527f4d61727368656c6c65496e755f547261636b65723a20636c61696d576169742060448201527f6d757374206265207570646174656420746f206265747765656e203120616e6460648201526820323420686f75727360b81b608482015260a4016109dc565b60135481036110a25760405162461bcd60e51b815260206004820152603b60248201527f4d61727368656c6c65496e755f547261636b65723a2043616e6e6f742075706460448201527f61746520636c61696d5761697420746f2073616d652076616c7565000000000060648201526084016109dc565b60135460405182907f474ea64804364a1e29a4487ddb63c3342a2dd826ccd8acf48825e680a0e6f20f90600090a3601355565b6110dd611494565b6001600160a01b0381166111425760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109dc565b610e35816117f1565b80600080808080808061115f600c89611a3e565b96506000199550600087126111c15760105487111561118d57601054611186908890611a89565b95506111c1565b601054600c54600091106111a25760006111b1565b601054600c546111b191611843565b90506111bd88826115d3565b9650505b6111ca88610d75565b94506111d588610a1d565b6001600160a01b0389166000908152601260205260409020549094509250826111ff57600061120d565b60135461120d908490611364565b915042821161121d576000611227565b6112278242611843565b9050919395975091939597565b600c54600090819081908082036112565750506010546000925082915061134a565b6010546000805a90506000805b898410801561127157508582105b1561133957846112808161201d565b600c549096508610905061129357600094505b6000600c60000186815481106112ab576112ab612036565b60009182526020808320909101546001600160a01b031680835260129091526040909120549091506112dc90611ad5565b156112ff576112ec816001610e38565b156112ff57816112fb8161201d565b9250505b826113098161201d565b93505060005a9050808511156113305761132d6113268683611843565b8790611364565b95505b93506112639050565b601085905590975095509193505050505b9193909250565b600061135d8284611ff3565b9392505050565b600061135d828461200a565b6001600160a01b0383166113d25760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016109dc565b6001600160a01b0382166114335760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016109dc565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6005546001600160a01b0316331461086d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109dc565b60006114fa8484610eec565b9050600019811461156257818110156115555760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016109dc565b6115628484848403611370565b50505050565b60405162461bcd60e51b815260206004820152602a60248201527f4d61727368656c6c65496e755f547261636b65723a204e6f207472616e7366656044820152691c9cc8185b1b1bddd95960b21b60648201526084016109dc565b6000818181121561091557600080fd5b6000806115e0838561204c565b9050600083121580156115f35750838112155b80611608575060008312801561160857508381125b61135d57600080fd5b60008082121561162057600080fd5b5090565b6001600160a01b038216600090815260208190526040902054808211156116635760006116518383611843565b905061165d8482611afc565b50610f84565b80821015610f845760006116778284611843565b90506115628482611b60565b6001600160a01b038116600090815260038301602052604090205460ff166116a9575050565b6001600160a01b03811660009081526003830160209081526040808320805460ff19169055600180860183528184208490556002860190925282205484549092916116f391612074565b9050600084600001828154811061170c5761170c612036565b60009182526020808320909101546001600160a01b0390811680845260028901909252604080842087905590871683528220919091558554909150819086908590811061175b5761175b612036565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055845485908061179557611795612087565b600082815260209020810160001990810180546001600160a01b03191690550190555050505050565b60008260000182815481106117d5576117d5612036565b6000918252602090912001546001600160a01b03169392505050565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600061135d8284612074565b60008061185b83610d75565b9050801561198c576001600160a01b0383166000908152600860205260409020546118869082611364565b6001600160a01b038416600081815260086020526040908190209290925590517fee503bee2bb6a87e57bc57db795f98137327401a0e7b7ce42e37926cc1a9ca4d906118d59084815260200190565b60405180910390a26000836001600160a01b031682610bb890604051600060405180830381858888f193505050503d806000811461192f576040519150601f19603f3d011682016040523d82523d6000602084013e611934565b606091505b5050905080611985576001600160a01b0384166000908152600860205260409020546119609083611843565b6001600160a01b03909416600090815260086020526040812094909455509192915050565b5092915050565b50600092915050565b6001600160a01b038216600090815260038401602052604090205460ff16156119da576001600160a01b03821660009081526001840160205260409020819055610f84565b6001600160a01b03821660008181526003850160209081526040808320805460ff19166001908117909155878101835281842086905587546002890184529184208290558101875586835291200180546001600160a01b0319169091179055505050565b6001600160a01b038116600090815260038301602052604081205460ff16611a695750600019610915565b506001600160a01b03166000908152600291909101602052604090205490565b6000808212158015611aa4575082611aa1838261209d565b13155b80611ac25750600082128015611ac2575082611ac0838261209d565b135b611acb57600080fd5b61135d828461209d565b600042821115611ae757506000919050565b601354611af44284611843565b101592915050565b611b068282611ba4565b611b40611b21610a5f8360065461135190919063ffffffff16565b6001600160a01b03841660009081526007602052604090205490611a89565b6001600160a01b0390921660009081526007602052604090209190915550565b611b6a8282611c97565b611b40611b85610a5f8360065461135190919063ffffffff16565b6001600160a01b038416600090815260076020526040902054906115d3565b6001600160a01b038216611bfa5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016109dc565b611c0660008383610f84565b8060026000828254611c18919061200a565b90915550506001600160a01b03821660009081526020819052604081208054839290611c4590849061200a565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3610f8660008383610f84565b6001600160a01b038216611cf75760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016109dc565b611d0382600083610f84565b6001600160a01b03821660009081526020819052604090205481811015611d775760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016109dc565b6001600160a01b0383166000908152602081905260408120838303905560028054849290611da6908490612074565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3610f8483600084610f84565b600060208083528351808285015260005b81811015611e2557858101830151858201604001528201611e09565b506000604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b0381168114610e3557600080fd5b60008060408385031215611e6e57600080fd5b8235611e7981611e46565b946020939093013593505050565b80358015158114611e9757600080fd5b919050565b60008060408385031215611eaf57600080fd5b8235611eba81611e46565b9150611ec860208401611e87565b90509250929050565b600060208284031215611ee357600080fd5b5035919050565b600060208284031215611efc57600080fd5b813561135d81611e46565b600080600060608486031215611f1c57600080fd5b8335611f2781611e46565b92506020840135611f3781611e46565b929592945050506040919091013590565b60008060408385031215611f5b57600080fd5b8235611f6681611e46565b91506020830135611f7681611e46565b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b600082611fb457634e487b7160e01b600052601260045260246000fd5b500490565b600181811c90821680611fcd57607f821691505b602082108103611fed57634e487b7160e01b600052602260045260246000fd5b50919050565b808202811582820484141761091557610915611f81565b8082018082111561091557610915611f81565b60006001820161202f5761202f611f81565b5060010190565b634e487b7160e01b600052603260045260246000fd5b808201828112600083128015821682158216171561206c5761206c611f81565b505092915050565b8181038181111561091557610915611f81565b634e487b7160e01b600052603160045260246000fd5b818103600083128015838313168383128216171561198557611985611f8156fea2646970667358221220333a0404539fae773bf87405e35ce1660028709a787246db57465d0f3827dc6a64736f6c63430008110033

Deployed Bytecode

0x6080604052600436106103905760003560e01c806395d89b41116101dc578063c2d84c4e11610102578063d851fd0d116100a0578063e7ad9fcd1161006f578063e7ad9fcd14610a8b578063ec7a661714610aab578063f2fde38b14610adb578063f3bc974014610afb57600080fd5b8063d851fd0d14610a10578063dd62ed3e14610a26578063e0bf7fd114610a46578063e7841ec014610a7657600080fd5b8063c646c019116100dc578063c646c01914610980578063d1d7d7ef146109a0578063d257b34f146109d0578063d2fcc001146109f057600080fd5b8063c2d84c4e1461092a578063c31fe80a1461094a578063c49b9a801461096057600080fd5b8063a87e5da41161017a578063ae51d9f511610149578063ae51d9f5146108a5578063b62496f5146108ba578063c0246668146108ea578063c18bc1951461090a57600080fd5b8063a87e5da414610839578063a9059cbb1461084f578063aa4bde281461086f578063ae146e851461088557600080fd5b80639c1b8af5116101b65780639c1b8af5146107ce578063a26579ad146107e4578063a457c2d7146107f9578063a511a1a51461081957600080fd5b806395d89b4114610778578063969097991461078d5780639a7a23d6146107ae57600080fd5b80633eaaf86b116102c1578063685fc5681161025f57806375f0a8741161022e57806375f0a874146107055780638886ecfb146107255780638da5cb5b1461073a5780638ea5220f1461075857600080fd5b8063685fc56814610692578063700bb191146106b057806370a08231146106d0578063715018a6146106f057600080fd5b80634e71d92d1161029b5780634e71d92d14610628578063515eb2841461063d5780635d098b381461065d57806366eb37851461067d57600080fd5b80633eaaf86b146105dd57806344b4a75b146105f35780634b1f17c31461061357600080fd5b806323b872dd1161032e578063313ce56711610308578063313ce5671461056157806339086b9b1461057d578063395093511461059d5780633e92088b146105bd57600080fd5b806323b872dd146104f357806327c8f835146105135780632e6ed7ef1461054157600080fd5b8063095ea7b31161036a578063095ea7b31461046257806311a582c31461049257806318160ddd146104b45780631f53ac02146104d357600080fd5b80630644e7571461039c57806306fdde03146103db57806307f149b4146103fd57600080fd5b3661039757005b600080fd5b3480156103a857600080fd5b506013546014546015546016545b6040805194855260208501939093529183015260608201526080015b60405180910390f35b3480156103e757600080fd5b506103f0610b11565b6040516103d29190612d88565b34801561040957600080fd5b5061041d610418366004612deb565b610ba3565b604080516001600160a01b0390991689526020890197909752958701949094526060860192909252608085015260a084015260c083015260e0820152610100016103d2565b34801561046e57600080fd5b5061048261047d366004612e0f565b610c3e565b60405190151581526020016103d2565b34801561049e57600080fd5b506104b26104ad366004612e3b565b610c58565b005b3480156104c057600080fd5b506002545b6040519081526020016103d2565b3480156104df57600080fd5b506104b26104ee366004612deb565b610db2565b3480156104ff57600080fd5b5061048261050e366004612e5d565b610e0c565b34801561051f57600080fd5b5061052961dead81565b6040516001600160a01b0390911681526020016103d2565b34801561054d57600080fd5b506104b261055c366004612e9e565b610e30565b34801561056d57600080fd5b50604051601281526020016103d2565b34801561058957600080fd5b506104b2610598366004612deb565b610f32565b3480156105a957600080fd5b506104826105b8366004612e0f565b610ff3565b3480156105c957600080fd5b50600954610529906001600160a01b031681565b3480156105e957600080fd5b506104c5600c5481565b3480156105ff57600080fd5b506104c561060e366004612deb565b611015565b34801561061f57600080fd5b506104c5611085565b34801561063457600080fd5b506104b26110f8565b34801561064957600080fd5b5061041d610658366004612ed0565b611170565b34801561066957600080fd5b506104b2610678366004612deb565b6111b2565b34801561068957600080fd5b506104b261120c565b34801561069e57600080fd5b50601854601954601a54601b546103b6565b3480156106bc57600080fd5b506104b26106cb366004612ed0565b61122f565b3480156106dc57600080fd5b506104c56106eb366004612deb565b611301565b3480156106fc57600080fd5b506104b261131c565b34801561071157600080fd5b50600a54610529906001600160a01b031681565b34801561073157600080fd5b506104c561132e565b34801561074657600080fd5b506005546001600160a01b0316610529565b34801561076457600080fd5b50600b54610529906001600160a01b031681565b34801561078457600080fd5b506103f0611378565b34801561079957600080fd5b50600b5461048290600160b01b900460ff1681565b3480156107ba57600080fd5b506104b26107c9366004612ef7565b611387565b3480156107da57600080fd5b506104c560205481565b3480156107f057600080fd5b506104c56113e3565b34801561080557600080fd5b50610482610814366004612e0f565b61142d565b34801561082557600080fd5b506104b2610834366004612ef7565b6114a8565b34801561084557600080fd5b506104c5600d5481565b34801561085b57600080fd5b5061048261086a366004612e0f565b6115e4565b34801561087b57600080fd5b506104c5600f5481565b34801561089157600080fd5b50600754610529906001600160a01b031681565b3480156108b157600080fd5b506104c56115f2565b3480156108c657600080fd5b506104826108d5366004612deb565b60246020526000908152604090205460ff1681565b3480156108f657600080fd5b506104b2610905366004612ef7565b61163c565b34801561091657600080fd5b506104b2610925366004612ed0565b6116a4565b34801561093657600080fd5b506104c5610945366004612deb565b611754565b34801561095657600080fd5b506104c560115481565b34801561096c57600080fd5b506104b261097b366004612f30565b611787565b34801561098c57600080fd5b506104b261099b366004612ef7565b6117ad565b3480156109ac57600080fd5b506104826109bb366004612deb565b60236020526000908152604090205460ff1681565b3480156109dc57600080fd5b506104826109eb366004612ed0565b61180d565b3480156109fc57600080fd5b506104b2610a0b366004612ef7565b61193e565b348015610a1c57600080fd5b506104c5600e5481565b348015610a3257600080fd5b506104c5610a41366004612f4d565b61199e565b348015610a5257600080fd5b50610482610a61366004612deb565b60216020526000908152604090205460ff1681565b348015610a8257600080fd5b506104c56119c9565b348015610a9757600080fd5b506104b2610aa6366004612e9e565b611a13565b348015610ab757600080fd5b50610482610ac6366004612deb565b60226020526000908152604090205460ff1681565b348015610ae757600080fd5b506104b2610af6366004612deb565b611b0c565b348015610b0757600080fd5b506104c560105481565b606060038054610b2090612f7b565b80601f0160208091040260200160405190810160405280929190818152602001828054610b4c90612f7b565b8015610b995780601f10610b6e57610100808354040283529160200191610b99565b820191906000526020600020905b815481529060010190602001808311610b7c57829003601f168201915b5050505050905090565b60075460405163fbcbc0f160e01b81526001600160a01b038381166004830152600092839283928392839283928392839291169063fbcbc0f1906024015b61010060405180830381865afa158015610bff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c239190612fb5565b97509750975097509750975097509750919395975091939597565b600033610c4c818585611b82565b60019150505b92915050565b610c60611ca6565b670de0b6b3a76400006103e8610c7560025490565b610c80906005613035565b610c8a919061304c565b610c94919061304c565b821015610cf45760405163d0179c8560e01b815260206004820152602260248201527f43616e6e6f7420736574206d617820627579206c6f776572207468616e20302e604482015261352560f01b60648201526084015b60405180910390fd5b670de0b6b3a76400006103e8610d0960025490565b610d14906005613035565b610d1e919061304c565b610d28919061304c565b811015610d845760405163d0179c8560e01b815260206004820152602360248201527f43616e6e6f7420736574206d61782073656c6c206c6f776572207468616e20306044820152622e352560e81b6064820152608401610ceb565b610d9682670de0b6b3a7640000613035565b600d55610dab81670de0b6b3a7640000613035565b600e555050565b610dba611ca6565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f923334f00a08147112838c5c41f68a92979493ae7af34177449883db5743427790600090a35050565b600033610e1a858285611d00565b610e25858585611d7a565b506001949350505050565b610e38611ca6565b60138490556014839055601582905560168190558082610e58858761306e565b610e62919061306e565b610e6c919061306e565b6012819055601754601991610e809161306e565b1115610ecf57604051637f20723d60e01b815260206004820181905260248201527f546f74616c2046656573206d757374206265206c657373207468616e203235256044820152606401610ceb565b60125460135460145460155460165460408051958652602086019490945292840191909152606083015260808201527f36f734ef6334bb46ffb96a53ac28a5f80f907b4e1edb3c8af6dd32ba6e57f8589060a0015b60405180910390a150505050565b610f3a611ca6565b600980546001600160a01b038381166001600160a01b031983168117909355600754604051633f1f3fe960e11b8152600481019490945291811692911690637e3e7fd290602401600060405180830381600087803b158015610f9b57600080fd5b505af1158015610faf573d6000803e3d6000fd5b50506009546040516001600160a01b03918216935090841691507fc50953975bfb7dc05da466bc18236bf737c11097c9cc7ef9d079bc7ed96f03ae90600090a35050565b600033610c4c818585611006838361199e565b611010919061306e565b611b82565b6007546040516370a0823160e01b81526001600160a01b03838116600483015260009216906370a08231906024015b602060405180830381865afa158015611061573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c529190613081565b600754604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa1580156110cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f39190613081565b905090565b60075460405163bc4c4b3760e01b8152336004820152600060248201526001600160a01b039091169063bc4c4b37906044016020604051808303816000875af1158015611149573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116d919061309a565b50565b600754604051635183d6fd60e01b81526004810183905260009182918291829182918291829182916001600160a01b0390911690635183d6fd90602401610be1565b6111ba611ca6565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907facf03c50dcf01e53e2775267d12acd0158d87c2f20fb84226837142693b36ae790600090a35050565b611214611ca6565b600061121f30611301565b111561122d5761122d6123af565b565b6007546040516001624d3b8760e01b0319815260048101839052600091829182916001600160a01b03169063ffb2c479906024016060604051808303816000875af1158015611282573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a691906130b7565b604080518481526020810184905290810182905260608101889052929550909350915032906000907fc864333d6121033635ab41b29ae52f10a22cf4438c3e4f1c4c68518feb2f8a989060800160405180910390a350505050565b6001600160a01b031660009081526020819052604090205490565b611324611ca6565b61122d600061280f565b600754604080516304ddf6ef60e11b815290516000926001600160a01b0316916309bbedde9160048083019260209291908290030181865afa1580156110cf573d6000803e3d6000fd5b606060048054610b2090612f7b565b61138f611ca6565b6001600160a01b038216600081815260246020526040808220805460ff191685151590811790915590519092917fffa9187bf1f18bf477bd0ea1bcbb64e93b6a98132473929edfce215cd9b16fab91a35050565b60075460408051631bc9e27b60e21b815290516000926001600160a01b031691636f2789ec9160048083019260209291908290030181865afa1580156110cf573d6000803e3d6000fd5b6000338161143b828661199e565b90508381101561149b5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610ceb565b610e258286868403611b82565b6114b0611ca6565b801561154d5760075460405163c0f306ef60e01b81526001600160a01b0384811660048301529091169063c0f306ef90602401600060405180830381600087803b1580156114fd57600080fd5b505af1158015611511573d6000803e3d6000fd5b50506040516001600160a01b03851692507f40a78dcf8526b72f2eaf598af1c7e49c8d5fc577f6c8f1bed887f3e4dfa289329150600090a25050565b60075460405163031e79db60e41b81526001600160a01b038481166004830152909116906331e79db090602401600060405180830381600087803b15801561159457600080fd5b505af11580156115a8573d6000803e3d6000fd5b50506040516001600160a01b03851692507fa878b31040b2e6d0a9a3d3361209db3908ba62014b0dca52adbaee451d128b259150600090a25050565b600033610c4c818585611d7a565b600754604080516342d359d760e11b815290516000926001600160a01b0316916385a6b3ae9160048083019260209291908290030181865afa1580156110cf573d6000803e3d6000fd5b611644611ca6565b6001600160a01b038216600081815260216020908152604091829020805460ff191685151590811790915591519182527f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df791015b60405180910390a25050565b6116ac611ca6565b670de0b6b3a76400006103e86116c160025490565b6116cc906005613035565b6116d6919061304c565b6116e0919061304c565b81101561173c57604051634d8a090560e01b8152602060048201526024808201527f43616e6e6f7420736574206d617857616c6c6574206c6f776572207468616e20604482015263302e352560e01b6064820152608401610ceb565b61174e81670de0b6b3a7640000613035565b600f5550565b6007546040516302a2e74960e61b81526001600160a01b038381166004830152600092169063a8b9d24090602401611044565b61178f611ca6565b600b8054911515600160a81b0260ff60a81b19909216919091179055565b6117b5611ca6565b6001600160a01b038216600081815260226020908152604091829020805460ff191685151590811790915591519182527fbbba3cea579dbad4552c9ff73eabdce62821f125571c096df83e2116e438567c9101611698565b6000611817611ca6565b620186a061182460025490565b61182f906001613035565b611839919061304c565b8210156118a75760405163dcd85d8f60e01b815260206004820152603560248201527f5377617020616d6f756e742063616e6e6f74206265206c6f776572207468616e60448201527410181718181892903a37ba30b61039bab838363c9760591b6064820152608401610ceb565b6103e86118b360025490565b6118be906001613035565b6118c8919061304c565b8211156119355760405163dcd85d8f60e01b815260206004820152603460248201527f5377617020616d6f756e742063616e6e6f742062652068696768657220746861604482015273371018171892903a37ba30b61039bab838363c9760611b6064820152608401610ceb565b50601055600190565b611946611ca6565b6001600160a01b038216600081815260236020908152604091829020805460ff191685151590811790915591519182527f4a8452f723db48bf05f301f94d62a2cf7a72976cde77d83e3646584858b8f4b29101611698565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6007546040805163039e107b60e61b815290516000926001600160a01b03169163e7841ec09160048083019260209291908290030181865afa1580156110cf573d6000803e3d6000fd5b611a1b611ca6565b60188490556019839055601a829055601b8190558082611a3b858761306e565b611a45919061306e565b611a4f919061306e565b6017819055601254601991611a64919061306e565b1115611ab357604051637f20723d60e01b815260206004820181905260248201527f546f74616c2046656573206d757374206265206c657373207468616e203235256044820152606401610ceb565b601754601854601954601a54601b5460408051958652602086019490945292840191909152606083015260808201527fa047973ee053932e622d31fe5ab89f310d1c9c947ac06a81f382d0d3df2b11029060a001610f24565b611b14611ca6565b6001600160a01b038116611b795760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ceb565b61116d8161280f565b6001600160a01b038316611be45760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610ceb565b6001600160a01b038216611c455760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610ceb565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6005546001600160a01b0316331461122d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ceb565b6000611d0c848461199e565b90506000198114611d745781811015611d675760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610ceb565b611d748484848403611b82565b50505050565b6000601054611d8830611301565b600b549111159150600160a01b900460ff166121cc576001600160a01b03841660009081526024602052604090205460ff1615611fde576001600160a01b03831660009081526022602052604090205460ff16611e2e57600d54821115611e2e57604051631e30f57d60e31b8152602060048201526019602482015278115e18d959591959081b585e08189d5e48151e105b5bdd5b9d603a1b6044820152606401610ceb565b6001600160a01b03831660009081526023602052604090205460ff16611eb057600f5482611e5b85611301565b611e65919061306e565b1115611eb057604051631e30f57d60e31b8152602060048201526019602482015278115e18d959591959081b585e08189d5e48151e105b5bdd5b9d603a1b6044820152606401610ceb565b6000601254118015611edb57506001600160a01b03831660009081526021602052604090205460ff16155b15611fd9576000606460125484611ef29190613035565b611efc919061304c565b9050611f0881846130e5565b925060125460135482611f1b9190613035565b611f25919061304c565b601c6000828254611f36919061306e565b9091555050601254601454611f4b9083613035565b611f55919061304c565b601d6000828254611f66919061306e565b9091555050601254601554611f7b9083613035565b611f85919061304c565b601e6000828254611f96919061306e565b9091555050601254601654611fab9083613035565b611fb5919061304c565b601f6000828254611fc6919061306e565b90915550611fd79050853083612861565b505b6121cc565b6001600160a01b03831660009081526024602052604090205460ff16156121cc57600b54600160a81b900460ff16801561201a57506000601754115b80156120235750805b15612030576120306123af565b6001600160a01b03841660009081526022602052604090205460ff166120a357600e548211156120a357604051631e30f57d60e31b815260206004820152601a60248201527f4578636565646564206d61782073656c6c205478416d6f756e740000000000006044820152606401610ceb565b60006017541180156120ce57506001600160a01b03841660009081526021602052604090205460ff16155b156121cc5760006064601754846120e59190613035565b6120ef919061304c565b90506120fb81846130e5565b92506017546018548261210e9190613035565b612118919061304c565b601c6000828254612129919061306e565b909155505060175460195461213e9083613035565b612148919061304c565b601d6000828254612159919061306e565b9091555050601754601a5461216e9083613035565b612178919061304c565b601e6000828254612189919061306e565b9091555050601754601b5461219e9083613035565b6121a8919061304c565b601f60008282546121b9919061306e565b909155506121ca9050853083612861565b505b6121d7848484612861565b6007546001600160a01b031663e30443bc856121f281611301565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561223857600080fd5b505af1925050508015612249575060015b506007546001600160a01b031663e30443bc8461226581611301565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156122ab57600080fd5b505af19250505080156122bc575060015b50600b54600160a01b900460ff161580156122e05750600b54600160b01b900460ff165b15611d74576020546007546040516001624d3b8760e01b03198152600481018390526001600160a01b039091169063ffb2c479906024016060604051808303816000875af1925050508015612352575060408051601f3d908101601f1916820190925261234f918101906130b7565b60015b156123a85760408051848152602081018490529081018290526060810185905232906001907fc864333d6121033635ab41b29ae52f10a22cf4438c3e4f1c4c68518feb2f8a989060800160405180910390a35050505b5050505050565b600b805460ff60a01b1916600160a01b17905560006123cd30611301565b90506000601f54601e54601c54601d546123e7919061306e565b6123f1919061306e565b6123fb919061306e565b905060008083158061240b575082155b156124165750505050565b601054831115612429575060105461242c565b50815b6000600284601e548461243f9190613035565b612449919061304c565b612453919061304c565b9050600061246182846130e5565b90504761246d82612a2f565b600061247982476130e5565b9050600087601d548361248c9190613035565b612496919061304c565b9050600088601e54846124a99190613035565b6124b3919061304c565b9050600089601f54856124c69190613035565b6124d0919061304c565b600b546040519192506001600160a01b0316908490600081818185875af1925050503d806000811461251e576040519150601f19603f3d011682016040523d82523d6000602084013e612523565b606091505b509099505086158015906125375750600082115b1561258a576125468783612b89565b601e54604080518881526020810185905280820192909252517f17bbfb9a6069321b6ded73bd96327c9e6b7212a5cd51ff219cd61370acafb5619181900360600190a15b61259381612c34565b6009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156125dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126009190613081565b60095460075460405163a9059cbb60e01b81526001600160a01b03918216600482015260248101849052929350169063a9059cbb906044016020604051808303816000875af1158015612657573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061267b919061309a565b9950891561271c5760075460405163b0c7ce3760e01b8152600481018390526001600160a01b039091169063b0c7ce3790602401600060405180830381600087803b1580156126c957600080fd5b505af11580156126dd573d6000803e3d6000fd5b505060408051848152602081018690527f80195cc573b02cc48460cbca6e6e4cc85ddb91959d946e1c3025ea3d87942dc3935001905060405180910390a15b600a546040516001600160a01b03909116904790600081818185875af1925050503d8060008114612769576040519150601f19603f3d011682016040523d82523d6000602084013e61276e565b606091505b5050809a505061277d30611301565b9b50601754601a548d6127909190613035565b61279a919061304c565b601e556017546018546127ad908e613035565b6127b7919061304c565b601c556017546019546127ca908e613035565b6127d4919061304c565b601d55601754601b546127e7908e613035565b6127f1919061304c565b601f555050600b805460ff60a01b1916905550505050505050505050565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0383166128c55760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610ceb565b6001600160a01b0382166129275760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610ceb565b6001600160a01b0383166000908152602081905260409020548181101561299f5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610ceb565b6001600160a01b038085166000908152602081905260408082208585039055918516815290812080548492906129d690849061306e565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612a2291815260200190565b60405180910390a3611d74565b6040805160028082526060820183526000926020830190803683370190505090503081600081518110612a6457612a646130f8565b6001600160a01b03928316602091820292909201810191909152600654604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa158015612abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ae1919061310e565b81600181518110612af457612af46130f8565b6001600160a01b039283166020918202929092010152600654612b1a9130911684611b82565b60065460405163791ac94760e01b81526001600160a01b039091169063791ac94790612b5390859060009086903090429060040161316f565b600060405180830381600087803b158015612b6d57600080fd5b505af1158015612b81573d6000803e3d6000fd5b505050505050565b600654612ba19030906001600160a01b031684611b82565b60065460405163f305d71960e01b815230600482015260248101849052600060448201819052606482015261dead60848201524260a48201526001600160a01b039091169063f305d71990839060c40160606040518083038185885af1158015612c0f573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906123a891906130b7565b801561116d576040805160028082526060820183526000926020830190803683375050600654604080516315ab88c960e31b815290519394506001600160a01b039091169263ad5c4648925060048083019260209291908290030181865afa158015612ca4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cc8919061310e565b81600081518110612cdb57612cdb6130f8565b6001600160a01b039283166020918202929092010152600954825191169082906001908110612d0c57612d0c6130f8565b6001600160a01b03928316602091820292909201015260065460405163b6f9de9560e01b815291169063b6f9de95908490612d52906000908690309042906004016131ab565b6000604051808303818588803b158015612d6b57600080fd5b505af1158015612d7f573d6000803e3d6000fd5b50505050505050565b600060208083528351808285015260005b81811015612db557858101830151858201604001528201612d99565b506000604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b038116811461116d57600080fd5b600060208284031215612dfd57600080fd5b8135612e0881612dd6565b9392505050565b60008060408385031215612e2257600080fd5b8235612e2d81612dd6565b946020939093013593505050565b60008060408385031215612e4e57600080fd5b50508035926020909101359150565b600080600060608486031215612e7257600080fd5b8335612e7d81612dd6565b92506020840135612e8d81612dd6565b929592945050506040919091013590565b60008060008060808587031215612eb457600080fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215612ee257600080fd5b5035919050565b801515811461116d57600080fd5b60008060408385031215612f0a57600080fd5b8235612f1581612dd6565b91506020830135612f2581612ee9565b809150509250929050565b600060208284031215612f4257600080fd5b8135612e0881612ee9565b60008060408385031215612f6057600080fd5b8235612f6b81612dd6565b91506020830135612f2581612dd6565b600181811c90821680612f8f57607f821691505b602082108103612faf57634e487b7160e01b600052602260045260246000fd5b50919050565b600080600080600080600080610100898b031215612fd257600080fd5b8851612fdd81612dd6565b809850506020890151965060408901519550606089015194506080890151935060a0890151925060c0890151915060e089015190509295985092959890939650565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610c5257610c5261301f565b60008261306957634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115610c5257610c5261301f565b60006020828403121561309357600080fd5b5051919050565b6000602082840312156130ac57600080fd5b8151612e0881612ee9565b6000806000606084860312156130cc57600080fd5b8351925060208401519150604084015190509250925092565b81810381811115610c5257610c5261301f565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561312057600080fd5b8151612e0881612dd6565b600081518084526020808501945080840160005b838110156131645781516001600160a01b03168752958201959082019060010161313f565b509495945050505050565b85815284602082015260a06040820152600061318e60a083018661312b565b6001600160a01b0394909416606083015250608001529392505050565b8481526080602082015260006131c4608083018661312b565b6001600160a01b0394909416604083015250606001529291505056fea2646970667358221220dcba0c5baed83de0f8acdeaa02765a0eff7bf3690997c17062b2c6b97a604e9c64736f6c63430008110033

Deployed Bytecode Sourcemap

60083:25167:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84454:384;;;;;;;;;;-1:-1:-1;84713:15:0;;84748:9;;84777:15;;84812:17;;84454:384;;;;245:25:1;;;301:2;286:18;;279:34;;;;329:18;;;322:34;387:2;372:18;;365:34;232:3;217:19;84454:384:0;;;;;;;;27988:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;83684:372::-;;;;;;;;;;-1:-1:-1;83684:372:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;1708:32:1;;;1690:51;;1772:2;1757:18;;1750:34;;;;1800:18;;;1793:34;;;;1858:2;1843:18;;1836:34;;;;1901:3;1886:19;;1879:35;1728:3;1930:19;;1923:35;1989:3;1974:19;;1967:35;2033:3;2018:19;;2011:35;1677:3;1662:19;83684:372:0;1351:701:1;30339:201:0;;;;;;;;;;-1:-1:-1;30339:201:0;;;;;:::i;:::-;;:::i;:::-;;;2542:14:1;;2535:22;2517:41;;2505:2;2490:18;30339:201:0;2377:187:1;76758:569:0;;;;;;;;;;-1:-1:-1;76758:569:0;;;;;:::i;:::-;;:::i;:::-;;29108:108;;;;;;;;;;-1:-1:-1;29196:12:0;;29108:108;;;2968:25:1;;;2956:2;2941:18;29108:108:0;2822:177:1;80243:206:0;;;;;;;;;;-1:-1:-1;80243:206:0;;;;;:::i;:::-;;:::i;31120:295::-;;;;;;;;;;-1:-1:-1;31120:295:0;;;;;:::i;:::-;;:::i;60324:53::-;;;;;;;;;;;;60370:6;60324:53;;;;;-1:-1:-1;;;;;3889:32:1;;;3871:51;;3859:2;3844:18;60324:53:0;3725:203:1;78576:814:0;;;;;;;;;;-1:-1:-1;78576:814:0;;;;;:::i;:::-;;:::i;28950:93::-;;;;;;;;;;-1:-1:-1;28950:93:0;;29033:2;4465:36:1;;4453:2;4438:18;28950:93:0;4323:184:1;81510:313:0;;;;;;;;;;-1:-1:-1;81510:313:0;;;;;:::i;:::-;;:::i;31824:238::-;;;;;;;;;;-1:-1:-1;31824:238:0;;;;;:::i;:::-;;:::i;60384:72::-;;;;;;;;;;-1:-1:-1;60384:72:0;;;;-1:-1:-1;;;;;60384:72:0;;;60773:27;;;;;;;;;;;;;;;;83481:195;;;;;;;;;;-1:-1:-1;83481:195:0;;;;;:::i;:::-;;:::i;82789:140::-;;;;;;;;;;;;;:::i;75699:115::-;;;;;;;;;;;;;:::i;84064:382::-;;;;;;;;;;-1:-1:-1;84064:382:0;;;;;:::i;:::-;;:::i;80457:247::-;;;;;;;;;;-1:-1:-1;80457:247:0;;;;;:::i;:::-;;:::i;75558:127::-;;;;;;;;;;;;;:::i;84846:401::-;;;;;;;;;;-1:-1:-1;85123:16:0;;85154:10;;85179:16;;85210:18;;84846:401;;81080:422;;;;;;;;;;-1:-1:-1;81080:422:0;;;;;:::i;:::-;;:::i;29279:127::-;;;;;;;;;;-1:-1:-1;29279:127:0;;;;;:::i;:::-;;:::i;40657:103::-;;;;;;;;;;;;;:::i;60463:84::-;;;;;;;;;;-1:-1:-1;60463:84:0;;;;-1:-1:-1;;;;;60463:84:0;;;82586:195;;;;;;;;;;;;;:::i;40009:87::-;;;;;;;;;;-1:-1:-1;40082:6:0;;-1:-1:-1;;;;;40082:6:0;40009:87;;60554:78;;;;;;;;;;-1:-1:-1;60554:78:0;;;;-1:-1:-1;;;;;60554:78:0;;;28207:104;;;;;;;;;;;;;:::i;60720:33::-;;;;;;;;;;-1:-1:-1;60720:33:0;;;;-1:-1:-1;;;60720:33:0;;;;;;78346:222;;;;;;;;;;-1:-1:-1;78346:222:0;;;;;:::i;:::-;;:::i;61541:40::-;;;;;;;;;;;;;;;;82937:121;;;;;;;;;;;;;:::i;32565:436::-;;;;;;;;;;-1:-1:-1;32565:436:0;;;;;:::i;:::-;;:::i;81831:385::-;;;;;;;;;;-1:-1:-1;81831:385:0;;;;;:::i;:::-;;:::i;60807:29::-;;;;;;;;;;;;;;;;29612:193;;;;;;;;;;-1:-1:-1;29612:193:0;;;;;:::i;:::-;;:::i;60880:30::-;;;;;;;;;;;;;;;;60213:62;;;;;;;;;;-1:-1:-1;60213:62:0;;;;-1:-1:-1;;;;;60213:62:0;;;83066:194;;;;;;;;;;;;;:::i;61790:57::-;;;;;;;;;;-1:-1:-1;61790:57:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;78125:213;;;;;;;;;;-1:-1:-1;78125:213:0;;;;;:::i;:::-;;:::i;77335:313::-;;;;;;;;;;-1:-1:-1;77335:313:0;;;;;:::i;:::-;;:::i;83268:205::-;;;;;;;;;;-1:-1:-1;83268:205:0;;;;;:::i;:::-;;:::i;60962:31::-;;;;;;;;;;;;;;;;80714:147;;;;;;;;;;-1:-1:-1;80714:147:0;;;;;:::i;:::-;;:::i;77892:225::-;;;;;;;;;;-1:-1:-1;77892:225:0;;;;;:::i;:::-;;:::i;61727:56::-;;;;;;;;;;-1:-1:-1;61727:56:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;76174:576;;;;;;;;;;-1:-1:-1;76174:576:0;;;;;:::i;:::-;;:::i;77656:228::-;;;;;;;;;;-1:-1:-1;77656:228:0;;;;;:::i;:::-;;:::i;60843:30::-;;;;;;;;;;;;;;;;29868:151;;;;;;;;;;-1:-1:-1;29868:151:0;;;;;:::i;:::-;;:::i;61607:51::-;;;;;;;;;;-1:-1:-1;61607:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;82436:142;;;;;;;;;;;;;:::i;79398:837::-;;;;;;;;;;-1:-1:-1;79398:837:0;;;;;:::i;:::-;;:::i;61665:55::-;;;;;;;;;;-1:-1:-1;61665:55:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;40915:201;;;;;;;;;;-1:-1:-1;40915:201:0;;;;;:::i;:::-;;:::i;60917:38::-;;;;;;;;;;;;;;;;27988:100;28042:13;28075:5;28068:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27988:100;:::o;83684:372::-;84001:27;;:47;;-1:-1:-1;;;84001:47:0;;-1:-1:-1;;;;;3889:32:1;;;84001:47:0;;;3871:51:1;83807:7:0;;;;;;;;;;;;;;;;84001:27;;;:38;;3844:18:1;;84001:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;83994:54;;;;;;;;;;;;;;;;83684:372;;;;;;;;;:::o;30339:201::-;30422:4;25708:10;30478:32;25708:10;30494:7;30503:6;30478:8;:32::i;:::-;30528:4;30521:11;;;30339:201;;;;;:::o;76758:569::-;39895:13;:11;:13::i;:::-;76925:4:::1;76917;76896:13;29196:12:::0;;;29108:108;76896:13:::1;:17;::::0;76912:1:::1;76896:17;:::i;:::-;76895:26;;;;:::i;:::-;76894:35;;;;:::i;:::-;76882:9;:47;76878:164;;;76951:91;::::0;-1:-1:-1;;;76951:91:0;;7898:2:1;76951:91:0::1;::::0;::::1;7880:21:1::0;7937:2;7917:18;;;7910:30;7976:34;7956:18;;;7949:62;-1:-1:-1;;;8027:18:1;;;8020:32;8069:19;;76951:91:0::1;;;;;;;;76878:164;77101:4;77093;77072:13;29196:12:::0;;;29108:108;77072:13:::1;:17;::::0;77088:1:::1;77072:17;:::i;:::-;77071:26;;;;:::i;:::-;77070:35;;;;:::i;:::-;77057:10;:48;77053:166;;;77127:92;::::0;-1:-1:-1;;;77127:92:0;;8301:2:1;77127:92:0::1;::::0;::::1;8283:21:1::0;8340:2;8320:18;;;8313:30;8379:34;8359:18;;;8352:62;-1:-1:-1;;;8430:18:1;;;8423:33;8473:19;;77127:92:0::1;8099:399:1::0;77053:166:0::1;77249:20;:9:::0;77262:6:::1;77249:20;:::i;:::-;77232:14;:37:::0;77298:21:::1;:10:::0;77312:6:::1;77298:21;:::i;:::-;77280:15;:39:::0;-1:-1:-1;;76758:569:0:o;80243:206::-;39895:13;:11;:13::i;:::-;80344:9:::1;::::0;;-1:-1:-1;;;;;80364:22:0;;::::1;-1:-1:-1::0;;;;;;80364:22:0;::::1;::::0;::::1;::::0;;;80402:39:::1;::::0;80344:9;::::1;::::0;80364:22;80344:9;;80402:39:::1;::::0;80323:18:::1;::::0;80402:39:::1;80312:137;80243:206:::0;:::o;31120:295::-;31251:4;25708:10;31309:38;31325:4;25708:10;31340:6;31309:15;:38::i;:::-;31358:27;31368:4;31374:2;31378:6;31358:9;:27::i;:::-;-1:-1:-1;31403:4:0;;31120:295;-1:-1:-1;;;;31120:295:0:o;78576:814::-;39895:13;:11;:13::i;:::-;78772:15:::1;:34:::0;;;78817:9:::1;:22:::0;;;78850:15:::1;:34:::0;;;78895:17:::1;:38:::0;;;78915:18;78868:16;78973:40:::1;78829:10:::0;78790:16;78973:40:::1;:::i;:::-;:71;;;;:::i;:::-;:104;;;;:::i;:::-;78944:12;:133:::0;;;79092:13:::1;::::0;79123:2:::1;::::0;79092:28:::1;::::0;::::1;:::i;:::-;:33;79088:111;;;79147:52;::::0;-1:-1:-1;;;79147:52:0;;8835:2:1;79147:52:0::1;::::0;::::1;8817:21:1::0;;;8854:18;;;8847:30;8913:34;8893:18;;;8886:62;8965:18;;79147:52:0::1;8633:356:1::0;79088:111:0::1;79243:12;::::0;79270:15:::1;::::0;79300:9:::1;::::0;79324:15:::1;::::0;79354:17:::1;::::0;79215:167:::1;::::0;;9253:25:1;;;9309:2;9294:18;;9287:34;;;;9337:18;;;9330:34;;;;9395:2;9380:18;;9373:34;9438:3;9423:19;;9416:35;79215:167:0::1;::::0;9240:3:1;9225:19;79215:167:0::1;;;;;;;;78576:814:::0;;;;:::o;81510:313::-;39895:13;:11;:13::i;:::-;81643:3:::1;::::0;;-1:-1:-1;;;;;81657:24:0;;::::1;-1:-1:-1::0;;;;;;81657:24:0;::::1;::::0;::::1;::::0;;;81692:27:::1;::::0;:71:::1;::::0;-1:-1:-1;;;81692:71:0;;::::1;::::0;::::1;3871:51:1::0;;;;81643:3:0;;::::1;::::0;81692:27;::::1;::::0;:51:::1;::::0;3844:18:1;;81692:71:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;81811:3:0::1;::::0;81779:36:::1;::::0;-1:-1:-1;;;;;81811:3:0;;::::1;::::0;-1:-1:-1;81779:36:0;;::::1;::::0;-1:-1:-1;81779:36:0::1;::::0;81811:3:::1;::::0;81779:36:::1;81611:212;81510:313:::0;:::o;31824:238::-;31912:4;25708:10;31968:64;25708:10;31984:7;32021:10;31993:25;25708:10;31984:7;31993:9;:25::i;:::-;:38;;;;:::i;:::-;31968:8;:64::i;83481:195::-;83622:27;;:46;;-1:-1:-1;;;83622:46:0;;-1:-1:-1;;;;;3889:32:1;;;83622:46:0;;;3871:51:1;83590:7:0;;83622:27;;:37;;3844:18:1;;83622:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;82789:140::-;82880:27;;:41;;;-1:-1:-1;;;82880:41:0;;;;82853:7;;-1:-1:-1;;;;;82880:27:0;;:39;;:41;;;;;;;;;;;;;;:27;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;82873:48;;82789:140;:::o;75699:115::-;75736:27;;:70;;-1:-1:-1;;;75736:70:0;;75787:10;75736:70;;;9835:51:1;75736:27:0;9902:18:1;;;9895:50;-1:-1:-1;;;;;75736:27:0;;;;:42;;9808:18:1;;75736:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;75699:115::o;84064:382::-;84386:27;;:52;;-1:-1:-1;;;84386:52:0;;;;;2968:25:1;;;84192:7:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;84386:27:0;;;;:45;;2941:18:1;;84386:52:0;2822:177:1;80457:247:0;39895:13;:11;:13::i;:::-;80569:15:::1;::::0;;-1:-1:-1;;;;;80595:34:0;;::::1;-1:-1:-1::0;;;;;;80595:34:0;::::1;::::0;::::1;::::0;;;80645:51:::1;::::0;80569:15;::::1;::::0;80595:34;80569:15;;80645:51:::1;::::0;80548:18:::1;::::0;80645:51:::1;80537:167;80457:247:::0;:::o;75558:127::-;39895:13;:11;:13::i;:::-;75643:1:::1;75616:24;75634:4;75616:9;:24::i;:::-;:28;75613:57;;;75660:10;:8;:10::i;:::-;75558:127::o:0;81080:422::-;81262:27;;:40;;-1:-1:-1;;;;;;81262:40:0;;;;;2968:25:1;;;81160:18:0;;;;;;-1:-1:-1;;;;;81262:27:0;;:35;;2941:18:1;;81262:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81318:176;;;245:25:1;;;301:2;286:18;;279:34;;;329:18;;;322:34;;;387:2;372:18;;365:34;;;81145:157:0;;-1:-1:-1;81145:157:0;;-1:-1:-1;81145:157:0;-1:-1:-1;81474:9:0;;81436:5;;81318:176;;232:3:1;217:19;81318:176:0;;;;;;;81134:368;;;81080:422;:::o;29279:127::-;-1:-1:-1;;;;;29380:18:0;29353:7;29380:18;;;;;;;;;;;;29279:127::o;40657:103::-;39895:13;:11;:13::i;:::-;40722:30:::1;40749:1;40722:18;:30::i;82586:195::-:0;82720:27;;:53;;;-1:-1:-1;;;82720:53:0;;;;82688:7;;-1:-1:-1;;;;;82720:27:0;;:51;;:53;;;;;;;;;;;;;;:27;:53;;;;;;;;;;;;;;28207:104;28263:13;28296:7;28289:14;;;;;:::i;78346:222::-;39895:13;:11;:13::i;:::-;-1:-1:-1;;;;;78463:31:0;::::1;;::::0;;;:25:::1;:31;::::0;;;;;:40;;-1:-1:-1;;78463:40:0::1;::::0;::::1;;::::0;;::::1;::::0;;;78519:41;;78463:40;;:31;78519:41:::1;::::0;::::1;78346:222:::0;;:::o;82937:121::-;83011:27;;:39;;;-1:-1:-1;;;83011:39:0;;;;82984:7;;-1:-1:-1;;;;;83011:27:0;;:37;;:39;;;;;;;;;;;;;;:27;:39;;;;;;;;;;;;;;32565:436;32658:4;25708:10;32658:4;32741:25;25708:10;32758:7;32741:9;:25::i;:::-;32714:52;;32805:15;32785:16;:35;;32777:85;;;;-1:-1:-1;;;32777:85:0;;10719:2:1;32777:85:0;;;10701:21:1;10758:2;10738:18;;;10731:30;10797:34;10777:18;;;10770:62;-1:-1:-1;;;10848:18:1;;;10841:35;10893:19;;32777:85:0;10517:401:1;32777:85:0;32898:60;32907:5;32914:7;32942:15;32923:16;:34;32898:8;:60::i;81831:385::-;39895:13;:11;:13::i;:::-;81931:10:::1;81928:281;;;81957:27;::::0;:55:::1;::::0;-1:-1:-1;;;81957:55:0;;-1:-1:-1;;;;;3889:32:1;;;81957:55:0::1;::::0;::::1;3871:51:1::0;81957:27:0;;::::1;::::0;:46:::1;::::0;3844:18:1;;81957:55:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;82032:27:0::1;::::0;-1:-1:-1;;;;;82032:27:0;::::1;::::0;-1:-1:-1;82032:27:0::1;::::0;-1:-1:-1;82032:27:0;;::::1;81831:385:::0;;:::o;81928:281::-:1;82091:27;::::0;:57:::1;::::0;-1:-1:-1;;;82091:57:0;;-1:-1:-1;;;;;3889:32:1;;;82091:57:0::1;::::0;::::1;3871:51:1::0;82091:27:0;;::::1;::::0;:48:::1;::::0;3844:18:1;;82091:57:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;82168:29:0::1;::::0;-1:-1:-1;;;;;82168:29:0;::::1;::::0;-1:-1:-1;82168:29:0::1;::::0;-1:-1:-1;82168:29:0;;::::1;81831:385:::0;;:::o;29612:193::-;29691:4;25708:10;29747:28;25708:10;29764:2;29768:6;29747:9;:28::i;83066:194::-;83197:27;;:55;;;-1:-1:-1;;;83197:55:0;;;;83165:7;;-1:-1:-1;;;;;83197:27:0;;:53;;:55;;;;;;;;;;;;;;:27;:55;;;;;;;;;;;;;;78125:213;39895:13;:11;:13::i;:::-;-1:-1:-1;;;;;78237:28:0;::::1;;::::0;;;:19:::1;:28;::::0;;;;;;;;:41;;-1:-1:-1;;78237:41:0::1;::::0;::::1;;::::0;;::::1;::::0;;;78294:36;;2517:41:1;;;78294:36:0::1;::::0;2490:18:1;78294:36:0::1;;;;;;;;78125:213:::0;;:::o;77335:313::-;39895:13;:11;:13::i;:::-;77468:4:::1;77460;77439:13;29196:12:::0;;;29108:108;77439:13:::1;:17;::::0;77455:1:::1;77439:17;:::i;:::-;77438:26;;;;:::i;:::-;77437:35;;;;:::i;:::-;77422:12;:50;77418:170;;;77494:94;::::0;-1:-1:-1;;;77494:94:0;;11125:2:1;77494:94:0::1;::::0;::::1;11107:21:1::0;11164:2;11144:18;;;11137:30;11203:34;11183:18;;;11176:62;-1:-1:-1;;;11254:18:1;;;11247:34;11298:19;;77494:94:0::1;10923:400:1::0;77418:170:0::1;77617:23;:12:::0;77633:6:::1;77617:23;:::i;:::-;77599:15;:41:::0;-1:-1:-1;77335:313:0:o;83268:205::-;83406:27;;:59;;-1:-1:-1;;;83406:59:0;;-1:-1:-1;;;;;3889:32:1;;;83406:59:0;;;3871:51:1;83374:7:0;;83406:27;;:50;;3844:18:1;;83406:59:0;3725:203:1;80714:147:0;39895:13;:11;:13::i;:::-;80822:21:::1;:31:::0;;;::::1;;-1:-1:-1::0;;;80822:31:0::1;-1:-1:-1::0;;;;80822:31:0;;::::1;::::0;;;::::1;::::0;;80714:147::o;77892:225::-;39895:13;:11;:13::i;:::-;-1:-1:-1;;;;;78008:32:0;::::1;;::::0;;;:23:::1;:32;::::0;;;;;;;;:45;;-1:-1:-1;;78008:45:0::1;::::0;::::1;;::::0;;::::1;::::0;;;78069:40;;2517:41:1;;;78069:40:0::1;::::0;2490:18:1;78069:40:0::1;2377:187:1::0;76174:576:0;76285:4;39895:13;:11;:13::i;:::-;76348:6:::1;76327:13;29196:12:::0;;;29108:108;76327:13:::1;:17;::::0;76343:1:::1;76327:17;:::i;:::-;76326:28;;;;:::i;:::-;76311:12;:43;76307:180;;;76376:111;::::0;-1:-1:-1;;;76376:111:0;;11530:2:1;76376:111:0::1;::::0;::::1;11512:21:1::0;11569:2;11549:18;;;11542:30;11608:34;11588:18;;;11581:62;-1:-1:-1;;;11659:18:1;;;11652:51;11720:19;;76376:111:0::1;11328:417:1::0;76307:180:0::1;76535:4;76514:13;29196:12:::0;;;29108:108;76514:13:::1;:17;::::0;76530:1:::1;76514:17;:::i;:::-;76513:26;;;;:::i;:::-;76498:12;:41;76494:177;;;76561:110;::::0;-1:-1:-1;;;76561:110:0;;11952:2:1;76561:110:0::1;::::0;::::1;11934:21:1::0;11991:2;11971:18;;;11964:30;12030:34;12010:18;;;12003:62;-1:-1:-1;;;12081:18:1;;;12074:50;12141:19;;76561:110:0::1;11750:416:1::0;76494:177:0::1;-1:-1:-1::0;76682:23:0::1;:38:::0;76738:4:::1;::::0;76174:576::o;77656:228::-;39895:13;:11;:13::i;:::-;-1:-1:-1;;;;;77773:33:0;::::1;;::::0;;;:24:::1;:33;::::0;;;;;;;;:46;;-1:-1:-1;;77773:46:0::1;::::0;::::1;;::::0;;::::1;::::0;;;77835:41;;2517::1;;;77835::0::1;::::0;2490:18:1;77835:41:0::1;2377:187:1::0;29868:151:0;-1:-1:-1;;;;;29984:18:0;;;29957:7;29984:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;29868:151::o;82436:142::-;82519:27;;:51;;;-1:-1:-1;;;82519:51:0;;;;82492:7;;-1:-1:-1;;;;;82519:27:0;;:49;;:51;;;;;;;;;;;;;;:27;:51;;;;;;;;;;;;;;79398:837;39895:13;:11;:13::i;:::-;79599:16:::1;:36:::0;;;79646:10:::1;:24:::0;;;79681:16:::1;:36:::0;;;79728:18:::1;:40:::0;;;79749:19;79700:17;79808:42:::1;79659:11:::0;79618:17;79808:42:::1;:::i;:::-;:74;;;;:::i;:::-;:108;;;;:::i;:::-;79779:13;:137:::0;;;79947:12:::1;::::0;79962:2:::1;::::0;79931:28:::1;::::0;79947:12;79931:28:::1;:::i;:::-;:33;79927:111;;;79986:52;::::0;-1:-1:-1;;;79986:52:0;;8835:2:1;79986:52:0::1;::::0;::::1;8817:21:1::0;;;8854:18;;;8847:30;8913:34;8893:18;;;8886:62;8965:18;;79986:52:0::1;8633:356:1::0;79927:111:0::1;80083:13;::::0;80111:16:::1;::::0;80142:10:::1;::::0;80167:16:::1;::::0;80198:18:::1;::::0;80054:173:::1;::::0;;9253:25:1;;;9309:2;9294:18;;9287:34;;;;9337:18;;;9330:34;;;;9395:2;9380:18;;9373:34;9438:3;9423:19;;9416:35;80054:173:0::1;::::0;9240:3:1;9225:19;80054:173:0::1;8994:463:1::0;40915:201:0;39895:13;:11;:13::i;:::-;-1:-1:-1;;;;;41004:22:0;::::1;40996:73;;;::::0;-1:-1:-1;;;40996:73:0;;12373:2:1;40996:73:0::1;::::0;::::1;12355:21:1::0;12412:2;12392:18;;;12385:30;12451:34;12431:18;;;12424:62;-1:-1:-1;;;12502:18:1;;;12495:36;12548:19;;40996:73:0::1;12171:402:1::0;40996:73:0::1;41080:28;41099:8;41080:18;:28::i;36190:380::-:0;-1:-1:-1;;;;;36326:19:0;;36318:68;;;;-1:-1:-1;;;36318:68:0;;12780:2:1;36318:68:0;;;12762:21:1;12819:2;12799:18;;;12792:30;12858:34;12838:18;;;12831:62;-1:-1:-1;;;12909:18:1;;;12902:34;12953:19;;36318:68:0;12578:400:1;36318:68:0;-1:-1:-1;;;;;36405:21:0;;36397:68;;;;-1:-1:-1;;;36397:68:0;;13185:2:1;36397:68:0;;;13167:21:1;13224:2;13204:18;;;13197:30;13263:34;13243:18;;;13236:62;-1:-1:-1;;;13314:18:1;;;13307:32;13356:19;;36397:68:0;12983:398:1;36397:68:0;-1:-1:-1;;;;;36478:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;36530:32;;2968:25:1;;;36530:32:0;;2941:18:1;36530:32:0;;;;;;;36190:380;;;:::o;40174:132::-;40082:6;;-1:-1:-1;;;;;40082:6:0;25708:10;40238:23;40230:68;;;;-1:-1:-1;;;40230:68:0;;13588:2:1;40230:68:0;;;13570:21:1;;;13607:18;;;13600:30;13666:34;13646:18;;;13639:62;13718:18;;40230:68:0;13386:356:1;36861:453:0;36996:24;37023:25;37033:5;37040:7;37023:9;:25::i;:::-;36996:52;;-1:-1:-1;;37063:16:0;:37;37059:248;;37145:6;37125:16;:26;;37117:68;;;;-1:-1:-1;;;37117:68:0;;13949:2:1;37117:68:0;;;13931:21:1;13988:2;13968:18;;;13961:30;14027:31;14007:18;;;14000:59;14076:18;;37117:68:0;13747:353:1;37117:68:0;37229:51;37238:5;37245:7;37273:6;37254:16;:25;37229:8;:51::i;:::-;36985:329;36861:453;;;:::o;67149:4025::-;67345:22;67411:23;;67370:24;67388:4;67370:9;:24::i;:::-;67454:10;;-1:-1:-1;;67370:64:0;;-1:-1:-1;;;;67454:10:0;;;;67449:2732;;-1:-1:-1;;;;;67523:31:0;;;;;;:25;:31;;;;;;;;67519:2651;;;-1:-1:-1;;;;;67617:27:0;;;;;;:23;:27;;;;;;;;67612:213;;67715:14;;67706:6;:23;67702:103;;;67763:42;;-1:-1:-1;;;67763:42:0;;14307:2:1;67763:42:0;;;14289:21:1;14346:2;14326:18;;;14319:30;-1:-1:-1;;;14365:18:1;;;14358:55;14430:18;;67763:42:0;14105:349:1;67702:103:0;-1:-1:-1;;;;;67850:28:0;;;;;;:24;:28;;;;;;;;67845:235;;67969:15;;67960:6;67944:13;67954:2;67944:9;:13::i;:::-;:22;;;;:::i;:::-;:40;67940:120;;;68018:42;;-1:-1:-1;;;68018:42:0;;14307:2:1;68018:42:0;;;14289:21:1;14346:2;14326:18;;;14319:30;-1:-1:-1;;;14365:18:1;;;14358:55;14430:18;;68018:42:0;14105:349:1;67940:120:0;68154:1;68139:12;;:16;:44;;;;-1:-1:-1;;;;;;68160:23:0;;;;;;:19;:23;;;;;;;;68159:24;68139:44;68135:731;;;68208:14;68251:3;68235:12;;68226:6;:21;;;;:::i;:::-;68225:29;;;;:::i;:::-;68208:46;-1:-1:-1;68277:16:0;68208:46;68277:16;;:::i;:::-;;;68417:12;;68373:15;;68364:6;:24;;;;:::i;:::-;68363:66;;;;:::i;:::-;68316:18;;:113;;;;;;;:::i;:::-;;;;-1:-1:-1;;68491:12:0;;68478:9;;68469:18;;:6;:18;:::i;:::-;68468:35;;;;:::i;:::-;68452:12;;:51;;;;;;;:::i;:::-;;;;-1:-1:-1;;68627:12:0;;68583:15;;68574:24;;:6;:24;:::i;:::-;68573:66;;;;:::i;:::-;68526:18;;:113;;;;;;;:::i;:::-;;;;-1:-1:-1;;68767:12:0;;68721:17;;68712:26;;:6;:26;:::i;:::-;68711:68;;;;:::i;:::-;68662:20;;:117;;;;;;;:::i;:::-;;;;-1:-1:-1;68802:44:0;;-1:-1:-1;68818:4:0;68832;68839:6;68802:15;:44::i;:::-;68185:681;68135:731;67519:2651;;;-1:-1:-1;;;;;68891:29:0;;;;;;:25;:29;;;;;;;;68887:1283;;;69003:21;;-1:-1:-1;;;69003:21:0;;;;:63;;;;;69065:1;69049:13;;:17;69003:63;:105;;;;;69091:17;69003:105;68977:161;;;69128:10;:8;:10::i;:::-;-1:-1:-1;;;;;69167:29:0;;;;;;:23;:29;;;;;;;;69162:184;;69234:15;;69225:6;:24;69221:105;;;69283:43;;-1:-1:-1;;;69283:43:0;;14794:2:1;69283:43:0;;;14776:21:1;14833:2;14813:18;;;14806:30;14872:28;14852:18;;;14845:56;14918:18;;69283:43:0;14592:350:1;69221:105:0;69490:1;69474:13;;:17;:47;;;;-1:-1:-1;;;;;;69496:25:0;;;;;;:19;:25;;;;;;;;69495:26;69474:47;69470:689;;;69542:14;69586:3;69569:13;;69560:6;:22;;;;:::i;:::-;69559:30;;;;:::i;:::-;69542:47;-1:-1:-1;69608:16:0;69542:47;69608:16;;:::i;:::-;;;69737:13;;69696:16;;69687:6;:25;;;;:::i;:::-;69686:64;;;;:::i;:::-;69643:18;;:107;;;;;;;:::i;:::-;;;;-1:-1:-1;;69809:13:0;;69795:10;;69786:19;;:6;:19;:::i;:::-;69785:37;;;;:::i;:::-;69769:12;;:53;;;;;;;:::i;:::-;;;;-1:-1:-1;;69935:13:0;;69894:16;;69885:25;;:6;:25;:::i;:::-;69884:64;;;;:::i;:::-;69841:18;;:107;;;;;;;:::i;:::-;;;;-1:-1:-1;;70065:13:0;;70022:18;;70013:27;;:6;:27;:::i;:::-;70012:66;;;;:::i;:::-;69967:20;;:111;;;;;;;:::i;:::-;;;;-1:-1:-1;70099:44:0;;-1:-1:-1;70115:4:0;70129;70136:6;70099:15;:44::i;:::-;69523:636;69470:689;70236:33;70252:4;70258:2;70262:6;70236:15;:33::i;:::-;70324:27;;-1:-1:-1;;;;;70324:27:0;:38;70371:4;70378:15;70371:4;70378:9;:15::i;:::-;70324:70;;-1:-1:-1;;;;;;70324:70:0;;;;;;;-1:-1:-1;;;;;15155:32:1;;;70324:70:0;;;15137:51:1;15204:18;;;15197:34;15110:18;;70324:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70307:108;70442:27;;-1:-1:-1;;;;;70442:27:0;:38;70489:2;70494:13;70489:2;70494:9;:13::i;:::-;70442:66;;-1:-1:-1;;;;;;70442:66:0;;;;;;;-1:-1:-1;;;;;15155:32:1;;;70442:66:0;;;15137:51:1;15204:18;;;15197:34;15110:18;;70442:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70425:104;70593:10;;-1:-1:-1;;;70593:10:0;;;;70592:11;:36;;;;-1:-1:-1;70607:21:0;;-1:-1:-1;;;70607:21:0;;;;70592:36;70588:579;;;70659:16;;70696:27;;:40;;-1:-1:-1;;;;;;70696:40:0;;;;;2968:25:1;;;-1:-1:-1;;;;;70696:27:0;;;;:35;;2941:18:1;;70696:40:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;70696:40:0;;;;;;;;-1:-1:-1;;70696:40:0;;;;;;;;;;;;:::i;:::-;;;70692:464;;;70900:231;;;245:25:1;;;301:2;286:18;;279:34;;;329:18;;;322:34;;;387:2;372:18;;365:34;;;71103:9:0;;71050:4;;70900:231;;232:3:1;217:19;70900:231:0;;;;;;;70737:410;;;70692:464;70630:537;67262:3912;67149:4025;;;:::o;72780:2766::-;72819:10;:17;;-1:-1:-1;;;;72819:17:0;-1:-1:-1;;;72819:17:0;;;;72874:24;72892:4;72874:9;:24::i;:::-;72848:50;;72911:19;73029:20;;72995:18;;72961;;72933:12;;:46;;;;:::i;:::-;:80;;;;:::i;:::-;:116;;;;:::i;:::-;72911:138;-1:-1:-1;73074:12:0;;73131:20;;;:40;;-1:-1:-1;73155:16:0;;73131:40;73127:79;;;73188:7;;;;72780:2766::o;73127:79::-;73235:23;;73221:11;:37;73218:213;;;-1:-1:-1;73339:23:0;;73218:213;;;-1:-1:-1;73408:11:0;73218:213;73502:23;73605:1;73578:11;73543:18;;73529:11;:32;;;;:::i;:::-;73528:61;;;;:::i;:::-;:78;;;;:::i;:::-;73502:104;-1:-1:-1;73617:26:0;73646:29;73502:104;73646:11;:29;:::i;:::-;73617:58;-1:-1:-1;73716:21:0;73750:36;73617:58;73750:16;:36::i;:::-;73799:18;73820:41;73844:17;73820:21;:41;:::i;:::-;73799:62;;73874:17;73924:11;73908:12;;73895:10;:25;;;;:::i;:::-;73894:41;;;;:::i;:::-;73874:61;;73948:23;74023:11;73988:18;;73975:10;:31;;;;:::i;:::-;73974:60;;;;:::i;:::-;73948:86;;74047:25;74126:11;74089:20;;74076:10;:33;;;;:::i;:::-;74075:62;;;;:::i;:::-;74172:9;;74164:45;;74047:90;;-1:-1:-1;;;;;;74172:9:0;;74195;;74164:45;;;;74195:9;74172;74164:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;74150:59:0;;-1:-1:-1;;74226:19:0;;;;;:42;;;74267:1;74249:15;:19;74226:42;74222:278;;;74285:46;74298:15;74315;74285:12;:46::i;:::-;74455:18;;74351:137;;;15654:25:1;;;15710:2;15695:18;;15688:34;;;15738:18;;;15731:34;;;;74351:137:0;;;;;;15642:2:1;74351:137:0;;;74222:278;74512:32;74526:17;74512:13;:32::i;:::-;74587:3;;74580:36;;-1:-1:-1;;;74580:36:0;;74610:4;74580:36;;;3871:51:1;74557:20:0;;-1:-1:-1;;;;;74587:3:0;;74580:21;;3844:18:1;;74580:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74644:3;;74680:27;;74637:109;;-1:-1:-1;;;74637:109:0;;-1:-1:-1;;;;;74680:27:0;;;74637:109;;;15137:51:1;15204:18;;;15197:34;;;74557:59:0;;-1:-1:-1;74644:3:0;;74637:20;;15110:18:1;;74637:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74627:119;;74763:7;74759:172;;;74787:27;;:66;;-1:-1:-1;;;74787:66:0;;;;;2968:25:1;;;-1:-1:-1;;;;;74787:27:0;;;;:52;;2941:18:1;;74787:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;74873:46:0;;;16229:25:1;;;16285:2;16270:18;;16263:34;;;74873:46:0;;-1:-1:-1;16202:18:1;;-1:-1:-1;74873:46:0;;;;;;;74759:172;74965:15;;74957:87;;-1:-1:-1;;;;;74965:15:0;;;;75008:21;;74957:87;;;;75008:21;74965:15;74957:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74943:101;;;;;75075:24;75093:4;75075:9;:24::i;:::-;75057:42;;75198:13;;75165:16;;75147:15;:34;;;;:::i;:::-;75146:65;;;;:::i;:::-;75112:18;:99;75308:13;;75275:16;;75257:34;;:15;:34;:::i;:::-;75256:65;;;;:::i;:::-;75222:18;:99;75380:13;;75366:10;;75348:28;;:15;:28;:::i;:::-;75347:46;;;;:::i;:::-;75332:12;:61;75494:13;;75459:18;;75441:36;;:15;:36;:::i;:::-;75440:67;;;;:::i;:::-;75404:20;:103;-1:-1:-1;;75520:10:0;:18;;-1:-1:-1;;;;75520:18:0;;;-1:-1:-1;;;;;;;;;;72780:2766:0:o;41276:191::-;41369:6;;;-1:-1:-1;;;;;41386:17:0;;;-1:-1:-1;;;;;;41386:17:0;;;;;;;41419:40;;41369:6;;;41386:17;41369:6;;41419:40;;41350:16;;41419:40;41339:128;41276:191;:::o;33471:671::-;-1:-1:-1;;;;;33602:18:0;;33594:68;;;;-1:-1:-1;;;33594:68:0;;16510:2:1;33594:68:0;;;16492:21:1;16549:2;16529:18;;;16522:30;16588:34;16568:18;;;16561:62;-1:-1:-1;;;16639:18:1;;;16632:35;16684:19;;33594:68:0;16308:401:1;33594:68:0;-1:-1:-1;;;;;33681:16:0;;33673:64;;;;-1:-1:-1;;;33673:64:0;;16916:2:1;33673:64:0;;;16898:21:1;16955:2;16935:18;;;16928:30;16994:34;16974:18;;;16967:62;-1:-1:-1;;;17045:18:1;;;17038:33;17088:19;;33673:64:0;16714:399:1;33673:64:0;-1:-1:-1;;;;;33823:15:0;;33801:19;33823:15;;;;;;;;;;;33857:21;;;;33849:72;;;;-1:-1:-1;;;33849:72:0;;17320:2:1;33849:72:0;;;17302:21:1;17359:2;17339:18;;;17332:30;17398:34;17378:18;;;17371:62;-1:-1:-1;;;17449:18:1;;;17442:36;17495:19;;33849:72:0;17118:402:1;33849:72:0;-1:-1:-1;;;;;33957:15:0;;;:9;:15;;;;;;;;;;;33975:20;;;33957:38;;34017:13;;;;;;;;:23;;33989:6;;33957:9;34017:23;;33989:6;;34017:23;:::i;:::-;;;;;;;;34073:2;-1:-1:-1;;;;;34058:26:0;34067:4;-1:-1:-1;;;;;34058:26:0;;34077:6;34058:26;;;;2968:25:1;;2956:2;2941:18;;2822:177;34058:26:0;;;;;;;;34097:37;37914:125;71184:589;71334:16;;;71348:1;71334:16;;;;;;;;71310:21;;71334:16;;;;;;;;;;-1:-1:-1;71334:16:0;71310:40;;71379:4;71361;71366:1;71361:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;71361:23:0;;;:7;;;;;;;;;;:23;;;;71405:15;;:22;;;-1:-1:-1;;;71405:22:0;;;;:15;;;;;:20;;:22;;;;;71361:7;;71405:22;;;;;:15;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71395:4;71400:1;71395:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;71395:32:0;;;:7;;;;;;;;;:32;71472:15;;71440:62;;71457:4;;71472:15;71490:11;71440:8;:62::i;:::-;71541:15;;:224;;-1:-1:-1;;;71541:224:0;;-1:-1:-1;;;;;71541:15:0;;;;:66;;:224;;71622:11;;71541:15;;71692:4;;71719;;71739:15;;71541:224;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71239:534;71184:589;:::o;71781:517::-;71961:15;;71929:62;;71946:4;;-1:-1:-1;;;;;71961:15:0;71979:11;71929:8;:62::i;:::-;72034:15;;:256;;-1:-1:-1;;;72034:256:0;;72106:4;72034:256;;;19439:34:1;19489:18;;;19482:34;;;72034:15:0;19532:18:1;;;19525:34;;;19575:18;;;19568:34;60370:6:0;19618:19:1;;;19611:44;72264:15:0;19671:19:1;;;19664:35;-1:-1:-1;;;;;72034:15:0;;;;:31;;72073:9;;19373:19:1;;72034:256:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;72306:466::-;72372:13;;72369:396;;72425:16;;;72439:1;72425:16;;;;;;;;72401:21;;72425:16;;;;;;;;-1:-1:-1;;72466:15:0;;:22;;;-1:-1:-1;;;72466:22:0;;;;72401:40;;-1:-1:-1;;;;;;72466:15:0;;;;:20;;-1:-1:-1;72466:22:0;;;;;;;;;;;;;;:15;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72456:4;72461:1;72456:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;72456:32:0;;;:7;;;;;;;;;:32;72513:3;;72503:7;;72513:3;;;72503:4;;72513:3;;72503:7;;;;;;:::i;:::-;-1:-1:-1;;;;;72503:13:0;;;:7;;;;;;;;;:13;72545:15;;:208;;-1:-1:-1;;;72545:208:0;;:15;;;:66;;72619:9;;72545:208;;:15;;72668:4;;72699;;72723:15;;72545:208;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72386:379;72306:466;:::o;410:548:1:-;522:4;551:2;580;569:9;562:21;612:6;606:13;655:6;650:2;639:9;635:18;628:34;680:1;690:140;704:6;701:1;698:13;690:140;;;799:14;;;795:23;;789:30;765:17;;;784:2;761:26;754:66;719:10;;690:140;;;694:3;879:1;874:2;865:6;854:9;850:22;846:31;839:42;949:2;942;938:7;933:2;925:6;921:15;917:29;906:9;902:45;898:54;890:62;;;;410:548;;;;:::o;963:131::-;-1:-1:-1;;;;;1038:31:1;;1028:42;;1018:70;;1084:1;1081;1074:12;1099:247;1158:6;1211:2;1199:9;1190:7;1186:23;1182:32;1179:52;;;1227:1;1224;1217:12;1179:52;1266:9;1253:23;1285:31;1310:5;1285:31;:::i;:::-;1335:5;1099:247;-1:-1:-1;;;1099:247:1:o;2057:315::-;2125:6;2133;2186:2;2174:9;2165:7;2161:23;2157:32;2154:52;;;2202:1;2199;2192:12;2154:52;2241:9;2228:23;2260:31;2285:5;2260:31;:::i;:::-;2310:5;2362:2;2347:18;;;;2334:32;;-1:-1:-1;;;2057:315:1:o;2569:248::-;2637:6;2645;2698:2;2686:9;2677:7;2673:23;2669:32;2666:52;;;2714:1;2711;2704:12;2666:52;-1:-1:-1;;2737:23:1;;;2807:2;2792:18;;;2779:32;;-1:-1:-1;2569:248:1:o;3264:456::-;3341:6;3349;3357;3410:2;3398:9;3389:7;3385:23;3381:32;3378:52;;;3426:1;3423;3416:12;3378:52;3465:9;3452:23;3484:31;3509:5;3484:31;:::i;:::-;3534:5;-1:-1:-1;3591:2:1;3576:18;;3563:32;3604:33;3563:32;3604:33;:::i;:::-;3264:456;;3656:7;;-1:-1:-1;;;3710:2:1;3695:18;;;;3682:32;;3264:456::o;3933:385::-;4019:6;4027;4035;4043;4096:3;4084:9;4075:7;4071:23;4067:33;4064:53;;;4113:1;4110;4103:12;4064:53;-1:-1:-1;;4136:23:1;;;4206:2;4191:18;;4178:32;;-1:-1:-1;4257:2:1;4242:18;;4229:32;;4308:2;4293:18;4280:32;;-1:-1:-1;3933:385:1;-1:-1:-1;3933:385:1:o;4512:180::-;4571:6;4624:2;4612:9;4603:7;4599:23;4595:32;4592:52;;;4640:1;4637;4630:12;4592:52;-1:-1:-1;4663:23:1;;4512:180;-1:-1:-1;4512:180:1:o;4697:118::-;4783:5;4776:13;4769:21;4762:5;4759:32;4749:60;;4805:1;4802;4795:12;4820:382;4885:6;4893;4946:2;4934:9;4925:7;4921:23;4917:32;4914:52;;;4962:1;4959;4952:12;4914:52;5001:9;4988:23;5020:31;5045:5;5020:31;:::i;:::-;5070:5;-1:-1:-1;5127:2:1;5112:18;;5099:32;5140:30;5099:32;5140:30;:::i;:::-;5189:7;5179:17;;;4820:382;;;;;:::o;5459:241::-;5515:6;5568:2;5556:9;5547:7;5543:23;5539:32;5536:52;;;5584:1;5581;5574:12;5536:52;5623:9;5610:23;5642:28;5664:5;5642:28;:::i;5705:388::-;5773:6;5781;5834:2;5822:9;5813:7;5809:23;5805:32;5802:52;;;5850:1;5847;5840:12;5802:52;5889:9;5876:23;5908:31;5933:5;5908:31;:::i;:::-;5958:5;-1:-1:-1;6015:2:1;6000:18;;5987:32;6028:33;5987:32;6028:33;:::i;6098:380::-;6177:1;6173:12;;;;6220;;;6241:61;;6295:4;6287:6;6283:17;6273:27;;6241:61;6348:2;6340:6;6337:14;6317:18;6314:38;6311:161;;6394:10;6389:3;6385:20;6382:1;6375:31;6429:4;6426:1;6419:15;6457:4;6454:1;6447:15;6311:161;;6098:380;;;:::o;6483:681::-;6614:6;6622;6630;6638;6646;6654;6662;6670;6723:3;6711:9;6702:7;6698:23;6694:33;6691:53;;;6740:1;6737;6730:12;6691:53;6772:9;6766:16;6791:31;6816:5;6791:31;:::i;:::-;6841:5;6831:15;;;6886:2;6875:9;6871:18;6865:25;6855:35;;6930:2;6919:9;6915:18;6909:25;6899:35;;6974:2;6963:9;6959:18;6953:25;6943:35;;7018:3;7007:9;7003:19;6997:26;6987:36;;7063:3;7052:9;7048:19;7042:26;7032:36;;7108:3;7097:9;7093:19;7087:26;7077:36;;7153:3;7142:9;7138:19;7132:26;7122:36;;6483:681;;;;;;;;;;;:::o;7169:127::-;7230:10;7225:3;7221:20;7218:1;7211:31;7261:4;7258:1;7251:15;7285:4;7282:1;7275:15;7301:168;7374:9;;;7405;;7422:15;;;7416:22;;7402:37;7392:71;;7443:18;;:::i;7474:217::-;7514:1;7540;7530:132;;7584:10;7579:3;7575:20;7572:1;7565:31;7619:4;7616:1;7609:15;7647:4;7644:1;7637:15;7530:132;-1:-1:-1;7676:9:1;;7474:217::o;8503:125::-;8568:9;;;8589:10;;;8586:36;;;8602:18;;:::i;9462:184::-;9532:6;9585:2;9573:9;9564:7;9560:23;9556:32;9553:52;;;9601:1;9598;9591:12;9553:52;-1:-1:-1;9624:16:1;;9462:184;-1:-1:-1;9462:184:1:o;9956:245::-;10023:6;10076:2;10064:9;10055:7;10051:23;10047:32;10044:52;;;10092:1;10089;10082:12;10044:52;10124:9;10118:16;10143:28;10165:5;10143:28;:::i;10206:306::-;10294:6;10302;10310;10363:2;10351:9;10342:7;10338:23;10334:32;10331:52;;;10379:1;10376;10369:12;10331:52;10408:9;10402:16;10392:26;;10458:2;10447:9;10443:18;10437:25;10427:35;;10502:2;10491:9;10487:18;10481:25;10471:35;;10206:306;;;;;:::o;14459:128::-;14526:9;;;14547:11;;;14544:37;;;14561:18;;:::i;17657:127::-;17718:10;17713:3;17709:20;17706:1;17699:31;17749:4;17746:1;17739:15;17773:4;17770:1;17763:15;17789:251;17859:6;17912:2;17900:9;17891:7;17887:23;17883:32;17880:52;;;17928:1;17925;17918:12;17880:52;17960:9;17954:16;17979:31;18004:5;17979:31;:::i;18045:461::-;18098:3;18136:5;18130:12;18163:6;18158:3;18151:19;18189:4;18218:2;18213:3;18209:12;18202:19;;18255:2;18248:5;18244:14;18276:1;18286:195;18300:6;18297:1;18294:13;18286:195;;;18365:13;;-1:-1:-1;;;;;18361:39:1;18349:52;;18421:12;;;;18456:15;;;;18397:1;18315:9;18286:195;;;-1:-1:-1;18497:3:1;;18045:461;-1:-1:-1;;;;;18045:461:1:o;18511:582::-;18810:6;18799:9;18792:25;18853:6;18848:2;18837:9;18833:18;18826:34;18896:3;18891:2;18880:9;18876:18;18869:31;18773:4;18917:57;18969:3;18958:9;18954:19;18946:6;18917:57;:::i;:::-;-1:-1:-1;;;;;19010:32:1;;;;19005:2;18990:18;;18983:60;-1:-1:-1;19074:3:1;19059:19;19052:35;18909:65;18511:582;-1:-1:-1;;;18511:582:1:o;19710:510::-;19981:6;19970:9;19963:25;20024:3;20019:2;20008:9;20004:18;19997:31;19944:4;20045:57;20097:3;20086:9;20082:19;20074:6;20045:57;:::i;:::-;-1:-1:-1;;;;;20138:32:1;;;;20133:2;20118:18;;20111:60;-1:-1:-1;20202:2:1;20187:18;20180:34;20037:65;19710:510;-1:-1:-1;;19710:510:1:o

Swarm Source

ipfs://333a0404539fae773bf87405e35ce1660028709a787246db57465d0f3827dc6a
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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