ETH Price: $3,781.94 (+6.43%)

Token

ERC-20: ProofOfSteak (MOO)
 

Overview

Max Total Supply

1,000,000 MOO

Holders

82

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Filtered by Token Holder
subharmonic.eth
Balance
5,713.927303995400495866 MOO

Value
$0.00
0x0cBB58Cc03ee691E80BeF4B0c7A4dF2F505448F5
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:
PROOFOFSTEAK

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-05-04
*/

// proofofsteak.farm
// Introducing the first token with a dynamic stake tax. Say goodbye to rotatooors, say hello to $MOO

// SPDX-License-Identifier: Unlicensed

pragma solidity ^0.8.19;

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

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

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

contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) internal _balances;

    mapping(address => mapping(address => uint256)) internal _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;
            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
            // decrementing then incrementing.
            _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;
        unchecked {
            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
            _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;
            // Overflow not possible: amount <= accountBalance <= totalSupply.
            _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 {}
}

/**
 * @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 public _owner;

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

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

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

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

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

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

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

interface IUniswapV2Router01 {
    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 removeLiquidity(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB);

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

    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETHWithPermit(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountToken, uint256 amountETH);

    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapTokensForExactTokens(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactETHForTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function swapTokensForExactETH(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactTokensForETH(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapETHForExactTokens(
        uint256 amountOut,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function quote(
        uint256 amountA,
        uint256 reserveA,
        uint256 reserveB
    ) external pure returns (uint256 amountB);

    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut
    ) external pure returns (uint256 amountOut);

    function getAmountIn(
        uint256 amountOut,
        uint256 reserveIn,
        uint256 reserveOut
    ) external pure returns (uint256 amountIn);

    function getAmountsOut(
        uint256 amountIn,
        address[] calldata path
    ) external view returns (uint256[] memory amounts);

    function getAmountsIn(
        uint256 amountOut,
        address[] calldata path
    ) external view returns (uint256[] memory amounts);
}

interface IUniswapV2Router02 is IUniswapV2Router01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountETH);

    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountETH);

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

interface IUniswapV2Factory {
    event PairCreated(
        address indexed token0,
        address indexed token1,
        address pair,
        uint256
    );

    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(uint256) external view returns (address pair);

    function allPairsLength() external view returns (uint256);

    function createPair(
        address tokenA,
        address tokenB
    ) external returns (address pair);

    function setFeeTo(address) external;

    function setFeeToSetter(address) external;
}

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SignedSafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SignedSafeMath {
    /**
     * @dev Returns the multiplication of two signed integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(int256 a, int256 b) internal pure returns (int256) {
        return a * b;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. 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;
        }
    }
}

/**
 * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */
library SafeCast {
    /**
     * @dev Returns the downcasted uint224 from uint256, reverting on
     * overflow (when the input is greater than largest uint224).
     *
     * Counterpart to Solidity's `uint224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        require(
            value <= type(uint224).max,
            "SafeCast: value doesn't fit in 224 bits"
        );
        return uint224(value);
    }

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        require(
            value <= type(uint128).max,
            "SafeCast: value doesn't fit in 128 bits"
        );
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint96 from uint256, reverting on
     * overflow (when the input is greater than largest uint96).
     *
     * Counterpart to Solidity's `uint96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        require(
            value <= type(uint96).max,
            "SafeCast: value doesn't fit in 96 bits"
        );
        return uint96(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        require(
            value <= type(uint64).max,
            "SafeCast: value doesn't fit in 64 bits"
        );
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        require(
            value <= type(uint32).max,
            "SafeCast: value doesn't fit in 32 bits"
        );
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        require(
            value <= type(uint16).max,
            "SafeCast: value doesn't fit in 16 bits"
        );
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        require(
            value <= type(uint8).max,
            "SafeCast: value doesn't fit in 8 bits"
        );
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v3.1._
     */
    function toInt128(int256 value) internal pure returns (int128) {
        require(
            value >= type(int128).min && value <= type(int128).max,
            "SafeCast: value doesn't fit in 128 bits"
        );
        return int128(value);
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v3.1._
     */
    function toInt64(int256 value) internal pure returns (int64) {
        require(
            value >= type(int64).min && value <= type(int64).max,
            "SafeCast: value doesn't fit in 64 bits"
        );
        return int64(value);
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v3.1._
     */
    function toInt32(int256 value) internal pure returns (int32) {
        require(
            value >= type(int32).min && value <= type(int32).max,
            "SafeCast: value doesn't fit in 32 bits"
        );
        return int32(value);
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v3.1._
     */
    function toInt16(int256 value) internal pure returns (int16) {
        require(
            value >= type(int16).min && value <= type(int16).max,
            "SafeCast: value doesn't fit in 16 bits"
        );
        return int16(value);
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     *
     * _Available since v3.1._
     */
    function toInt8(int256 value) internal pure returns (int8) {
        require(
            value >= type(int8).min && value <= type(int8).max,
            "SafeCast: value doesn't fit in 8 bits"
        );
        return int8(value);
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
        require(
            value <= uint256(type(int256).max),
            "SafeCast: value doesn't fit in an int256"
        );
        return int256(value);
    }
}

interface CustomIERC20 {
    function changeUserSellTax(
        address _user,
        uint256 _sellTaxPercentage
    ) external;

    function checkUserTax(address _user) external view returns (uint256 tax);

    function shouldSwap() external view returns (uint256 swapAtAmount);

    function swapAndLiquify(uint256 contractTokenBalance) external;

    function triggerSwapAndLiquify(uint256 contractTokenBalance) external;
}

contract PROOFOFSTEAK is ERC20, Ownable, CustomIERC20 {
    using SafeMath for uint256;

    IUniswapV2Router02 private uniswapV2Router;
    address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    address public immutable uniswapV2Pair;
    // ***changed max sell and buy for testing
    uint256 public maxSellTransactionAmount = 10000 * (10 ** 18);
    uint256 public maxBuyTransactionAmount = 10000 * (10 ** 18);
    uint256 public swapTokensAtAmount = 1000 * (10 ** 18);
    uint256 public maxWalletToken = 20000 * (10 ** 18);
    uint256 public buyTax = 15;

    // distribute the collected tax percentage wise
    uint256 public liquidityPercent = 50; // 50% of total collected tax
    uint256 public marketingPercent = 50;

    address public stakingContract;
    address payable public marketingWallet =
        payable(0x0FaC4150B2bD8f2576a5648Bc289f5D713F4db59);
    bool public inSwapAndLiquify;
    // **** couldn't add liquidity with this on, so I set it to false on contract creation
    bool public swapAndLiquifyEnabled;
    // store addresses that a automatic market maker pairs. Any transfer *to* these addresses
    // could be subject to a maximum transfer amount
    mapping(address => bool) public whitelistedLpPair;
    mapping(address => bool) public isWhitelisted; //new
    mapping(address => bool) public excludedFromMaxWallet;
    mapping(address => uint256) public userSellTaxPercentage;

    string private error_sameValue = "Already set value";
    string private error_restrictedAccess = "Restricted access";
    event UpdateUniswapV2Router(
        address indexed newAddress,
        address indexed oldAddress
    );
    event EmergencyWithdrawal(
        address[] tokenType,
        uint256[] amount,
        uint256 timestamp
    );
    event SwapAndLiquifyEnabledUpdated(bool enabled);
    event SwapAndLiquify(uint256 tokensIntoLiqudity, uint256 ethReceived);
    // ** new events
    event Whitelisted(address target, bool value);
    event LpPairStatusChange(address target, bool value);
    event ExcludedFromMaxWalletAndTx(address target, bool value);
    event UserSellTaxChange(address target, uint256 amount);
    event StakingAddressChange(address target);
    event SwapAndLiquifyRateChange(uint256 amount);
    event BuyTaxChange(uint256 buyTax);
    event AntiwhaleSettingsChange(
        uint256 maxSell,
        uint256 maxBuy,
        uint256 maxWallet
    );
    modifier lockTheSwap() {
        inSwapAndLiquify = true;
        _;
        inSwapAndLiquify = false;
    }

    constructor() ERC20("ProofOfSteak", "MOO") {
        _mint(owner(), 1000000 * (10 ** 18));

        // Create a uniswap pair for this new token
        address router = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
        IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(router);
        address _uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
            .createPair(address(this), WETH);

        uniswapV2Router = _uniswapV2Router;
        uniswapV2Pair = _uniswapV2Pair;
        changeLpPairStatus(_uniswapV2Pair, true);
        addressWhitelistStatus(address(this), true);
        maxWalletExclusionStatus(address(this), true);
        maxWalletExclusionStatus(marketingWallet, true);
        maxWalletExclusionStatus(_msgSender(), true);
        maxWalletExclusionStatus(router, true);
        _allowances[address(this)][router] = type(uint256).max;
    }

    receive() external payable {}

    function _approveSL(
        address owner,
        address spender,
        uint256 amount
    ) internal {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");
        _allowances[owner][spender] = amount;

        uint256 contractTokenBalance = balanceOf(address(this));
        uint256 tokensToSwap = swapTokensAtAmount;
        bool overMinTokenBalance = contractTokenBalance >= tokensToSwap;
        if (overMinTokenBalance && !inSwapAndLiquify && swapAndLiquifyEnabled) {
            swapAndLiquify(tokensToSwap);
        }
        emit Approval(owner, spender, amount);
    }

     function approve(
        address spender,
        uint256 amount
    ) public override returns (bool) {
        address owner = _msgSender();
        //uses a separate approve function because overriding ERC20 _approve() includes S&L into transferFrom()
        _approveSL(owner, spender, amount);
        return true;
    }

    //set which LP pairs the max sell/buy limit, buy tax and dynamic sell tax will operate on
    function changeLpPairStatus(
        address _address,
        bool _value
    ) public onlyOwner {
        require(whitelistedLpPair[_address] != _value, error_sameValue);
        whitelistedLpPair[_address] = _value;
        maxWalletExclusionStatus(_address, _value);
        emit LpPairStatusChange(_address, _value);
    }

    //this is used to exclude users from swap taxes, max sell/buy amount and paying for swap&liquify function gas (recommend whitelisting all connected project contracts)
    function addressWhitelistStatus(address _address, bool _value) public {
        require(
            msg.sender == owner() || msg.sender == address(this),
            error_restrictedAccess
        );
        require(isWhitelisted[_address] != _value, error_sameValue);
        isWhitelisted[_address] = _value;
        emit Whitelisted(_address, _value);
    }

    //excludes address from max wallet limit, on transfer it applies only to receiver address, regardless of sender status
    function maxWalletExclusionStatus(address _target, bool _value) public {
        require(
            msg.sender == address(this) || msg.sender == owner(),
            error_restrictedAccess
        );
        require(excludedFromMaxWallet[_target] != _value, error_sameValue);
        excludedFromMaxWallet[_target] = _value;
        emit ExcludedFromMaxWalletAndTx(_target, _value);
    }

    //currently only called by staking contract, from stake() function,
    //only if user's taxes are not already the same or lower than new proposed tax
    //for security allows change only between values 0, 1, 3, 6, 10, zero is mapping default value for all users so it represents 15% tax
    function changeUserSellTax(
        address _user,
        uint256 _sellTaxPercentage
    ) external override {
        require(
            //msg.sender == address(this) ||
            //msg.sender == owner() ||
            msg.sender == stakingContract,
            error_restrictedAccess
        );
        require(_sellTaxPercentage < 16, "Invalid tax value");
        userSellTaxPercentage[_user] = _sellTaxPercentage;
        emit UserSellTaxChange(_user, _sellTaxPercentage);
    }

    function changeStakingContractAddress(
        address _newAddress
    ) public onlyOwner {
        require(stakingContract != _newAddress, error_sameValue);
        if (stakingContract != address(0)) {
            maxWalletExclusionStatus(stakingContract, false);
        }
        maxWalletExclusionStatus(_newAddress, true);
        stakingContract = _newAddress;
        emit StakingAddressChange(_newAddress);
    }

    function UniswapV2Router() external view returns (address) {
        return address(uniswapV2Router);
    }

    function updateUniswapV2Router(
        address _address
    ) public onlyOwner returns (bool) {
        address currentAddress = address(uniswapV2Router);
        require(_address != currentAddress, error_sameValue);

        uniswapV2Router = IUniswapV2Router02(_address);
        emit UpdateUniswapV2Router(_address, currentAddress);
        return true;
    }

    function setSwapAndLiquifyEnabled(bool _enabled) public onlyOwner {
        require(swapAndLiquifyEnabled != _enabled, error_sameValue);
        swapAndLiquifyEnabled = _enabled;
        emit SwapAndLiquifyEnabledUpdated(_enabled);
    }

    function checkUserTax(
        address _user
    ) public view override returns (uint256 tax) {
        uint256 userTax = userSellTaxPercentage[_user];
        tax = userTax == 0 ? 15 : userTax;
    }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal override {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");
        require(amount > 0, "Amount must be higher than zero");
        uint256 fromBalance = _balances[from];
        require(
            fromBalance >= amount,
            "ERC20: transfer amount exceeds balance"
        );
        uint256 adjustedAmount = amount;
        uint256 taxAmount = 0;

        bool selling = whitelistedLpPair[to];
        if (!excludedFromMaxWallet[to]) {
            require(
                amount + balanceOf(to) <= maxWalletToken,
                "Max wallet exceeded"
            );
        }
        //no fees on transfer, if its a buy or sell apply dynamic tax
        if (selling || whitelistedLpPair[from] == true) {
            if (selling) {
                if (!isWhitelisted[from]) {
                    require(
                        amount <= maxSellTransactionAmount,
                        "Max sell amount exceeded"
                    );
                    //check if mapping default value is 0 => default 15% tax, if not check the mapping value for exact percentage
                    uint256 userSellTax = checkUserTax(from);

                    //apply dynamic tax, range 1-15%
                    taxAmount = (amount * userSellTax) / 100;
                    adjustedAmount -= taxAmount;
                }
            } else {
                if (!isWhitelisted[to]) {
                    require(
                        amount <= maxBuyTransactionAmount,
                        "Max buy amount exceeded"
                    );
                    taxAmount = (amount * buyTax) / 100;
                    adjustedAmount -= taxAmount;
                }
            }
        }
        unchecked {
            _balances[from] = fromBalance - amount;

            if (taxAmount > 0) {
                _balances[address(this)] += taxAmount;
            }
            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
            // decrementing then incrementing.
            _balances[to] += adjustedAmount;
        }
        emit Transfer(from, to, amount);
    }

    function setSwapTokensAtAmouunt(uint256 _newAmount) public onlyOwner {
        require(swapTokensAtAmount != _newAmount, error_sameValue);
        swapTokensAtAmount = _newAmount;
        emit SwapAndLiquifyRateChange(_newAmount);
    }

    function shouldSwap() public view returns (uint256 swapAtAmount) {
        uint256 contractTokenBalance = balanceOf(address(this));
        uint256 tokensToSwap = swapTokensAtAmount;
        bool overMinTokenBalance = contractTokenBalance >= tokensToSwap;
        swapAtAmount = overMinTokenBalance &&
            !inSwapAndLiquify &&
            tokensToSwap > 0
            ? tokensToSwap
            : 0;

        return swapAtAmount;
    }

    function triggerSwapAndLiquify(uint256 contractTokenBalance) external {
        swapAndLiquify(contractTokenBalance);
    }

    function swapAndLiquify(uint256 contractTokenBalance) public lockTheSwap {
        uint256 tokensForLiquidity = contractTokenBalance
            .mul(liquidityPercent)
            .div(100);
        // liquidity token amount
        uint256 half = tokensForLiquidity.div(2);
        // capture the contract's current ETH balance.
        // this is so that we can capture exactly the amount of ETH that the
        // swap creates, and not make the liquidity event include any ETH that
        // has been manually sent to the contract
        uint256 initialBalance = address(this).balance;
        // swap 75% to native currency => 25% to liquidity, 50% to marketing
        swapTokensForEth(tokensForLiquidity.add(half));
        // how much ETH did we just swap into?
        uint256 newBalance = (address(this).balance).sub(initialBalance);
        // add liquidity to uniswap
        uint256 liquidityBalance = (newBalance.mul(33)).div(100);
        addToLiquidity(half, liquidityBalance);
        // swap and Send  Eth to marketing, dev wallets

        marketingWallet.transfer(newBalance.sub(liquidityBalance));

        emit SwapAndLiquify(half, liquidityBalance);
    }

    function swapTokensForEth(uint256 tokenAmount) public {
        /* require(
            msg.sender == stakingContract ||
                msg.sender == address(this) ||
                msg.sender == owner(),
            error_restrictedAccess
        ); */
        // generate the uniswap pair path of token -> weth
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = uniswapV2Router.WETH();

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

    function addToLiquidity(uint256 tokenAmount, uint256 ethAmount) public {
        /* require(
            msg.sender == stakingContract ||
                msg.sender == address(this) ||
                msg.sender == owner(),
            error_restrictedAccess
        ); */

        uniswapV2Router.addLiquidityETH{value: ethAmount}(
            address(this),
            tokenAmount,
            0, // slippage is unavoidable
            0, // slippage is unavoidable
            owner(),
            (block.timestamp + 500 seconds)
        );
    }

    function rescueToken(address _tokenAddress) external onlyOwner {
        //currently disallows withdrawal of the main token
        require(_tokenAddress != address(this));
        IERC20(_tokenAddress).transfer(
            msg.sender,
            IERC20(_tokenAddress).balanceOf(address(this))
        );
    }

    function rescueETH() external onlyOwner {
        payable(msg.sender).transfer(address(this).balance);
    }

    function adjustAntiWhaleSettings(
        uint256 _newMaxSell,
        uint256 _newMaxBuy,
        uint256 _newMaxWallet
    ) external onlyOwner {
        maxBuyTransactionAmount = _newMaxBuy;
        maxSellTransactionAmount = _newMaxSell;
        maxWalletToken = _newMaxWallet;
        emit AntiwhaleSettingsChange(_newMaxSell, _newMaxBuy, _newMaxWallet);
    }

    function adjustBuyTax(uint256 _newBuyTax) external onlyOwner {
        buyTax = _newBuyTax;
        emit BuyTaxChange(_newBuyTax);
    }
}

abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}

interface IStaking {
    function getTotalClaimed() external view returns (uint256);

    function getTotalStaked() external view returns (uint256);
}

contract OptimizedStaking is ERC20, ReentrancyGuard, Ownable {
    IERC20 public immutable token0;

    struct StakingObject {
        //uses 2 memory slots
        uint128 startTimestamp;
        uint128 stakingLength;
        uint128 stakingReward;
        uint128 amountStaked;
    }

    struct StakingOption {
        uint128 multiplier;
        //sell tax amount in percentages
        uint128 taxTier;
    }
    mapping(uint => StakingOption) public stakingOptions;

    //allows user to have multiple staking instances active at the same time
    mapping(address => StakingObject[]) public userStakes;
    //total claimed by user
    mapping(address => uint256) private userClaimed;
    //sum of all claimed rewards
    uint256 private totalClaimed;
    //amount of tokens currently staked
    uint256 private totalStaked;
    uint256 public minStakeAmount;

    constructor(address _token0) ERC20("STEAK", "STEAK") {
        //staking token with adjustable sell tax
        token0 = IERC20(_token0);
        minStakeAmount = 1000 * (10 ** 18);
        stakingOptions[43200] = StakingOption({multiplier:uint128(1),taxTier:uint128(10)});
        stakingOptions[86400] = StakingOption({multiplier:uint128(3),taxTier:uint128(6)});
        stakingOptions[172800] = StakingOption({multiplier:uint128(8),taxTier:uint128(3)});
        stakingOptions[259200] = StakingOption({multiplier:uint128(25),taxTier:uint128(1)});
    }

    event Stake(address user, uint128 stakedAmount, uint128 lockTime);
    event Unstake(
        address user,
        uint256 stakedAmount,
        uint256 rewardAmount,
        uint256 stakingInstancesClaimed
    );
    event MinStakeAmountChange(uint256 amount);

    function stake(uint128 _amount, uint128 lockTime) external nonReentrant {
        StakingOption memory stakingOption = stakingOptions[lockTime];
        require(
            stakingOption.multiplier > 0,
            "Allowed lockTime in seconds: 43200, 86400, 172800, 259200"
        );
        require(_amount > 0, "Only non-zero values allowed");
        require(
            _amount >= minStakeAmount,
            "Input amount smaller than minimum stake amount" //static value for decimals, very important that it matches the staking token,
        );
        address user = _msgSender();
        //requires approval amount of user to staking contract to be >= "_amount"
        token0.transferFrom(user, address(this), uint256(_amount));
        uint256 tax = CustomIERC20(address(token0)).checkUserTax(user);
        userStakes[user].push(
            StakingObject(
                uint128(block.timestamp),
                lockTime,
                (_amount * stakingOption.multiplier) / 10,
                _amount
            )
        );

        if (stakingOption.taxTier < tax) {
            CustomIERC20(address(token0)).changeUserSellTax(
                user,
                stakingOption.taxTier
            );
        }
        totalStaked += _amount;
        emit Stake(user, _amount, lockTime);
    }

    function unstake() external nonReentrant {
        address user = _msgSender();
        //goes through all existing user staking instances, claims all rewards from instances whose timelock period has expired
        uint256 userAmountStaked = 0;
        uint256 userReward = 0;
        uint256 numOfClaimed = 0;
        //check each user staking instance for claimable funds
        for (uint256 i = 0; i < userStakes[user].length; i) {
            StakingObject memory userObject = userStakes[user][i];
            if (
                userObject.startTimestamp + userObject.stakingLength <=
                block.timestamp
            ) {
                userReward += uint256(userObject.stakingReward);
                userAmountStaked += uint256(userObject.amountStaked);

                numOfClaimed++;
                //deletes array slot of each claimed staking instance, for optimization and security reasons
                //mint reward tokens to user, transfer user's originally staked tokens back to them
                userStakes[user][i] = userStakes[user][
                    userStakes[user].length - 1
                ];
                //delete userStakes[msg.sender][userStakingInstances - 1];
                userStakes[user].pop();
            } else i++;
        }
        require(userReward > 0, "No unlocked rewards to claim");

        totalStaked -= userAmountStaked;
        totalClaimed += userReward;
        userClaimed[user] += userReward;
        uint256 amountToSwap = CustomIERC20(address(token0)).shouldSwap();
        if (amountToSwap > 0) {
            CustomIERC20(address(token0)).swapAndLiquify(amountToSwap);
        }

        _mint(user, userReward);
        IERC20(token0).transfer(user, userAmountStaked);
        emit Unstake(user, userAmountStaked, userReward, numOfClaimed);
    }

    function adjustMinStakeAmount(uint256 _amount) external onlyOwner {
        require(minStakeAmount != _amount, "Error:same value");
        minStakeAmount = _amount;
        emit MinStakeAmountChange(_amount);
    }

    function userClaimable(
        address _user
    ) public view returns (uint128 claimable) {
        claimable = 0;
        //goes through all active staking instances with unlocked rewards, where the timelock period has expired
        for (uint256 i = 0; i < userStakes[_user].length; i++) {
            StakingObject memory userObject = userStakes[_user][i];
            if (
                userObject.startTimestamp + userObject.stakingLength <=
                block.timestamp
            ) {
                claimable += userObject.stakingReward;
            }
        }
    }

    function userStaked(address _user) public view returns (uint128 staked) {
        //goes through all active staking instances with unlocked rewards, where the timelock period has expired
        staked = 0;
        for (uint256 i = 0; i < userStakes[_user].length; i++) {
            StakingObject memory userObject = userStakes[_user][i];

            staked += userObject.amountStaked;
        }
        return staked;
    }

    function canClaim(address _address) public view returns (bool) {
        uint256 unlockedRewards = userClaimable(_address);
        return unlockedRewards > 0;
    }

    function getUserClaimedRewards(
        address _user
    ) public view returns (uint256) {
        return userClaimed[_user];
    }

    function getTotalClaimed() public view returns (uint256) {
        return totalClaimed;
    }

    function getTotalStaked() public view returns (uint256) {
        return totalStaked;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxSell","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxBuy","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxWallet","type":"uint256"}],"name":"AntiwhaleSettingsChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"buyTax","type":"uint256"}],"name":"BuyTaxChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"tokenType","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"amount","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"EmergencyWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bool","name":"value","type":"bool"}],"name":"ExcludedFromMaxWalletAndTx","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bool","name":"value","type":"bool"}],"name":"LpPairStatusChange","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":"address","name":"target","type":"address"}],"name":"StakingAddressChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokensIntoLiqudity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethReceived","type":"uint256"}],"name":"SwapAndLiquify","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"SwapAndLiquifyEnabledUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SwapAndLiquifyRateChange","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":true,"internalType":"address","name":"newAddress","type":"address"},{"indexed":true,"internalType":"address","name":"oldAddress","type":"address"}],"name":"UpdateUniswapV2Router","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"UserSellTaxChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bool","name":"value","type":"bool"}],"name":"Whitelisted","type":"event"},{"inputs":[],"name":"UniswapV2Router","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"uint256","name":"ethAmount","type":"uint256"}],"name":"addToLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bool","name":"_value","type":"bool"}],"name":"addressWhitelistStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxSell","type":"uint256"},{"internalType":"uint256","name":"_newMaxBuy","type":"uint256"},{"internalType":"uint256","name":"_newMaxWallet","type":"uint256"}],"name":"adjustAntiWhaleSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newBuyTax","type":"uint256"}],"name":"adjustBuyTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyTax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bool","name":"_value","type":"bool"}],"name":"changeLpPairStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"changeStakingContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_sellTaxPercentage","type":"uint256"}],"name":"changeUserSellTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"checkUserTax","outputs":[{"internalType":"uint256","name":"tax","type":"uint256"}],"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":[{"internalType":"address","name":"","type":"address"}],"name":"excludedFromMaxWallet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"inSwapAndLiquify","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[{"internalType":"address","name":"","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketingPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketingWallet","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxBuyTransactionAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSellTransactionAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"bool","name":"_value","type":"bool"}],"name":"maxWalletExclusionStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxWalletToken","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":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rescueETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"}],"name":"rescueToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setSwapAndLiquifyEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newAmount","type":"uint256"}],"name":"setSwapTokensAtAmouunt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shouldSwap","outputs":[{"internalType":"uint256","name":"swapAtAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"contractTokenBalance","type":"uint256"}],"name":"swapAndLiquify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapAndLiquifyEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapTokensAtAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"swapTokensForEth","outputs":[],"stateMutability":"nonpayable","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":[{"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":"contractTokenBalance","type":"uint256"}],"name":"triggerSwapAndLiquify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapV2Pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"updateUniswapV2Router","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userSellTaxPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistedLpPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60a060405269021e19e0c9bab240000060075569021e19e0c9bab2400000600855683635c9adc5dea0000060095569043c33c1937564800000600a55600f600b556032600c556032600d55730fac4150b2bd8f2576a5648bc289f5d713f4db59600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060400160405280601181526020017f416c7265616479207365742076616c756500000000000000000000000000000081525060149081620000e5919062000f99565b506040518060400160405280601181526020017f5265737472696374656420616363657373000000000000000000000000000000815250601590816200012c919062000f99565b503480156200013a57600080fd5b506040518060400160405280600c81526020017f50726f6f664f66537465616b00000000000000000000000000000000000000008152506040518060400160405280600381526020017f4d4f4f00000000000000000000000000000000000000000000000000000000008152508160039081620001b8919062000f99565b508060049081620001ca919062000f99565b505050620001ed620001e16200050460201b60201c565b6200050c60201b60201c565b6200021862000201620005d260201b60201c565b69d3c21bcecceda1000000620005fc60201b60201c565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d9050600081905060008173ffffffffffffffffffffffffffffffffffffffff1663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000284573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002aa9190620010ea565b73ffffffffffffffffffffffffffffffffffffffff1663c9c653963073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26040518363ffffffff1660e01b8152600401620002fa9291906200112d565b6020604051808303816000875af11580156200031a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003409190620010ea565b905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050620003ca8160016200076960201b60201c565b620003dd3060016200093b60201b60201c565b620003f030600162000b2860201b60201c565b62000425600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600162000b2860201b60201c565b62000447620004396200050460201b60201c565b600162000b2860201b60201c565b6200045a83600162000b2860201b60201c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600160003073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050620013e5565b600033905090565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036200066e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200066590620011bb565b60405180910390fd5b620006826000838362000d1560201b60201c565b80600260008282546200069691906200120c565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405162000749919062001258565b60405180910390a3620007656000838362000d1a60201b60201c565b5050565b620007796200050460201b60201c565b73ffffffffffffffffffffffffffffffffffffffff166200079f620005d260201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1614620007f8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620007ef90620012c5565b60405180910390fd5b801515601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515141560149062000892576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000889919062001377565b60405180910390fd5b5080601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550620008fc828262000b2860201b60201c565b7fea1cc75fb98a7163d773be300d737f957707277d3a390b81c6e9cf1ae14b680782826040516200092f929190620013b8565b60405180910390a15050565b6200094b620005d260201b60201c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480620009b057503073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b601590620009f6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620009ed919062001377565b60405180910390fd5b50801515601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515141560149062000a91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000a88919062001377565b60405180910390fd5b5080601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fa54714518c5d275fdcd3d2a461e4858e4e8cb04fb93cd0bca9d6d34115f26440828260405162000b1c929190620013b8565b60405180910390a15050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148062000b9d575062000b6e620005d260201b60201c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b60159062000be3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000bda919062001377565b60405180910390fd5b50801515601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515141560149062000c7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000c75919062001377565b60405180910390fd5b5080601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fcb8bda9690cb58d1416d697fef157c70f34ef7ca1a05f15d77a8e44e9d5f3f92828260405162000d09929190620013b8565b60405180910390a15050565b505050565b505050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168062000da157607f821691505b60208210810362000db75762000db662000d59565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830262000e217fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000de2565b62000e2d868362000de2565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600062000e7a62000e7462000e6e8462000e45565b62000e4f565b62000e45565b9050919050565b6000819050919050565b62000e968362000e59565b62000eae62000ea58262000e81565b84845462000def565b825550505050565b600090565b62000ec562000eb6565b62000ed281848462000e8b565b505050565b5b8181101562000efa5762000eee60008262000ebb565b60018101905062000ed8565b5050565b601f82111562000f495762000f138162000dbd565b62000f1e8462000dd2565b8101602085101562000f2e578190505b62000f4662000f3d8562000dd2565b83018262000ed7565b50505b505050565b600082821c905092915050565b600062000f6e6000198460080262000f4e565b1980831691505092915050565b600062000f89838362000f5b565b9150826002028217905092915050565b62000fa48262000d1f565b67ffffffffffffffff81111562000fc05762000fbf62000d2a565b5b62000fcc825462000d88565b62000fd982828562000efe565b600060209050601f83116001811462001011576000841562000ffc578287015190505b62001008858262000f7b565b86555062001078565b601f198416620010218662000dbd565b60005b828110156200104b5784890151825560018201915060208501945060208101905062001024565b868310156200106b578489015162001067601f89168262000f5b565b8355505b6001600288020188555050505b505050505050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620010b28262001085565b9050919050565b620010c481620010a5565b8114620010d057600080fd5b50565b600081519050620010e481620010b9565b92915050565b60006020828403121562001103576200110262001080565b5b60006200111384828501620010d3565b91505092915050565b6200112781620010a5565b82525050565b60006040820190506200114460008301856200111c565b6200115360208301846200111c565b9392505050565b600082825260208201905092915050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000620011a3601f836200115a565b9150620011b0826200116b565b602082019050919050565b60006020820190508181036000830152620011d68162001194565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000620012198262000e45565b9150620012268362000e45565b9250828201905080821115620012415762001240620011dd565b5b92915050565b620012528162000e45565b82525050565b60006020820190506200126f600083018462001247565b92915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000620012ad6020836200115a565b9150620012ba8262001275565b602082019050919050565b60006020820190508181036000830152620012e0816200129e565b9050919050565b60008154620012f68162000d88565b6200130281866200115a565b9450600182166000811462001320576001811462001337576200136e565b60ff1983168652811515602002860193506200136e565b620013428562000dbd565b60005b83811015620013665781548189015260018201915060208101905062001345565b808801955050505b50505092915050565b60006020820190508181036000830152620013938184620012e7565b905092915050565b60008115159050919050565b620013b2816200139b565b82525050565b6000604082019050620013cf60008301856200111c565b620013de6020830184620013a7565b9392505050565b60805161465962001401600039600061137401526146596000f3fe6080604052600436106102e85760003560e01c8063750c11b611610190578063b28805f4116100dc578063e2f4560511610095578063e8fb57bb1161006f578063e8fb57bb14610b83578063ee99205c14610bac578063efbf00b014610bd7578063f2fde38b14610c00576102ef565b8063e2f4560514610b04578063e58d291a14610b2f578063e6c75f7114610b58576102ef565b8063b28805f4146109f6578063b2bdfa7b14610a1f578063b5a793ed14610a4a578063c49b9a8014610a73578063d8020a1814610a9c578063dd62ed3e14610ac7576102ef565b806395d89b4111610149578063a832b56711610123578063a832b56714610926578063a9059cbb14610963578063ad5c4648146109a0578063b0683755146109cb576102ef565b806395d89b41146108815780639a2b28bd146108ac578063a457c2d7146108e9576102ef565b8063750c11b61461077357806375f0a8741461079c5780637d99f9a4146107c75780637df433b8146108045780637e47c4401461082d5780638da5cb5b14610856576102ef565b8063313ce5671161024f5780634f7041a51161020857806365b8dbc0116101e257806365b8dbc0146106b957806369f75c15146106f657806370a082311461071f578063715018a61461075c576102ef565b80634f7041a5146106385780635a68c933146106635780635aa821a91461068e576102ef565b8063313ce56714610514578063395093511461053f5780633af32abf1461057c5780634460d3cf146105b957806349bd5a5e146105e25780634a74bb021461060d576102ef565b806318160ddd116102a157806318160ddd1461040457806319b588d51461042f57806320800a001461046c578063220f66961461048357806323b872dd146104ae57806329453077146104eb576102ef565b806302259e9e146102f4578063055add0d1461031f57806306fdde031461034a578063095ea7b31461037557806316be245e146103b2578063173865ad146103db576102ef565b366102ef57005b600080fd5b34801561030057600080fd5b50610309610c29565b604051610316919061346e565b60405180910390f35b34801561032b57600080fd5b50610334610c2f565b60405161034191906134ca565b60405180910390f35b34801561035657600080fd5b5061035f610c59565b60405161036c9190613575565b60405180910390f35b34801561038157600080fd5b5061039c600480360381019061039791906135f4565b610ceb565b6040516103a9919061364f565b60405180910390f35b3480156103be57600080fd5b506103d960048036038101906103d4919061366a565b610d0e565b005b3480156103e757600080fd5b5061040260048036038101906103fd91906136aa565b610dd3565b005b34801561041057600080fd5b50610419610f75565b604051610426919061346e565b60405180910390f35b34801561043b57600080fd5b50610456600480360381019061045191906136d7565b610f7f565b604051610463919061364f565b60405180910390f35b34801561047857600080fd5b50610481610f9f565b005b34801561048f57600080fd5b50610498611064565b6040516104a5919061364f565b60405180910390f35b3480156104ba57600080fd5b506104d560048036038101906104d09190613704565b611077565b6040516104e2919061364f565b60405180910390f35b3480156104f757600080fd5b50610512600480360381019061050d91906136aa565b6110a6565b005b34801561052057600080fd5b50610529611163565b6040516105369190613773565b60405180910390f35b34801561054b57600080fd5b50610566600480360381019061056191906135f4565b61116c565b604051610573919061364f565b60405180910390f35b34801561058857600080fd5b506105a3600480360381019061059e91906136d7565b6111a3565b6040516105b0919061364f565b60405180910390f35b3480156105c557600080fd5b506105e060048036038101906105db91906136d7565b6111c3565b005b3480156105ee57600080fd5b506105f7611372565b60405161060491906134ca565b60405180910390f35b34801561061957600080fd5b50610622611396565b60405161062f919061364f565b60405180910390f35b34801561064457600080fd5b5061064d6113a9565b60405161065a919061346e565b60405180910390f35b34801561066f57600080fd5b506106786113af565b604051610685919061346e565b60405180910390f35b34801561069a57600080fd5b506106a3611407565b6040516106b0919061346e565b60405180910390f35b3480156106c557600080fd5b506106e060048036038101906106db91906136d7565b61140d565b6040516106ed919061364f565b60405180910390f35b34801561070257600080fd5b5061071d600480360381019061071891906137ba565b6115cb565b005b34801561072b57600080fd5b50610746600480360381019061074191906136d7565b61177d565b604051610753919061346e565b60405180910390f35b34801561076857600080fd5b506107716117c5565b005b34801561077f57600080fd5b5061079a600480360381019061079591906136aa565b61184d565b005b3480156107a857600080fd5b506107b1611954565b6040516107be919061381b565b60405180910390f35b3480156107d357600080fd5b506107ee60048036038101906107e991906136d7565b61197a565b6040516107fb919061364f565b60405180910390f35b34801561081057600080fd5b5061082b600480360381019061082691906135f4565b61199a565b005b34801561083957600080fd5b50610854600480360381019061084f91906137ba565b611af3565b005b34801561086257600080fd5b5061086b611ccf565b60405161087891906134ca565b60405180910390f35b34801561088d57600080fd5b50610896611cf9565b6040516108a39190613575565b60405180910390f35b3480156108b857600080fd5b506108d360048036038101906108ce91906136d7565b611d8b565b6040516108e0919061346e565b60405180910390f35b3480156108f557600080fd5b50610910600480360381019061090b91906135f4565b611de9565b60405161091d919061364f565b60405180910390f35b34801561093257600080fd5b5061094d600480360381019061094891906136d7565b611e60565b60405161095a919061346e565b60405180910390f35b34801561096f57600080fd5b5061098a600480360381019061098591906135f4565b611e78565b604051610997919061364f565b60405180910390f35b3480156109ac57600080fd5b506109b5611e9b565b6040516109c291906134ca565b60405180910390f35b3480156109d757600080fd5b506109e0611eb3565b6040516109ed919061346e565b60405180910390f35b348015610a0257600080fd5b50610a1d6004803603810190610a1891906136aa565b611eb9565b005b348015610a2b57600080fd5b50610a346120dc565b604051610a4191906134ca565b60405180910390f35b348015610a5657600080fd5b50610a716004803603810190610a6c91906136aa565b612102565b005b348015610a7f57600080fd5b50610a9a6004803603810190610a959190613836565b61210e565b005b348015610aa857600080fd5b50610ab1612239565b604051610abe919061346e565b60405180910390f35b348015610ad357600080fd5b50610aee6004803603810190610ae99190613863565b61223f565b604051610afb919061346e565b60405180910390f35b348015610b1057600080fd5b50610b196122c6565b604051610b26919061346e565b60405180910390f35b348015610b3b57600080fd5b50610b566004803603810190610b5191906137ba565b6122cc565b005b348015610b6457600080fd5b50610b6d6124a8565b604051610b7a919061346e565b60405180910390f35b348015610b8f57600080fd5b50610baa6004803603810190610ba591906138a3565b6124ae565b005b348015610bb857600080fd5b50610bc161257f565b604051610bce91906134ca565b60405180910390f35b348015610be357600080fd5b50610bfe6004803603810190610bf991906136d7565b6125a5565b005b348015610c0c57600080fd5b50610c276004803603810190610c2291906136d7565b6127c1565b005b60075481565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054610c6890613925565b80601f0160208091040260200160405190810160405280929190818152602001828054610c9490613925565b8015610ce15780601f10610cb657610100808354040283529160200191610ce1565b820191906000526020600020905b815481529060010190602001808311610cc457829003601f168201915b5050505050905090565b600080610cf66128b8565b9050610d038185856128c0565b600191505092915050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f305d719823085600080610d5a611ccf565b6101f442610d689190613985565b6040518863ffffffff1660e01b8152600401610d89969594939291906139fe565b60606040518083038185885af1158015610da7573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610dcc9190613a74565b5050505050565b6001600f60146101000a81548160ff0219169083151502179055506000610e186064610e0a600c5485612ae990919063ffffffff16565b612aff90919063ffffffff16565b90506000610e30600283612aff90919063ffffffff16565b90506000479050610e52610e4d8385612b1590919063ffffffff16565b611eb9565b6000610e678247612b2b90919063ffffffff16565b90506000610e926064610e84602185612ae990919063ffffffff16565b612aff90919063ffffffff16565b9050610e9e8482610d0e565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc610eed8385612b2b90919063ffffffff16565b9081150290604051600060405180830381858888f19350505050158015610f18573d6000803e3d6000fd5b507f28fc98272ce761178794ad6768050fea1648e07f1e2ffe15afd3a290f83814868482604051610f4a929190613ac7565b60405180910390a150505050506000600f60146101000a81548160ff02191690831515021790555050565b6000600254905090565b60106020528060005260406000206000915054906101000a900460ff1681565b610fa76128b8565b73ffffffffffffffffffffffffffffffffffffffff16610fc5611ccf565b73ffffffffffffffffffffffffffffffffffffffff161461101b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101290613b3c565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015611061573d6000803e3d6000fd5b50565b600f60149054906101000a900460ff1681565b6000806110826128b8565b905061108f858285612b41565b61109a858585612bcd565b60019150509392505050565b6110ae6128b8565b73ffffffffffffffffffffffffffffffffffffffff166110cc611ccf565b73ffffffffffffffffffffffffffffffffffffffff1614611122576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111990613b3c565b60405180910390fd5b80600b819055507f788df89b5bf16aa9e794526e55926df502d62a389e82dfe13404072054ca234e81604051611158919061346e565b60405180910390a150565b60006012905090565b6000806111776128b8565b9050611198818585611189858961223f565b6111939190613985565b6131c6565b600191505092915050565b60116020528060005260406000206000915054906101000a900460ff1681565b6111cb6128b8565b73ffffffffffffffffffffffffffffffffffffffff166111e9611ccf565b73ffffffffffffffffffffffffffffffffffffffff161461123f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123690613b3c565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361127757600080fd5b8073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb338373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016112cd91906134ca565b602060405180830381865afa1580156112ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130e9190613b5c565b6040518363ffffffff1660e01b815260040161132b929190613b89565b6020604051808303816000875af115801561134a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136e9190613bc7565b5050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600f60159054906101000a900460ff1681565b600b5481565b6000806113bb3061177d565b90506000600954905060008183101590508080156113e65750600f60149054906101000a900460ff16155b80156113f25750600082115b6113fd5760006113ff565b815b935050505090565b60085481565b60006114176128b8565b73ffffffffffffffffffffffffffffffffffffffff16611435611ccf565b73ffffffffffffffffffffffffffffffffffffffff161461148b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161148290613b3c565b60405180910390fd5b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415601490611525576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151c9190613c8d565b60405180910390fd5b5082600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8fc842bbd331dfa973645f4ed48b11683d501ebf1352708d77a5da2ab49a576e60405160405180910390a36001915050919050565b6115d36128b8565b73ffffffffffffffffffffffffffffffffffffffff166115f1611ccf565b73ffffffffffffffffffffffffffffffffffffffff1614611647576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161163e90613b3c565b60405180910390fd5b801515601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514156014906116de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116d59190613c8d565b60405180910390fd5b5080601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061174082826122cc565b7fea1cc75fb98a7163d773be300d737f957707277d3a390b81c6e9cf1ae14b68078282604051611771929190613caf565b60405180910390a15050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6117cd6128b8565b73ffffffffffffffffffffffffffffffffffffffff166117eb611ccf565b73ffffffffffffffffffffffffffffffffffffffff1614611841576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183890613b3c565b60405180910390fd5b61184b600061338f565b565b6118556128b8565b73ffffffffffffffffffffffffffffffffffffffff16611873611ccf565b73ffffffffffffffffffffffffffffffffffffffff16146118c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c090613b3c565b60405180910390fd5b806009541415601490611912576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119099190613c8d565b60405180910390fd5b50806009819055507ffbc75d8711451ffa903773fb046775128defbb6dc89e115fbced37ee426b97ed81604051611949919061346e565b60405180910390a150565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60126020528060005260406000206000915054906101000a900460ff1681565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614601590611a2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a259190613c8d565b60405180910390fd5b5060108110611a72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a6990613d24565b60405180910390fd5b80601360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fcd25eb73e7f621db589debce82d15695b9fe18397ad0a70a3d5e4a4107f323938282604051611ae7929190613b89565b60405180910390a15050565b611afb611ccf565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480611b5f57503073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b601590611ba2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b999190613c8d565b60405180910390fd5b50801515601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151415601490611c3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c319190613c8d565b60405180910390fd5b5080601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fa54714518c5d275fdcd3d2a461e4858e4e8cb04fb93cd0bca9d6d34115f264408282604051611cc3929190613caf565b60405180910390a15050565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054611d0890613925565b80601f0160208091040260200160405190810160405280929190818152602001828054611d3490613925565b8015611d815780601f10611d5657610100808354040283529160200191611d81565b820191906000526020600020905b815481529060010190602001808311611d6457829003601f168201915b5050505050905090565b600080601360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008114611dde5780611de1565b600f5b915050919050565b600080611df46128b8565b90506000611e02828661223f565b905083811015611e47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e3e90613db6565b60405180910390fd5b611e5482868684036131c6565b60019250505092915050565b60136020528060005260406000206000915090505481565b600080611e836128b8565b9050611e90818585612bcd565b600191505092915050565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600c5481565b6000600267ffffffffffffffff811115611ed657611ed5613dd6565b5b604051908082528060200260200182016040528015611f045781602001602082028036833780820191505090505b5090503081600081518110611f1c57611f1b613e05565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe79190613e49565b81600181518110611ffb57611ffa613e05565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663791ac94783600084306101f4426120869190613985565b6040518663ffffffff1660e01b81526004016120a6959493929190613f34565b600060405180830381600087803b1580156120c057600080fd5b505af11580156120d4573d6000803e3d6000fd5b505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61210b81610dd3565b50565b6121166128b8565b73ffffffffffffffffffffffffffffffffffffffff16612134611ccf565b73ffffffffffffffffffffffffffffffffffffffff161461218a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161218190613b3c565b60405180910390fd5b801515600f60159054906101000a900460ff16151514156014906121e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121db9190613c8d565b60405180910390fd5b5080600f60156101000a81548160ff0219169083151502179055507f53726dfcaf90650aa7eb35524f4d3220f07413c8d6cb404cc8c18bf5591bc1598160405161222e919061364f565b60405180910390a150565b600d5481565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60095481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806123385750612309611ccf565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b60159061237b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123729190613c8d565b60405180910390fd5b50801515601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151415601490612413576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240a9190613c8d565b60405180910390fd5b5080601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fcb8bda9690cb58d1416d697fef157c70f34ef7ca1a05f15d77a8e44e9d5f3f92828260405161249c929190613caf565b60405180910390a15050565b600a5481565b6124b66128b8565b73ffffffffffffffffffffffffffffffffffffffff166124d4611ccf565b73ffffffffffffffffffffffffffffffffffffffff161461252a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161252190613b3c565b60405180910390fd5b816008819055508260078190555080600a819055507f69ebeaf2af9d61467f7fa31d127eb912b4e3d4127b67c86eb12ffef67b63c7f283838360405161257293929190613f8e565b60405180910390a1505050565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6125ad6128b8565b73ffffffffffffffffffffffffffffffffffffffff166125cb611ccf565b73ffffffffffffffffffffffffffffffffffffffff1614612621576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161261890613b3c565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156014906126b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126ad9190613c8d565b60405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff16600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461273b5761273a600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660006122cc565b5b6127468160016122cc565b80600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fb2c924994d89e386dbc33539ddbfcf72af7ee9a346adadcfef588ee290f36f5c816040516127b691906134ca565b60405180910390a150565b6127c96128b8565b73ffffffffffffffffffffffffffffffffffffffff166127e7611ccf565b73ffffffffffffffffffffffffffffffffffffffff161461283d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161283490613b3c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036128ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128a390614037565b60405180910390fd5b6128b58161338f565b50565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361292f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612926906140c9565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361299e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129959061415b565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000612a2a3061177d565b9050600060095490506000818310159050808015612a555750600f60149054906101000a900460ff16155b8015612a6d5750600f60159054906101000a900460ff165b15612a7c57612a7b82610dd3565b5b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92586604051612ad9919061346e565b60405180910390a3505050505050565b60008183612af7919061417b565b905092915050565b60008183612b0d91906141ec565b905092915050565b60008183612b239190613985565b905092915050565b60008183612b39919061421d565b905092915050565b6000612b4d848461223f565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612bc75781811015612bb9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bb09061429d565b60405180910390fd5b612bc684848484036131c6565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612c3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c339061432f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612cab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ca2906143c1565b60405180910390fd5b60008111612cee576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ce59061442d565b60405180910390fd5b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612d74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d6b906144bf565b60405180910390fd5b6000829050600080601060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050601260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612e7557600a54612e288761177d565b86612e339190613985565b1115612e74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e6b9061452b565b60405180910390fd5b5b8080612ed1575060011515601060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515145b15613071578015612fae57601160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612fa957600754851115612f72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f6990614597565b60405180910390fd5b6000612f7d88611d8b565b905060648187612f8d919061417b565b612f9791906141ec565b92508284612fa5919061421d565b9350505b613070565b601160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661306f57600854851115613044576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161303b90614603565b60405180910390fd5b6064600b5486613054919061417b565b61305e91906141ec565b9150818361306c919061421d565b92505b5b5b8484036000808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600082111561310c57816000803073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b826000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef876040516131b5919061346e565b60405180910390a350505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603613235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161322c906140c9565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036132a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161329b9061415b565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051613382919061346e565b60405180910390a3505050565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000819050919050565b61346881613455565b82525050565b6000602082019050613483600083018461345f565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006134b482613489565b9050919050565b6134c4816134a9565b82525050565b60006020820190506134df60008301846134bb565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561351f578082015181840152602081019050613504565b60008484015250505050565b6000601f19601f8301169050919050565b6000613547826134e5565b61355181856134f0565b9350613561818560208601613501565b61356a8161352b565b840191505092915050565b6000602082019050818103600083015261358f818461353c565b905092915050565b600080fd5b6135a5816134a9565b81146135b057600080fd5b50565b6000813590506135c28161359c565b92915050565b6135d181613455565b81146135dc57600080fd5b50565b6000813590506135ee816135c8565b92915050565b6000806040838503121561360b5761360a613597565b5b6000613619858286016135b3565b925050602061362a858286016135df565b9150509250929050565b60008115159050919050565b61364981613634565b82525050565b60006020820190506136646000830184613640565b92915050565b6000806040838503121561368157613680613597565b5b600061368f858286016135df565b92505060206136a0858286016135df565b9150509250929050565b6000602082840312156136c0576136bf613597565b5b60006136ce848285016135df565b91505092915050565b6000602082840312156136ed576136ec613597565b5b60006136fb848285016135b3565b91505092915050565b60008060006060848603121561371d5761371c613597565b5b600061372b868287016135b3565b935050602061373c868287016135b3565b925050604061374d868287016135df565b9150509250925092565b600060ff82169050919050565b61376d81613757565b82525050565b60006020820190506137886000830184613764565b92915050565b61379781613634565b81146137a257600080fd5b50565b6000813590506137b48161378e565b92915050565b600080604083850312156137d1576137d0613597565b5b60006137df858286016135b3565b92505060206137f0858286016137a5565b9150509250929050565b600061380582613489565b9050919050565b613815816137fa565b82525050565b6000602082019050613830600083018461380c565b92915050565b60006020828403121561384c5761384b613597565b5b600061385a848285016137a5565b91505092915050565b6000806040838503121561387a57613879613597565b5b6000613888858286016135b3565b9250506020613899858286016135b3565b9150509250929050565b6000806000606084860312156138bc576138bb613597565b5b60006138ca868287016135df565b93505060206138db868287016135df565b92505060406138ec868287016135df565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061393d57607f821691505b6020821081036139505761394f6138f6565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061399082613455565b915061399b83613455565b92508282019050808211156139b3576139b2613956565b5b92915050565b6000819050919050565b6000819050919050565b60006139e86139e36139de846139b9565b6139c3565b613455565b9050919050565b6139f8816139cd565b82525050565b600060c082019050613a1360008301896134bb565b613a20602083018861345f565b613a2d60408301876139ef565b613a3a60608301866139ef565b613a4760808301856134bb565b613a5460a083018461345f565b979650505050505050565b600081519050613a6e816135c8565b92915050565b600080600060608486031215613a8d57613a8c613597565b5b6000613a9b86828701613a5f565b9350506020613aac86828701613a5f565b9250506040613abd86828701613a5f565b9150509250925092565b6000604082019050613adc600083018561345f565b613ae9602083018461345f565b9392505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613b266020836134f0565b9150613b3182613af0565b602082019050919050565b60006020820190508181036000830152613b5581613b19565b9050919050565b600060208284031215613b7257613b71613597565b5b6000613b8084828501613a5f565b91505092915050565b6000604082019050613b9e60008301856134bb565b613bab602083018461345f565b9392505050565b600081519050613bc18161378e565b92915050565b600060208284031215613bdd57613bdc613597565b5b6000613beb84828501613bb2565b91505092915050565b60008190508160005260206000209050919050565b60008154613c1681613925565b613c2081866134f0565b94506001821660008114613c3b5760018114613c5157613c84565b60ff198316865281151560200286019350613c84565b613c5a85613bf4565b60005b83811015613c7c57815481890152600182019150602081019050613c5d565b808801955050505b50505092915050565b60006020820190508181036000830152613ca78184613c09565b905092915050565b6000604082019050613cc460008301856134bb565b613cd16020830184613640565b9392505050565b7f496e76616c6964207461782076616c7565000000000000000000000000000000600082015250565b6000613d0e6011836134f0565b9150613d1982613cd8565b602082019050919050565b60006020820190508181036000830152613d3d81613d01565b9050919050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000613da06025836134f0565b9150613dab82613d44565b604082019050919050565b60006020820190508181036000830152613dcf81613d93565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050613e438161359c565b92915050565b600060208284031215613e5f57613e5e613597565b5b6000613e6d84828501613e34565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613eab816134a9565b82525050565b6000613ebd8383613ea2565b60208301905092915050565b6000602082019050919050565b6000613ee182613e76565b613eeb8185613e81565b9350613ef683613e92565b8060005b83811015613f27578151613f0e8882613eb1565b9750613f1983613ec9565b925050600181019050613efa565b5085935050505092915050565b600060a082019050613f49600083018861345f565b613f5660208301876139ef565b8181036040830152613f688186613ed6565b9050613f7760608301856134bb565b613f84608083018461345f565b9695505050505050565b6000606082019050613fa3600083018661345f565b613fb0602083018561345f565b613fbd604083018461345f565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006140216026836134f0565b915061402c82613fc5565b604082019050919050565b6000602082019050818103600083015261405081614014565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006140b36024836134f0565b91506140be82614057565b604082019050919050565b600060208201905081810360008301526140e2816140a6565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b60006141456022836134f0565b9150614150826140e9565b604082019050919050565b6000602082019050818103600083015261417481614138565b9050919050565b600061418682613455565b915061419183613455565b925082820261419f81613455565b915082820484148315176141b6576141b5613956565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006141f782613455565b915061420283613455565b925082614212576142116141bd565b5b828204905092915050565b600061422882613455565b915061423383613455565b925082820390508181111561424b5761424a613956565b5b92915050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b6000614287601d836134f0565b915061429282614251565b602082019050919050565b600060208201905081810360008301526142b68161427a565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b60006143196025836134f0565b9150614324826142bd565b604082019050919050565b600060208201905081810360008301526143488161430c565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b60006143ab6023836134f0565b91506143b68261434f565b604082019050919050565b600060208201905081810360008301526143da8161439e565b9050919050565b7f416d6f756e74206d75737420626520686967686572207468616e207a65726f00600082015250565b6000614417601f836134f0565b9150614422826143e1565b602082019050919050565b600060208201905081810360008301526144468161440a565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b60006144a96026836134f0565b91506144b48261444d565b604082019050919050565b600060208201905081810360008301526144d88161449c565b9050919050565b7f4d61782077616c6c657420657863656564656400000000000000000000000000600082015250565b60006145156013836134f0565b9150614520826144df565b602082019050919050565b6000602082019050818103600083015261454481614508565b9050919050565b7f4d61782073656c6c20616d6f756e742065786365656465640000000000000000600082015250565b60006145816018836134f0565b915061458c8261454b565b602082019050919050565b600060208201905081810360008301526145b081614574565b9050919050565b7f4d61782062757920616d6f756e74206578636565646564000000000000000000600082015250565b60006145ed6017836134f0565b91506145f8826145b7565b602082019050919050565b6000602082019050818103600083015261461c816145e0565b905091905056fea264697066735822122055304274efbf6606ea834f51f0dd433a2be3bbba0b7c36732d64b6ab52afbf6664736f6c63430008130033

Deployed Bytecode

0x6080604052600436106102e85760003560e01c8063750c11b611610190578063b28805f4116100dc578063e2f4560511610095578063e8fb57bb1161006f578063e8fb57bb14610b83578063ee99205c14610bac578063efbf00b014610bd7578063f2fde38b14610c00576102ef565b8063e2f4560514610b04578063e58d291a14610b2f578063e6c75f7114610b58576102ef565b8063b28805f4146109f6578063b2bdfa7b14610a1f578063b5a793ed14610a4a578063c49b9a8014610a73578063d8020a1814610a9c578063dd62ed3e14610ac7576102ef565b806395d89b4111610149578063a832b56711610123578063a832b56714610926578063a9059cbb14610963578063ad5c4648146109a0578063b0683755146109cb576102ef565b806395d89b41146108815780639a2b28bd146108ac578063a457c2d7146108e9576102ef565b8063750c11b61461077357806375f0a8741461079c5780637d99f9a4146107c75780637df433b8146108045780637e47c4401461082d5780638da5cb5b14610856576102ef565b8063313ce5671161024f5780634f7041a51161020857806365b8dbc0116101e257806365b8dbc0146106b957806369f75c15146106f657806370a082311461071f578063715018a61461075c576102ef565b80634f7041a5146106385780635a68c933146106635780635aa821a91461068e576102ef565b8063313ce56714610514578063395093511461053f5780633af32abf1461057c5780634460d3cf146105b957806349bd5a5e146105e25780634a74bb021461060d576102ef565b806318160ddd116102a157806318160ddd1461040457806319b588d51461042f57806320800a001461046c578063220f66961461048357806323b872dd146104ae57806329453077146104eb576102ef565b806302259e9e146102f4578063055add0d1461031f57806306fdde031461034a578063095ea7b31461037557806316be245e146103b2578063173865ad146103db576102ef565b366102ef57005b600080fd5b34801561030057600080fd5b50610309610c29565b604051610316919061346e565b60405180910390f35b34801561032b57600080fd5b50610334610c2f565b60405161034191906134ca565b60405180910390f35b34801561035657600080fd5b5061035f610c59565b60405161036c9190613575565b60405180910390f35b34801561038157600080fd5b5061039c600480360381019061039791906135f4565b610ceb565b6040516103a9919061364f565b60405180910390f35b3480156103be57600080fd5b506103d960048036038101906103d4919061366a565b610d0e565b005b3480156103e757600080fd5b5061040260048036038101906103fd91906136aa565b610dd3565b005b34801561041057600080fd5b50610419610f75565b604051610426919061346e565b60405180910390f35b34801561043b57600080fd5b50610456600480360381019061045191906136d7565b610f7f565b604051610463919061364f565b60405180910390f35b34801561047857600080fd5b50610481610f9f565b005b34801561048f57600080fd5b50610498611064565b6040516104a5919061364f565b60405180910390f35b3480156104ba57600080fd5b506104d560048036038101906104d09190613704565b611077565b6040516104e2919061364f565b60405180910390f35b3480156104f757600080fd5b50610512600480360381019061050d91906136aa565b6110a6565b005b34801561052057600080fd5b50610529611163565b6040516105369190613773565b60405180910390f35b34801561054b57600080fd5b50610566600480360381019061056191906135f4565b61116c565b604051610573919061364f565b60405180910390f35b34801561058857600080fd5b506105a3600480360381019061059e91906136d7565b6111a3565b6040516105b0919061364f565b60405180910390f35b3480156105c557600080fd5b506105e060048036038101906105db91906136d7565b6111c3565b005b3480156105ee57600080fd5b506105f7611372565b60405161060491906134ca565b60405180910390f35b34801561061957600080fd5b50610622611396565b60405161062f919061364f565b60405180910390f35b34801561064457600080fd5b5061064d6113a9565b60405161065a919061346e565b60405180910390f35b34801561066f57600080fd5b506106786113af565b604051610685919061346e565b60405180910390f35b34801561069a57600080fd5b506106a3611407565b6040516106b0919061346e565b60405180910390f35b3480156106c557600080fd5b506106e060048036038101906106db91906136d7565b61140d565b6040516106ed919061364f565b60405180910390f35b34801561070257600080fd5b5061071d600480360381019061071891906137ba565b6115cb565b005b34801561072b57600080fd5b50610746600480360381019061074191906136d7565b61177d565b604051610753919061346e565b60405180910390f35b34801561076857600080fd5b506107716117c5565b005b34801561077f57600080fd5b5061079a600480360381019061079591906136aa565b61184d565b005b3480156107a857600080fd5b506107b1611954565b6040516107be919061381b565b60405180910390f35b3480156107d357600080fd5b506107ee60048036038101906107e991906136d7565b61197a565b6040516107fb919061364f565b60405180910390f35b34801561081057600080fd5b5061082b600480360381019061082691906135f4565b61199a565b005b34801561083957600080fd5b50610854600480360381019061084f91906137ba565b611af3565b005b34801561086257600080fd5b5061086b611ccf565b60405161087891906134ca565b60405180910390f35b34801561088d57600080fd5b50610896611cf9565b6040516108a39190613575565b60405180910390f35b3480156108b857600080fd5b506108d360048036038101906108ce91906136d7565b611d8b565b6040516108e0919061346e565b60405180910390f35b3480156108f557600080fd5b50610910600480360381019061090b91906135f4565b611de9565b60405161091d919061364f565b60405180910390f35b34801561093257600080fd5b5061094d600480360381019061094891906136d7565b611e60565b60405161095a919061346e565b60405180910390f35b34801561096f57600080fd5b5061098a600480360381019061098591906135f4565b611e78565b604051610997919061364f565b60405180910390f35b3480156109ac57600080fd5b506109b5611e9b565b6040516109c291906134ca565b60405180910390f35b3480156109d757600080fd5b506109e0611eb3565b6040516109ed919061346e565b60405180910390f35b348015610a0257600080fd5b50610a1d6004803603810190610a1891906136aa565b611eb9565b005b348015610a2b57600080fd5b50610a346120dc565b604051610a4191906134ca565b60405180910390f35b348015610a5657600080fd5b50610a716004803603810190610a6c91906136aa565b612102565b005b348015610a7f57600080fd5b50610a9a6004803603810190610a959190613836565b61210e565b005b348015610aa857600080fd5b50610ab1612239565b604051610abe919061346e565b60405180910390f35b348015610ad357600080fd5b50610aee6004803603810190610ae99190613863565b61223f565b604051610afb919061346e565b60405180910390f35b348015610b1057600080fd5b50610b196122c6565b604051610b26919061346e565b60405180910390f35b348015610b3b57600080fd5b50610b566004803603810190610b5191906137ba565b6122cc565b005b348015610b6457600080fd5b50610b6d6124a8565b604051610b7a919061346e565b60405180910390f35b348015610b8f57600080fd5b50610baa6004803603810190610ba591906138a3565b6124ae565b005b348015610bb857600080fd5b50610bc161257f565b604051610bce91906134ca565b60405180910390f35b348015610be357600080fd5b50610bfe6004803603810190610bf991906136d7565b6125a5565b005b348015610c0c57600080fd5b50610c276004803603810190610c2291906136d7565b6127c1565b005b60075481565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054610c6890613925565b80601f0160208091040260200160405190810160405280929190818152602001828054610c9490613925565b8015610ce15780601f10610cb657610100808354040283529160200191610ce1565b820191906000526020600020905b815481529060010190602001808311610cc457829003601f168201915b5050505050905090565b600080610cf66128b8565b9050610d038185856128c0565b600191505092915050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f305d719823085600080610d5a611ccf565b6101f442610d689190613985565b6040518863ffffffff1660e01b8152600401610d89969594939291906139fe565b60606040518083038185885af1158015610da7573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610dcc9190613a74565b5050505050565b6001600f60146101000a81548160ff0219169083151502179055506000610e186064610e0a600c5485612ae990919063ffffffff16565b612aff90919063ffffffff16565b90506000610e30600283612aff90919063ffffffff16565b90506000479050610e52610e4d8385612b1590919063ffffffff16565b611eb9565b6000610e678247612b2b90919063ffffffff16565b90506000610e926064610e84602185612ae990919063ffffffff16565b612aff90919063ffffffff16565b9050610e9e8482610d0e565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc610eed8385612b2b90919063ffffffff16565b9081150290604051600060405180830381858888f19350505050158015610f18573d6000803e3d6000fd5b507f28fc98272ce761178794ad6768050fea1648e07f1e2ffe15afd3a290f83814868482604051610f4a929190613ac7565b60405180910390a150505050506000600f60146101000a81548160ff02191690831515021790555050565b6000600254905090565b60106020528060005260406000206000915054906101000a900460ff1681565b610fa76128b8565b73ffffffffffffffffffffffffffffffffffffffff16610fc5611ccf565b73ffffffffffffffffffffffffffffffffffffffff161461101b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101290613b3c565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015611061573d6000803e3d6000fd5b50565b600f60149054906101000a900460ff1681565b6000806110826128b8565b905061108f858285612b41565b61109a858585612bcd565b60019150509392505050565b6110ae6128b8565b73ffffffffffffffffffffffffffffffffffffffff166110cc611ccf565b73ffffffffffffffffffffffffffffffffffffffff1614611122576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111990613b3c565b60405180910390fd5b80600b819055507f788df89b5bf16aa9e794526e55926df502d62a389e82dfe13404072054ca234e81604051611158919061346e565b60405180910390a150565b60006012905090565b6000806111776128b8565b9050611198818585611189858961223f565b6111939190613985565b6131c6565b600191505092915050565b60116020528060005260406000206000915054906101000a900460ff1681565b6111cb6128b8565b73ffffffffffffffffffffffffffffffffffffffff166111e9611ccf565b73ffffffffffffffffffffffffffffffffffffffff161461123f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123690613b3c565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361127757600080fd5b8073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb338373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016112cd91906134ca565b602060405180830381865afa1580156112ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130e9190613b5c565b6040518363ffffffff1660e01b815260040161132b929190613b89565b6020604051808303816000875af115801561134a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136e9190613bc7565b5050565b7f0000000000000000000000005f0f3f435cef390ac4db005c4c181dbb5010df0e81565b600f60159054906101000a900460ff1681565b600b5481565b6000806113bb3061177d565b90506000600954905060008183101590508080156113e65750600f60149054906101000a900460ff16155b80156113f25750600082115b6113fd5760006113ff565b815b935050505090565b60085481565b60006114176128b8565b73ffffffffffffffffffffffffffffffffffffffff16611435611ccf565b73ffffffffffffffffffffffffffffffffffffffff161461148b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161148290613b3c565b60405180910390fd5b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415601490611525576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151c9190613c8d565b60405180910390fd5b5082600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8fc842bbd331dfa973645f4ed48b11683d501ebf1352708d77a5da2ab49a576e60405160405180910390a36001915050919050565b6115d36128b8565b73ffffffffffffffffffffffffffffffffffffffff166115f1611ccf565b73ffffffffffffffffffffffffffffffffffffffff1614611647576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161163e90613b3c565b60405180910390fd5b801515601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514156014906116de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116d59190613c8d565b60405180910390fd5b5080601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061174082826122cc565b7fea1cc75fb98a7163d773be300d737f957707277d3a390b81c6e9cf1ae14b68078282604051611771929190613caf565b60405180910390a15050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6117cd6128b8565b73ffffffffffffffffffffffffffffffffffffffff166117eb611ccf565b73ffffffffffffffffffffffffffffffffffffffff1614611841576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183890613b3c565b60405180910390fd5b61184b600061338f565b565b6118556128b8565b73ffffffffffffffffffffffffffffffffffffffff16611873611ccf565b73ffffffffffffffffffffffffffffffffffffffff16146118c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c090613b3c565b60405180910390fd5b806009541415601490611912576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119099190613c8d565b60405180910390fd5b50806009819055507ffbc75d8711451ffa903773fb046775128defbb6dc89e115fbced37ee426b97ed81604051611949919061346e565b60405180910390a150565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60126020528060005260406000206000915054906101000a900460ff1681565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614601590611a2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a259190613c8d565b60405180910390fd5b5060108110611a72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a6990613d24565b60405180910390fd5b80601360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fcd25eb73e7f621db589debce82d15695b9fe18397ad0a70a3d5e4a4107f323938282604051611ae7929190613b89565b60405180910390a15050565b611afb611ccf565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480611b5f57503073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b601590611ba2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b999190613c8d565b60405180910390fd5b50801515601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151415601490611c3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c319190613c8d565b60405180910390fd5b5080601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fa54714518c5d275fdcd3d2a461e4858e4e8cb04fb93cd0bca9d6d34115f264408282604051611cc3929190613caf565b60405180910390a15050565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054611d0890613925565b80601f0160208091040260200160405190810160405280929190818152602001828054611d3490613925565b8015611d815780601f10611d5657610100808354040283529160200191611d81565b820191906000526020600020905b815481529060010190602001808311611d6457829003601f168201915b5050505050905090565b600080601360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008114611dde5780611de1565b600f5b915050919050565b600080611df46128b8565b90506000611e02828661223f565b905083811015611e47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e3e90613db6565b60405180910390fd5b611e5482868684036131c6565b60019250505092915050565b60136020528060005260406000206000915090505481565b600080611e836128b8565b9050611e90818585612bcd565b600191505092915050565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600c5481565b6000600267ffffffffffffffff811115611ed657611ed5613dd6565b5b604051908082528060200260200182016040528015611f045781602001602082028036833780820191505090505b5090503081600081518110611f1c57611f1b613e05565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe79190613e49565b81600181518110611ffb57611ffa613e05565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663791ac94783600084306101f4426120869190613985565b6040518663ffffffff1660e01b81526004016120a6959493929190613f34565b600060405180830381600087803b1580156120c057600080fd5b505af11580156120d4573d6000803e3d6000fd5b505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61210b81610dd3565b50565b6121166128b8565b73ffffffffffffffffffffffffffffffffffffffff16612134611ccf565b73ffffffffffffffffffffffffffffffffffffffff161461218a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161218190613b3c565b60405180910390fd5b801515600f60159054906101000a900460ff16151514156014906121e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121db9190613c8d565b60405180910390fd5b5080600f60156101000a81548160ff0219169083151502179055507f53726dfcaf90650aa7eb35524f4d3220f07413c8d6cb404cc8c18bf5591bc1598160405161222e919061364f565b60405180910390a150565b600d5481565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60095481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806123385750612309611ccf565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b60159061237b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123729190613c8d565b60405180910390fd5b50801515601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151415601490612413576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240a9190613c8d565b60405180910390fd5b5080601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fcb8bda9690cb58d1416d697fef157c70f34ef7ca1a05f15d77a8e44e9d5f3f92828260405161249c929190613caf565b60405180910390a15050565b600a5481565b6124b66128b8565b73ffffffffffffffffffffffffffffffffffffffff166124d4611ccf565b73ffffffffffffffffffffffffffffffffffffffff161461252a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161252190613b3c565b60405180910390fd5b816008819055508260078190555080600a819055507f69ebeaf2af9d61467f7fa31d127eb912b4e3d4127b67c86eb12ffef67b63c7f283838360405161257293929190613f8e565b60405180910390a1505050565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6125ad6128b8565b73ffffffffffffffffffffffffffffffffffffffff166125cb611ccf565b73ffffffffffffffffffffffffffffffffffffffff1614612621576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161261890613b3c565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156014906126b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126ad9190613c8d565b60405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff16600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461273b5761273a600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660006122cc565b5b6127468160016122cc565b80600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fb2c924994d89e386dbc33539ddbfcf72af7ee9a346adadcfef588ee290f36f5c816040516127b691906134ca565b60405180910390a150565b6127c96128b8565b73ffffffffffffffffffffffffffffffffffffffff166127e7611ccf565b73ffffffffffffffffffffffffffffffffffffffff161461283d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161283490613b3c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036128ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128a390614037565b60405180910390fd5b6128b58161338f565b50565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361292f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612926906140c9565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361299e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129959061415b565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000612a2a3061177d565b9050600060095490506000818310159050808015612a555750600f60149054906101000a900460ff16155b8015612a6d5750600f60159054906101000a900460ff165b15612a7c57612a7b82610dd3565b5b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92586604051612ad9919061346e565b60405180910390a3505050505050565b60008183612af7919061417b565b905092915050565b60008183612b0d91906141ec565b905092915050565b60008183612b239190613985565b905092915050565b60008183612b39919061421d565b905092915050565b6000612b4d848461223f565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612bc75781811015612bb9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bb09061429d565b60405180910390fd5b612bc684848484036131c6565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612c3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c339061432f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612cab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ca2906143c1565b60405180910390fd5b60008111612cee576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ce59061442d565b60405180910390fd5b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612d74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d6b906144bf565b60405180910390fd5b6000829050600080601060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050601260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612e7557600a54612e288761177d565b86612e339190613985565b1115612e74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e6b9061452b565b60405180910390fd5b5b8080612ed1575060011515601060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515145b15613071578015612fae57601160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612fa957600754851115612f72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f6990614597565b60405180910390fd5b6000612f7d88611d8b565b905060648187612f8d919061417b565b612f9791906141ec565b92508284612fa5919061421d565b9350505b613070565b601160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661306f57600854851115613044576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161303b90614603565b60405180910390fd5b6064600b5486613054919061417b565b61305e91906141ec565b9150818361306c919061421d565b92505b5b5b8484036000808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600082111561310c57816000803073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b826000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef876040516131b5919061346e565b60405180910390a350505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603613235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161322c906140c9565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036132a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161329b9061415b565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051613382919061346e565b60405180910390a3505050565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000819050919050565b61346881613455565b82525050565b6000602082019050613483600083018461345f565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006134b482613489565b9050919050565b6134c4816134a9565b82525050565b60006020820190506134df60008301846134bb565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561351f578082015181840152602081019050613504565b60008484015250505050565b6000601f19601f8301169050919050565b6000613547826134e5565b61355181856134f0565b9350613561818560208601613501565b61356a8161352b565b840191505092915050565b6000602082019050818103600083015261358f818461353c565b905092915050565b600080fd5b6135a5816134a9565b81146135b057600080fd5b50565b6000813590506135c28161359c565b92915050565b6135d181613455565b81146135dc57600080fd5b50565b6000813590506135ee816135c8565b92915050565b6000806040838503121561360b5761360a613597565b5b6000613619858286016135b3565b925050602061362a858286016135df565b9150509250929050565b60008115159050919050565b61364981613634565b82525050565b60006020820190506136646000830184613640565b92915050565b6000806040838503121561368157613680613597565b5b600061368f858286016135df565b92505060206136a0858286016135df565b9150509250929050565b6000602082840312156136c0576136bf613597565b5b60006136ce848285016135df565b91505092915050565b6000602082840312156136ed576136ec613597565b5b60006136fb848285016135b3565b91505092915050565b60008060006060848603121561371d5761371c613597565b5b600061372b868287016135b3565b935050602061373c868287016135b3565b925050604061374d868287016135df565b9150509250925092565b600060ff82169050919050565b61376d81613757565b82525050565b60006020820190506137886000830184613764565b92915050565b61379781613634565b81146137a257600080fd5b50565b6000813590506137b48161378e565b92915050565b600080604083850312156137d1576137d0613597565b5b60006137df858286016135b3565b92505060206137f0858286016137a5565b9150509250929050565b600061380582613489565b9050919050565b613815816137fa565b82525050565b6000602082019050613830600083018461380c565b92915050565b60006020828403121561384c5761384b613597565b5b600061385a848285016137a5565b91505092915050565b6000806040838503121561387a57613879613597565b5b6000613888858286016135b3565b9250506020613899858286016135b3565b9150509250929050565b6000806000606084860312156138bc576138bb613597565b5b60006138ca868287016135df565b93505060206138db868287016135df565b92505060406138ec868287016135df565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061393d57607f821691505b6020821081036139505761394f6138f6565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061399082613455565b915061399b83613455565b92508282019050808211156139b3576139b2613956565b5b92915050565b6000819050919050565b6000819050919050565b60006139e86139e36139de846139b9565b6139c3565b613455565b9050919050565b6139f8816139cd565b82525050565b600060c082019050613a1360008301896134bb565b613a20602083018861345f565b613a2d60408301876139ef565b613a3a60608301866139ef565b613a4760808301856134bb565b613a5460a083018461345f565b979650505050505050565b600081519050613a6e816135c8565b92915050565b600080600060608486031215613a8d57613a8c613597565b5b6000613a9b86828701613a5f565b9350506020613aac86828701613a5f565b9250506040613abd86828701613a5f565b9150509250925092565b6000604082019050613adc600083018561345f565b613ae9602083018461345f565b9392505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613b266020836134f0565b9150613b3182613af0565b602082019050919050565b60006020820190508181036000830152613b5581613b19565b9050919050565b600060208284031215613b7257613b71613597565b5b6000613b8084828501613a5f565b91505092915050565b6000604082019050613b9e60008301856134bb565b613bab602083018461345f565b9392505050565b600081519050613bc18161378e565b92915050565b600060208284031215613bdd57613bdc613597565b5b6000613beb84828501613bb2565b91505092915050565b60008190508160005260206000209050919050565b60008154613c1681613925565b613c2081866134f0565b94506001821660008114613c3b5760018114613c5157613c84565b60ff198316865281151560200286019350613c84565b613c5a85613bf4565b60005b83811015613c7c57815481890152600182019150602081019050613c5d565b808801955050505b50505092915050565b60006020820190508181036000830152613ca78184613c09565b905092915050565b6000604082019050613cc460008301856134bb565b613cd16020830184613640565b9392505050565b7f496e76616c6964207461782076616c7565000000000000000000000000000000600082015250565b6000613d0e6011836134f0565b9150613d1982613cd8565b602082019050919050565b60006020820190508181036000830152613d3d81613d01565b9050919050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000613da06025836134f0565b9150613dab82613d44565b604082019050919050565b60006020820190508181036000830152613dcf81613d93565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050613e438161359c565b92915050565b600060208284031215613e5f57613e5e613597565b5b6000613e6d84828501613e34565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613eab816134a9565b82525050565b6000613ebd8383613ea2565b60208301905092915050565b6000602082019050919050565b6000613ee182613e76565b613eeb8185613e81565b9350613ef683613e92565b8060005b83811015613f27578151613f0e8882613eb1565b9750613f1983613ec9565b925050600181019050613efa565b5085935050505092915050565b600060a082019050613f49600083018861345f565b613f5660208301876139ef565b8181036040830152613f688186613ed6565b9050613f7760608301856134bb565b613f84608083018461345f565b9695505050505050565b6000606082019050613fa3600083018661345f565b613fb0602083018561345f565b613fbd604083018461345f565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006140216026836134f0565b915061402c82613fc5565b604082019050919050565b6000602082019050818103600083015261405081614014565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006140b36024836134f0565b91506140be82614057565b604082019050919050565b600060208201905081810360008301526140e2816140a6565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b60006141456022836134f0565b9150614150826140e9565b604082019050919050565b6000602082019050818103600083015261417481614138565b9050919050565b600061418682613455565b915061419183613455565b925082820261419f81613455565b915082820484148315176141b6576141b5613956565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006141f782613455565b915061420283613455565b925082614212576142116141bd565b5b828204905092915050565b600061422882613455565b915061423383613455565b925082820390508181111561424b5761424a613956565b5b92915050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b6000614287601d836134f0565b915061429282614251565b602082019050919050565b600060208201905081810360008301526142b68161427a565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b60006143196025836134f0565b9150614324826142bd565b604082019050919050565b600060208201905081810360008301526143488161430c565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b60006143ab6023836134f0565b91506143b68261434f565b604082019050919050565b600060208201905081810360008301526143da8161439e565b9050919050565b7f416d6f756e74206d75737420626520686967686572207468616e207a65726f00600082015250565b6000614417601f836134f0565b9150614422826143e1565b602082019050919050565b600060208201905081810360008301526144468161440a565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b60006144a96026836134f0565b91506144b48261444d565b604082019050919050565b600060208201905081810360008301526144d88161449c565b9050919050565b7f4d61782077616c6c657420657863656564656400000000000000000000000000600082015250565b60006145156013836134f0565b9150614520826144df565b602082019050919050565b6000602082019050818103600083015261454481614508565b9050919050565b7f4d61782073656c6c20616d6f756e742065786365656465640000000000000000600082015250565b60006145816018836134f0565b915061458c8261454b565b602082019050919050565b600060208201905081810360008301526145b081614574565b9050919050565b7f4d61782062757920616d6f756e74206578636565646564000000000000000000600082015250565b60006145ed6017836134f0565b91506145f8826145b7565b602082019050919050565b6000602082019050818103600083015261461c816145e0565b905091905056fea264697066735822122055304274efbf6606ea834f51f0dd433a2be3bbba0b7c36732d64b6ab52afbf6664736f6c63430008130033

Deployed Bytecode Sourcemap

42577:15082:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42895:60;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49951:109;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5053:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46850:333;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56116:566;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;54162:1203;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;6173:108;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43812:49;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57017:110;;;;;;;;;;;;;:::i;:::-;;43496:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8276:295;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57517:139;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;6015:93;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8980:263;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43868:45;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56690:319;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;42802:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43623:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43145:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53567:454;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42962:59;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50068:372;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47286:335;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;6344:143;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18090:94;;;;;;;;;;;;;:::i;:::-;;53319:240;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43388:101;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43926:53;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49004:501;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47801:369;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;17439:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5272:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50697:205;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;9746:498;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43986:56;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6693:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42722:73;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43233:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55373:735;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;17056:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54029:125;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;50448:241;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43306:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6974:176;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43028:53;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48302:398;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43088:50;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57135:374;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43351:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49513:430;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;18339:229;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;42895:60;;;;:::o;49951:109::-;50001:7;50036:15;;;;;;;;;;;50021:31;;49951:109;:::o;5053:100::-;5107:13;5140:5;5133:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5053:100;:::o;46850:333::-;46950:4;46967:13;46983:12;:10;:12::i;:::-;46967:28;;47119:34;47130:5;47137:7;47146:6;47119:10;:34::i;:::-;47171:4;47164:11;;;46850:333;;;;:::o;56116:566::-;56406:15;;;;;;;;;;;:31;;;56445:9;56478:4;56498:11;56524:1;56567;56610:7;:5;:7::i;:::-;56651:11;56633:15;:29;;;;:::i;:::-;56406:268;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;56116:566;;:::o;54162:1203::-;45126:4;45107:16;;:23;;;;;;;;;;;;;;;;;;54246:26:::1;54275:79;54350:3;54275:56;54314:16;;54275:20;:38;;:56;;;;:::i;:::-;:74;;:79;;;;:::i;:::-;54246:108;;54400:12;54415:25;54438:1;54415:18;:22;;:25;;;;:::i;:::-;54400:40;;54716:22;54741:21;54716:46;;54851;54868:28;54891:4;54868:18;:22;;:28;;;;:::i;:::-;54851:16;:46::i;:::-;54956:18;54977:43;55005:14;54978:21;54977:27;;:43;;;;:::i;:::-;54956:64;;55068:24;55095:29;55120:3;55096:18;55111:2;55096:10;:14;;:18;;;;:::i;:::-;55095:24;;:29;;;;:::i;:::-;55068:56;;55135:38;55150:4;55156:16;55135:14;:38::i;:::-;55243:15;;;;;;;;;;;:24;;:58;55268:32;55283:16;55268:10;:14;;:32;;;;:::i;:::-;55243:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;55319:38;55334:4;55340:16;55319:38;;;;;;;:::i;:::-;;;;;;;;54235:1130;;;;;45172:5:::0;45153:16;;:24;;;;;;;;;;;;;;;;;;54162:1203;:::o;6173:108::-;6234:7;6261:12;;6254:19;;6173:108;:::o;43812:49::-;;;;;;;;;;;;;;;;;;;;;;:::o;57017:110::-;17670:12;:10;:12::i;:::-;17659:23;;:7;:5;:7::i;:::-;:23;;;17651:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;57076:10:::1;57068:28;;:51;57097:21;57068:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;57017:110::o:0;43496:28::-;;;;;;;;;;;;;:::o;8276:295::-;8407:4;8424:15;8442:12;:10;:12::i;:::-;8424:30;;8465:38;8481:4;8487:7;8496:6;8465:15;:38::i;:::-;8514:27;8524:4;8530:2;8534:6;8514:9;:27::i;:::-;8559:4;8552:11;;;8276:295;;;;;:::o;57517:139::-;17670:12;:10;:12::i;:::-;17659:23;;:7;:5;:7::i;:::-;:23;;;17651:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;57598:10:::1;57589:6;:19;;;;57624:24;57637:10;57624:24;;;;;;:::i;:::-;;;;;;;;57517:139:::0;:::o;6015:93::-;6073:5;6098:2;6091:9;;6015:93;:::o;8980:263::-;9093:4;9110:13;9126:12;:10;:12::i;:::-;9110:28;;9149:64;9158:5;9165:7;9202:10;9174:25;9184:5;9191:7;9174:9;:25::i;:::-;:38;;;;:::i;:::-;9149:8;:64::i;:::-;9231:4;9224:11;;;8980:263;;;;:::o;43868:45::-;;;;;;;;;;;;;;;;;;;;;;:::o;56690:319::-;17670:12;:10;:12::i;:::-;17659:23;;:7;:5;:7::i;:::-;:23;;;17651:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;56857:4:::1;56832:30;;:13;:30;;::::0;56824:39:::1;;;::::0;::::1;;56881:13;56874:30;;;56919:10;56951:13;56944:31;;;56984:4;56944:46;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56874:127;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;56690:319:::0;:::o;42802:38::-;;;:::o;43623:33::-;;;;;;;;;;;;;:::o;43145:26::-;;;;:::o;53567:454::-;53610:20;53643:28;53674:24;53692:4;53674:9;:24::i;:::-;53643:55;;53709:20;53732:18;;53709:41;;53761:24;53812:12;53788:20;:36;;53761:63;;53850:19;:53;;;;;53887:16;;;;;;;;;;;53886:17;53850:53;:86;;;;;53935:1;53920:12;:16;53850:86;:131;;53980:1;53850:131;;;53952:12;53850:131;53835:146;;53994:19;;;53567:454;:::o;42962:59::-;;;;:::o;50068:372::-;50159:4;17670:12;:10;:12::i;:::-;17659:23;;:7;:5;:7::i;:::-;:23;;;17651:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;50176:22:::1;50209:15;;;;;;;;;;;50176:49;;50256:14;50244:26;;:8;:26;;;;50272:15;50236:52;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;50338:8;50301:15;;:46;;;;;;;;;;;;;;;;;;50395:14;50363:47;;50385:8;50363:47;;;;;;;;;;;;50428:4;50421:11;;;50068:372:::0;;;:::o;47286:335::-;17670:12;:10;:12::i;:::-;17659:23;;:7;:5;:7::i;:::-;:23;;;17651:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;47437:6:::1;47406:37;;:17;:27;47424:8;47406:27;;;;;;;;;;;;;;;;;;;;;;;;;:37;;;;47445:15;47398:63;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;47502:6;47472:17;:27;47490:8;47472:27;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;47519:42;47544:8;47554:6;47519:24;:42::i;:::-;47577:36;47596:8;47606:6;47577:36;;;;;;;:::i;:::-;;;;;;;;47286:335:::0;;:::o;6344:143::-;6434:7;6461:9;:18;6471:7;6461:18;;;;;;;;;;;;;;;;6454:25;;6344:143;;;:::o;18090:94::-;17670:12;:10;:12::i;:::-;17659:23;;:7;:5;:7::i;:::-;:23;;;17651:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;18155:21:::1;18173:1;18155:9;:21::i;:::-;18090:94::o:0;53319:240::-;17670:12;:10;:12::i;:::-;17659:23;;:7;:5;:7::i;:::-;:23;;;17651:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;53429:10:::1;53407:18;;:32;;53441:15;53399:58;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;53489:10;53468:18;:31;;;;53515:36;53540:10;53515:36;;;;;;:::i;:::-;;;;;;;;53319:240:::0;:::o;43388:101::-;;;;;;;;;;;;;:::o;43926:53::-;;;;;;;;;;;;;;;;;;;;;;:::o;49004:501::-;49250:15;;;;;;;;;;;49236:29;;:10;:29;;;49280:22;49128:185;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;49353:2;49332:18;:23;49324:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;49419:18;49388:21;:28;49410:5;49388:28;;;;;;;;;;;;;;;:49;;;;49453:44;49471:5;49478:18;49453:44;;;;;;;:::i;:::-;;;;;;;;49004:501;;:::o;47801:369::-;47918:7;:5;:7::i;:::-;47904:21;;:10;:21;;;:52;;;;47951:4;47929:27;;:10;:27;;;47904:52;47971:22;47882:122;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;48050:6;48023:33;;:13;:23;48037:8;48023:23;;;;;;;;;;;;;;;;;;;;;;;;;:33;;;;48058:15;48015:59;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;48111:6;48085:13;:23;48099:8;48085:23;;;;;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;48133:29;48145:8;48155:6;48133:29;;;;;;;:::i;:::-;;;;;;;;47801:369;;:::o;17439:87::-;17485:7;17512:6;;;;;;;;;;;17505:13;;17439:87;:::o;5272:104::-;5328:13;5361:7;5354:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5272:104;:::o;50697:205::-;50780:11;50804:15;50822:21;:28;50844:5;50822:28;;;;;;;;;;;;;;;;50804:46;;50878:1;50867:7;:12;:27;;50887:7;50867:27;;;50882:2;50867:27;50861:33;;50793:109;50697:205;;;:::o;9746:498::-;9864:4;9881:13;9897:12;:10;:12::i;:::-;9881:28;;9920:24;9947:25;9957:5;9964:7;9947:9;:25::i;:::-;9920:52;;10025:15;10005:16;:35;;9983:122;;;;;;;;;;;;:::i;:::-;;;;;;;;;10141:60;10150:5;10157:7;10185:15;10166:16;:34;10141:8;:60::i;:::-;10232:4;10225:11;;;;9746:498;;;;:::o;43986:56::-;;;;;;;;;;;;;;;;;:::o;6693:218::-;6797:4;6814:13;6830:12;:10;:12::i;:::-;6814:28;;6853;6863:5;6870:2;6874:6;6853:9;:28::i;:::-;6899:4;6892:11;;;6693:218;;;;:::o;42722:73::-;42753:42;42722:73;:::o;43233:36::-;;;;:::o;55373:735::-;55704:21;55742:1;55728:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55704:40;;55773:4;55755;55760:1;55755:7;;;;;;;;:::i;:::-;;;;;;;:23;;;;;;;;;;;55799:15;;;;;;;;;;;:20;;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55789:4;55794:1;55789:7;;;;;;;;:::i;:::-;;;;;;;:32;;;;;;;;;;;55860:15;;;;;;;;;;;:66;;;55941:11;55967:1;56011:4;56038;56077:11;56059:15;:29;;;;:::i;:::-;55860:240;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55427:681;55373:735;:::o;17056:21::-;;;;;;;;;;;;;:::o;54029:125::-;54110:36;54125:20;54110:14;:36::i;:::-;54029:125;:::o;50448:241::-;17670:12;:10;:12::i;:::-;17659:23;;:7;:5;:7::i;:::-;:23;;;17651:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;50558:8:::1;50533:33;;:21;;;;;;;;;;;:33;;;;50568:15;50525:59;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;50619:8;50595:21;;:32;;;;;;;;;;;;;;;;;;50643:38;50672:8;50643:38;;;;;;:::i;:::-;;;;;;;;50448:241:::0;:::o;43306:36::-;;;;:::o;6974:176::-;7088:7;7115:11;:18;7127:5;7115:18;;;;;;;;;;;;;;;:27;7134:7;7115:27;;;;;;;;;;;;;;;;7108:34;;6974:176;;;;:::o;43028:53::-;;;;:::o;48302:398::-;48428:4;48406:27;;:10;:27;;;:52;;;;48451:7;:5;:7::i;:::-;48437:21;;:10;:21;;;48406:52;48473:22;48384:122;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;48559:6;48525:40;;:21;:30;48547:7;48525:30;;;;;;;;;;;;;;;;;;;;;;;;;:40;;;;48567:15;48517:66;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;48627:6;48594:21;:30;48616:7;48594:30;;;;;;;;;;;;;;;;:39;;;;;;;;;;;;;;;;;;48649:43;48676:7;48685:6;48649:43;;;;;;;:::i;:::-;;;;;;;;48302:398;;:::o;43088:50::-;;;;:::o;57135:374::-;17670:12;:10;:12::i;:::-;17659:23;;:7;:5;:7::i;:::-;:23;;;17651:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;57322:10:::1;57296:23;:36;;;;57370:11;57343:24;:38;;;;57409:13;57392:14;:30;;;;57438:63;57462:11;57475:10;57487:13;57438:63;;;;;;;;:::i;:::-;;;;;;;;57135:374:::0;;;:::o;43351:30::-;;;;;;;;;;;;;:::o;49513:430::-;17670:12;:10;:12::i;:::-;17659:23;;:7;:5;:7::i;:::-;:23;;;17651:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;49643:11:::1;49624:30;;:15;;;;;;;;;;;:30;;;;49656:15;49616:56;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;49714:1;49687:29;;:15;;;;;;;;;;;:29;;;49683:110;;49733:48;49758:15;;;;;;;;;;;49775:5;49733:24;:48::i;:::-;49683:110;49803:43;49828:11;49841:4;49803:24;:43::i;:::-;49875:11;49857:15;;:29;;;;;;;;;;;;;;;;;;49902:33;49923:11;49902:33;;;;;;:::i;:::-;;;;;;;;49513:430:::0;:::o;18339:229::-;17670:12;:10;:12::i;:::-;17659:23;;:7;:5;:7::i;:::-;:23;;;17651:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;18462:1:::1;18442:22;;:8;:22;;::::0;18420:110:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;18541:19;18551:8;18541:9;:19::i;:::-;18339:229:::0;:::o;737:98::-;790:7;817:10;810:17;;737:98;:::o;46139:702::-;46286:1;46269:19;;:5;:19;;;46261:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;46367:1;46348:21;;:7;:21;;;46340:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;46449:6;46419:11;:18;46431:5;46419:18;;;;;;;;;;;;;;;:27;46438:7;46419:27;;;;;;;;;;;;;;;:36;;;;46468:28;46499:24;46517:4;46499:9;:24::i;:::-;46468:55;;46534:20;46557:18;;46534:41;;46586:24;46637:12;46613:20;:36;;46586:63;;46664:19;:40;;;;;46688:16;;;;;;;;;;;46687:17;46664:40;:65;;;;;46708:21;;;;;;;;;;;46664:65;46660:126;;;46746:28;46761:12;46746:14;:28::i;:::-;46660:126;46817:7;46801:32;;46810:5;46801:32;;;46826:6;46801:32;;;;;;:::i;:::-;;;;;;;;46250:591;;;46139:702;;;:::o;30284:98::-;30342:7;30373:1;30369;:5;;;;:::i;:::-;30362:12;;30284:98;;;;:::o;30683:::-;30741:7;30772:1;30768;:5;;;;:::i;:::-;30761:12;;30683:98;;;;:::o;29546:::-;29604:7;29635:1;29631;:5;;;;:::i;:::-;29624:12;;29546:98;;;;:::o;29927:::-;29985:7;30016:1;30012;:5;;;;:::i;:::-;30005:12;;29927:98;;;;:::o;14543:502::-;14678:24;14705:25;14715:5;14722:7;14705:9;:25::i;:::-;14678:52;;14765:17;14745:16;:37;14741:297;;14845:6;14825:16;:26;;14799:117;;;;;;;;;;;;:::i;:::-;;;;;;;;;14960:51;14969:5;14976:7;15004:6;14985:16;:25;14960:8;:51::i;:::-;14741:297;14667:378;14543:502;;;:::o;50910:2401::-;51058:1;51042:18;;:4;:18;;;51034:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;51135:1;51121:16;;:2;:16;;;51113:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;51205:1;51196:6;:10;51188:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;51253:19;51275:9;:15;51285:4;51275:15;;;;;;;;;;;;;;;;51253:37;;51338:6;51323:11;:21;;51301:109;;;;;;;;;;;;:::i;:::-;;;;;;;;;51421:22;51446:6;51421:31;;51463:17;51497:12;51512:17;:21;51530:2;51512:21;;;;;;;;;;;;;;;;;;;;;;;;;51497:36;;51549:21;:25;51571:2;51549:25;;;;;;;;;;;;;;;;;;;;;;;;;51544:180;;51643:14;;51626:13;51636:2;51626:9;:13::i;:::-;51617:6;:22;;;;:::i;:::-;:40;;51591:121;;;;;;;;;;;;:::i;:::-;;;;;;;;;51544:180;51809:7;:42;;;;51847:4;51820:31;;:17;:23;51838:4;51820:23;;;;;;;;;;;;;;;;;;;;;;;;;:31;;;51809:42;51805:1054;;;51872:7;51868:980;;;51905:13;:19;51919:4;51905:19;;;;;;;;;;;;;;;;;;;;;;;;;51900:576;;51993:24;;51983:6;:34;;51949:144;;;;;;;;;;;;:::i;:::-;;;;;;;;;52247:19;52269:18;52282:4;52269:12;:18::i;:::-;52247:40;;52403:3;52388:11;52379:6;:20;;;;:::i;:::-;52378:28;;;;:::i;:::-;52366:40;;52447:9;52429:27;;;;;:::i;:::-;;;51926:550;51900:576;51868:980;;;52521:13;:17;52535:2;52521:17;;;;;;;;;;;;;;;;;;;;;;;;;52516:317;;52607:23;;52597:6;:33;;52563:142;;;;;;;;;;;;:::i;:::-;;;;;;;;;52760:3;52750:6;;52741;:15;;;;:::i;:::-;52740:23;;;;:::i;:::-;52728:35;;52804:9;52786:27;;;;;:::i;:::-;;;52516:317;51868:980;51805:1054;52926:6;52912:11;:20;52894:9;:15;52904:4;52894:15;;;;;;;;;;;;;;;:38;;;;52965:1;52953:9;:13;52949:91;;;53015:9;52987;:24;53005:4;52987:24;;;;;;;;;;;;;;;;:37;;;;;;;;;;;52949:91;53236:14;53219:9;:13;53229:2;53219:13;;;;;;;;;;;;;;;;:31;;;;;;;;;;;53292:2;53277:26;;53286:4;53277:26;;;53296:6;53277:26;;;;;;:::i;:::-;;;;;;;;51023:2288;;;;50910:2401;;;:::o;13872:380::-;14025:1;14008:19;;:5;:19;;;14000:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;14106:1;14087:21;;:7;:21;;;14079:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;14190:6;14160:11;:18;14172:5;14160:18;;;;;;;;;;;;;;;:27;14179:7;14160:27;;;;;;;;;;;;;;;:36;;;;14228:7;14212:32;;14221:5;14212:32;;;14237:6;14212:32;;;;;;:::i;:::-;;;;;;;;13872:380;;;:::o;18576:173::-;18632:16;18651:6;;;;;;;;;;;18632:25;;18677:8;18668:6;;:17;;;;;;;;;;;;;;;;;;18732:8;18701:40;;18722:8;18701:40;;;;;;;;;;;;18621:128;18576:173;:::o;7:77:1:-;44:7;73:5;62:16;;7:77;;;:::o;90:118::-;177:24;195:5;177:24;:::i;:::-;172:3;165:37;90:118;;:::o;214:222::-;307:4;345:2;334:9;330:18;322:26;;358:71;426:1;415:9;411:17;402:6;358:71;:::i;:::-;214:222;;;;:::o;442:126::-;479:7;519:42;512:5;508:54;497:65;;442:126;;;:::o;574:96::-;611:7;640:24;658:5;640:24;:::i;:::-;629:35;;574:96;;;:::o;676:118::-;763:24;781:5;763:24;:::i;:::-;758:3;751:37;676:118;;:::o;800:222::-;893:4;931:2;920:9;916:18;908:26;;944:71;1012:1;1001:9;997:17;988:6;944:71;:::i;:::-;800:222;;;;:::o;1028:99::-;1080:6;1114:5;1108:12;1098:22;;1028:99;;;:::o;1133:169::-;1217:11;1251:6;1246:3;1239:19;1291:4;1286:3;1282:14;1267:29;;1133:169;;;;:::o;1308:246::-;1389:1;1399:113;1413:6;1410:1;1407:13;1399:113;;;1498:1;1493:3;1489:11;1483:18;1479:1;1474:3;1470:11;1463:39;1435:2;1432:1;1428:10;1423:15;;1399:113;;;1546:1;1537:6;1532:3;1528:16;1521:27;1370:184;1308:246;;;:::o;1560:102::-;1601:6;1652:2;1648:7;1643:2;1636:5;1632:14;1628:28;1618:38;;1560:102;;;:::o;1668:377::-;1756:3;1784:39;1817:5;1784:39;:::i;:::-;1839:71;1903:6;1898:3;1839:71;:::i;:::-;1832:78;;1919:65;1977:6;1972:3;1965:4;1958:5;1954:16;1919:65;:::i;:::-;2009:29;2031:6;2009:29;:::i;:::-;2004:3;2000:39;1993:46;;1760:285;1668:377;;;;:::o;2051:313::-;2164:4;2202:2;2191:9;2187:18;2179:26;;2251:9;2245:4;2241:20;2237:1;2226:9;2222:17;2215:47;2279:78;2352:4;2343:6;2279:78;:::i;:::-;2271:86;;2051:313;;;;:::o;2451:117::-;2560:1;2557;2550:12;2697:122;2770:24;2788:5;2770:24;:::i;:::-;2763:5;2760:35;2750:63;;2809:1;2806;2799:12;2750:63;2697:122;:::o;2825:139::-;2871:5;2909:6;2896:20;2887:29;;2925:33;2952:5;2925:33;:::i;:::-;2825:139;;;;:::o;2970:122::-;3043:24;3061:5;3043:24;:::i;:::-;3036:5;3033:35;3023:63;;3082:1;3079;3072:12;3023:63;2970:122;:::o;3098:139::-;3144:5;3182:6;3169:20;3160:29;;3198:33;3225:5;3198:33;:::i;:::-;3098:139;;;;:::o;3243:474::-;3311:6;3319;3368:2;3356:9;3347:7;3343:23;3339:32;3336:119;;;3374:79;;:::i;:::-;3336:119;3494:1;3519:53;3564:7;3555:6;3544:9;3540:22;3519:53;:::i;:::-;3509:63;;3465:117;3621:2;3647:53;3692:7;3683:6;3672:9;3668:22;3647:53;:::i;:::-;3637:63;;3592:118;3243:474;;;;;:::o;3723:90::-;3757:7;3800:5;3793:13;3786:21;3775:32;;3723:90;;;:::o;3819:109::-;3900:21;3915:5;3900:21;:::i;:::-;3895:3;3888:34;3819:109;;:::o;3934:210::-;4021:4;4059:2;4048:9;4044:18;4036:26;;4072:65;4134:1;4123:9;4119:17;4110:6;4072:65;:::i;:::-;3934:210;;;;:::o;4150:474::-;4218:6;4226;4275:2;4263:9;4254:7;4250:23;4246:32;4243:119;;;4281:79;;:::i;:::-;4243:119;4401:1;4426:53;4471:7;4462:6;4451:9;4447:22;4426:53;:::i;:::-;4416:63;;4372:117;4528:2;4554:53;4599:7;4590:6;4579:9;4575:22;4554:53;:::i;:::-;4544:63;;4499:118;4150:474;;;;;:::o;4630:329::-;4689:6;4738:2;4726:9;4717:7;4713:23;4709:32;4706:119;;;4744:79;;:::i;:::-;4706:119;4864:1;4889:53;4934:7;4925:6;4914:9;4910:22;4889:53;:::i;:::-;4879:63;;4835:117;4630:329;;;;:::o;4965:::-;5024:6;5073:2;5061:9;5052:7;5048:23;5044:32;5041:119;;;5079:79;;:::i;:::-;5041:119;5199:1;5224:53;5269:7;5260:6;5249:9;5245:22;5224:53;:::i;:::-;5214:63;;5170:117;4965:329;;;;:::o;5300:619::-;5377:6;5385;5393;5442:2;5430:9;5421:7;5417:23;5413:32;5410:119;;;5448:79;;:::i;:::-;5410:119;5568:1;5593:53;5638:7;5629:6;5618:9;5614:22;5593:53;:::i;:::-;5583:63;;5539:117;5695:2;5721:53;5766:7;5757:6;5746:9;5742:22;5721:53;:::i;:::-;5711:63;;5666:118;5823:2;5849:53;5894:7;5885:6;5874:9;5870:22;5849:53;:::i;:::-;5839:63;;5794:118;5300:619;;;;;:::o;5925:86::-;5960:7;6000:4;5993:5;5989:16;5978:27;;5925:86;;;:::o;6017:112::-;6100:22;6116:5;6100:22;:::i;:::-;6095:3;6088:35;6017:112;;:::o;6135:214::-;6224:4;6262:2;6251:9;6247:18;6239:26;;6275:67;6339:1;6328:9;6324:17;6315:6;6275:67;:::i;:::-;6135:214;;;;:::o;6355:116::-;6425:21;6440:5;6425:21;:::i;:::-;6418:5;6415:32;6405:60;;6461:1;6458;6451:12;6405:60;6355:116;:::o;6477:133::-;6520:5;6558:6;6545:20;6536:29;;6574:30;6598:5;6574:30;:::i;:::-;6477:133;;;;:::o;6616:468::-;6681:6;6689;6738:2;6726:9;6717:7;6713:23;6709:32;6706:119;;;6744:79;;:::i;:::-;6706:119;6864:1;6889:53;6934:7;6925:6;6914:9;6910:22;6889:53;:::i;:::-;6879:63;;6835:117;6991:2;7017:50;7059:7;7050:6;7039:9;7035:22;7017:50;:::i;:::-;7007:60;;6962:115;6616:468;;;;;:::o;7090:104::-;7135:7;7164:24;7182:5;7164:24;:::i;:::-;7153:35;;7090:104;;;:::o;7200:142::-;7303:32;7329:5;7303:32;:::i;:::-;7298:3;7291:45;7200:142;;:::o;7348:254::-;7457:4;7495:2;7484:9;7480:18;7472:26;;7508:87;7592:1;7581:9;7577:17;7568:6;7508:87;:::i;:::-;7348:254;;;;:::o;7608:323::-;7664:6;7713:2;7701:9;7692:7;7688:23;7684:32;7681:119;;;7719:79;;:::i;:::-;7681:119;7839:1;7864:50;7906:7;7897:6;7886:9;7882:22;7864:50;:::i;:::-;7854:60;;7810:114;7608:323;;;;:::o;7937:474::-;8005:6;8013;8062:2;8050:9;8041:7;8037:23;8033:32;8030:119;;;8068:79;;:::i;:::-;8030:119;8188:1;8213:53;8258:7;8249:6;8238:9;8234:22;8213:53;:::i;:::-;8203:63;;8159:117;8315:2;8341:53;8386:7;8377:6;8366:9;8362:22;8341:53;:::i;:::-;8331:63;;8286:118;7937:474;;;;;:::o;8417:619::-;8494:6;8502;8510;8559:2;8547:9;8538:7;8534:23;8530:32;8527:119;;;8565:79;;:::i;:::-;8527:119;8685:1;8710:53;8755:7;8746:6;8735:9;8731:22;8710:53;:::i;:::-;8700:63;;8656:117;8812:2;8838:53;8883:7;8874:6;8863:9;8859:22;8838:53;:::i;:::-;8828:63;;8783:118;8940:2;8966:53;9011:7;9002:6;8991:9;8987:22;8966:53;:::i;:::-;8956:63;;8911:118;8417:619;;;;;:::o;9042:180::-;9090:77;9087:1;9080:88;9187:4;9184:1;9177:15;9211:4;9208:1;9201:15;9228:320;9272:6;9309:1;9303:4;9299:12;9289:22;;9356:1;9350:4;9346:12;9377:18;9367:81;;9433:4;9425:6;9421:17;9411:27;;9367:81;9495:2;9487:6;9484:14;9464:18;9461:38;9458:84;;9514:18;;:::i;:::-;9458:84;9279:269;9228:320;;;:::o;9554:180::-;9602:77;9599:1;9592:88;9699:4;9696:1;9689:15;9723:4;9720:1;9713:15;9740:191;9780:3;9799:20;9817:1;9799:20;:::i;:::-;9794:25;;9833:20;9851:1;9833:20;:::i;:::-;9828:25;;9876:1;9873;9869:9;9862:16;;9897:3;9894:1;9891:10;9888:36;;;9904:18;;:::i;:::-;9888:36;9740:191;;;;:::o;9937:85::-;9982:7;10011:5;10000:16;;9937:85;;;:::o;10028:60::-;10056:3;10077:5;10070:12;;10028:60;;;:::o;10094:158::-;10152:9;10185:61;10203:42;10212:32;10238:5;10212:32;:::i;:::-;10203:42;:::i;:::-;10185:61;:::i;:::-;10172:74;;10094:158;;;:::o;10258:147::-;10353:45;10392:5;10353:45;:::i;:::-;10348:3;10341:58;10258:147;;:::o;10411:807::-;10660:4;10698:3;10687:9;10683:19;10675:27;;10712:71;10780:1;10769:9;10765:17;10756:6;10712:71;:::i;:::-;10793:72;10861:2;10850:9;10846:18;10837:6;10793:72;:::i;:::-;10875:80;10951:2;10940:9;10936:18;10927:6;10875:80;:::i;:::-;10965;11041:2;11030:9;11026:18;11017:6;10965:80;:::i;:::-;11055:73;11123:3;11112:9;11108:19;11099:6;11055:73;:::i;:::-;11138;11206:3;11195:9;11191:19;11182:6;11138:73;:::i;:::-;10411:807;;;;;;;;;:::o;11224:143::-;11281:5;11312:6;11306:13;11297:22;;11328:33;11355:5;11328:33;:::i;:::-;11224:143;;;;:::o;11373:663::-;11461:6;11469;11477;11526:2;11514:9;11505:7;11501:23;11497:32;11494:119;;;11532:79;;:::i;:::-;11494:119;11652:1;11677:64;11733:7;11724:6;11713:9;11709:22;11677:64;:::i;:::-;11667:74;;11623:128;11790:2;11816:64;11872:7;11863:6;11852:9;11848:22;11816:64;:::i;:::-;11806:74;;11761:129;11929:2;11955:64;12011:7;12002:6;11991:9;11987:22;11955:64;:::i;:::-;11945:74;;11900:129;11373:663;;;;;:::o;12042:332::-;12163:4;12201:2;12190:9;12186:18;12178:26;;12214:71;12282:1;12271:9;12267:17;12258:6;12214:71;:::i;:::-;12295:72;12363:2;12352:9;12348:18;12339:6;12295:72;:::i;:::-;12042:332;;;;;:::o;12380:182::-;12520:34;12516:1;12508:6;12504:14;12497:58;12380:182;:::o;12568:366::-;12710:3;12731:67;12795:2;12790:3;12731:67;:::i;:::-;12724:74;;12807:93;12896:3;12807:93;:::i;:::-;12925:2;12920:3;12916:12;12909:19;;12568:366;;;:::o;12940:419::-;13106:4;13144:2;13133:9;13129:18;13121:26;;13193:9;13187:4;13183:20;13179:1;13168:9;13164:17;13157:47;13221:131;13347:4;13221:131;:::i;:::-;13213:139;;12940:419;;;:::o;13365:351::-;13435:6;13484:2;13472:9;13463:7;13459:23;13455:32;13452:119;;;13490:79;;:::i;:::-;13452:119;13610:1;13635:64;13691:7;13682:6;13671:9;13667:22;13635:64;:::i;:::-;13625:74;;13581:128;13365:351;;;;:::o;13722:332::-;13843:4;13881:2;13870:9;13866:18;13858:26;;13894:71;13962:1;13951:9;13947:17;13938:6;13894:71;:::i;:::-;13975:72;14043:2;14032:9;14028:18;14019:6;13975:72;:::i;:::-;13722:332;;;;;:::o;14060:137::-;14114:5;14145:6;14139:13;14130:22;;14161:30;14185:5;14161:30;:::i;:::-;14060:137;;;;:::o;14203:345::-;14270:6;14319:2;14307:9;14298:7;14294:23;14290:32;14287:119;;;14325:79;;:::i;:::-;14287:119;14445:1;14470:61;14523:7;14514:6;14503:9;14499:22;14470:61;:::i;:::-;14460:71;;14416:125;14203:345;;;;:::o;14554:141::-;14603:4;14626:3;14618:11;;14649:3;14646:1;14639:14;14683:4;14680:1;14670:18;14662:26;;14554:141;;;:::o;14725:831::-;14810:3;14847:5;14841:12;14876:36;14902:9;14876:36;:::i;:::-;14928:71;14992:6;14987:3;14928:71;:::i;:::-;14921:78;;15030:1;15019:9;15015:17;15046:1;15041:164;;;;15219:1;15214:336;;;;15008:542;;15041:164;15125:4;15121:9;15110;15106:25;15101:3;15094:38;15185:6;15178:14;15171:22;15165:4;15161:33;15156:3;15152:43;15145:50;;15041:164;;15214:336;15281:38;15313:5;15281:38;:::i;:::-;15341:1;15355:154;15369:6;15366:1;15363:13;15355:154;;;15443:7;15437:14;15433:1;15428:3;15424:11;15417:35;15493:1;15484:7;15480:15;15469:26;;15391:4;15388:1;15384:12;15379:17;;15355:154;;;15538:1;15533:3;15529:11;15522:18;;15221:329;;15008:542;;14814:742;;14725:831;;;;:::o;15562:307::-;15672:4;15710:2;15699:9;15695:18;15687:26;;15759:9;15753:4;15749:20;15745:1;15734:9;15730:17;15723:47;15787:75;15857:4;15848:6;15787:75;:::i;:::-;15779:83;;15562:307;;;;:::o;15875:320::-;15990:4;16028:2;16017:9;16013:18;16005:26;;16041:71;16109:1;16098:9;16094:17;16085:6;16041:71;:::i;:::-;16122:66;16184:2;16173:9;16169:18;16160:6;16122:66;:::i;:::-;15875:320;;;;;:::o;16201:167::-;16341:19;16337:1;16329:6;16325:14;16318:43;16201:167;:::o;16374:366::-;16516:3;16537:67;16601:2;16596:3;16537:67;:::i;:::-;16530:74;;16613:93;16702:3;16613:93;:::i;:::-;16731:2;16726:3;16722:12;16715:19;;16374:366;;;:::o;16746:419::-;16912:4;16950:2;16939:9;16935:18;16927:26;;16999:9;16993:4;16989:20;16985:1;16974:9;16970:17;16963:47;17027:131;17153:4;17027:131;:::i;:::-;17019:139;;16746:419;;;:::o;17171:224::-;17311:34;17307:1;17299:6;17295:14;17288:58;17380:7;17375:2;17367:6;17363:15;17356:32;17171:224;:::o;17401:366::-;17543:3;17564:67;17628:2;17623:3;17564:67;:::i;:::-;17557:74;;17640:93;17729:3;17640:93;:::i;:::-;17758:2;17753:3;17749:12;17742:19;;17401:366;;;:::o;17773:419::-;17939:4;17977:2;17966:9;17962:18;17954:26;;18026:9;18020:4;18016:20;18012:1;18001:9;17997:17;17990:47;18054:131;18180:4;18054:131;:::i;:::-;18046:139;;17773:419;;;:::o;18198:180::-;18246:77;18243:1;18236:88;18343:4;18340:1;18333:15;18367:4;18364:1;18357:15;18384:180;18432:77;18429:1;18422:88;18529:4;18526:1;18519:15;18553:4;18550:1;18543:15;18570:143;18627:5;18658:6;18652:13;18643:22;;18674:33;18701:5;18674:33;:::i;:::-;18570:143;;;;:::o;18719:351::-;18789:6;18838:2;18826:9;18817:7;18813:23;18809:32;18806:119;;;18844:79;;:::i;:::-;18806:119;18964:1;18989:64;19045:7;19036:6;19025:9;19021:22;18989:64;:::i;:::-;18979:74;;18935:128;18719:351;;;;:::o;19076:114::-;19143:6;19177:5;19171:12;19161:22;;19076:114;;;:::o;19196:184::-;19295:11;19329:6;19324:3;19317:19;19369:4;19364:3;19360:14;19345:29;;19196:184;;;;:::o;19386:132::-;19453:4;19476:3;19468:11;;19506:4;19501:3;19497:14;19489:22;;19386:132;;;:::o;19524:108::-;19601:24;19619:5;19601:24;:::i;:::-;19596:3;19589:37;19524:108;;:::o;19638:179::-;19707:10;19728:46;19770:3;19762:6;19728:46;:::i;:::-;19806:4;19801:3;19797:14;19783:28;;19638:179;;;;:::o;19823:113::-;19893:4;19925;19920:3;19916:14;19908:22;;19823:113;;;:::o;19972:732::-;20091:3;20120:54;20168:5;20120:54;:::i;:::-;20190:86;20269:6;20264:3;20190:86;:::i;:::-;20183:93;;20300:56;20350:5;20300:56;:::i;:::-;20379:7;20410:1;20395:284;20420:6;20417:1;20414:13;20395:284;;;20496:6;20490:13;20523:63;20582:3;20567:13;20523:63;:::i;:::-;20516:70;;20609:60;20662:6;20609:60;:::i;:::-;20599:70;;20455:224;20442:1;20439;20435:9;20430:14;;20395:284;;;20399:14;20695:3;20688:10;;20096:608;;;19972:732;;;;:::o;20710:831::-;20973:4;21011:3;21000:9;20996:19;20988:27;;21025:71;21093:1;21082:9;21078:17;21069:6;21025:71;:::i;:::-;21106:80;21182:2;21171:9;21167:18;21158:6;21106:80;:::i;:::-;21233:9;21227:4;21223:20;21218:2;21207:9;21203:18;21196:48;21261:108;21364:4;21355:6;21261:108;:::i;:::-;21253:116;;21379:72;21447:2;21436:9;21432:18;21423:6;21379:72;:::i;:::-;21461:73;21529:3;21518:9;21514:19;21505:6;21461:73;:::i;:::-;20710:831;;;;;;;;:::o;21547:442::-;21696:4;21734:2;21723:9;21719:18;21711:26;;21747:71;21815:1;21804:9;21800:17;21791:6;21747:71;:::i;:::-;21828:72;21896:2;21885:9;21881:18;21872:6;21828:72;:::i;:::-;21910;21978:2;21967:9;21963:18;21954:6;21910:72;:::i;:::-;21547:442;;;;;;:::o;21995:225::-;22135:34;22131:1;22123:6;22119:14;22112:58;22204:8;22199:2;22191:6;22187:15;22180:33;21995:225;:::o;22226:366::-;22368:3;22389:67;22453:2;22448:3;22389:67;:::i;:::-;22382:74;;22465:93;22554:3;22465:93;:::i;:::-;22583:2;22578:3;22574:12;22567:19;;22226:366;;;:::o;22598:419::-;22764:4;22802:2;22791:9;22787:18;22779:26;;22851:9;22845:4;22841:20;22837:1;22826:9;22822:17;22815:47;22879:131;23005:4;22879:131;:::i;:::-;22871:139;;22598:419;;;:::o;23023:223::-;23163:34;23159:1;23151:6;23147:14;23140:58;23232:6;23227:2;23219:6;23215:15;23208:31;23023:223;:::o;23252:366::-;23394:3;23415:67;23479:2;23474:3;23415:67;:::i;:::-;23408:74;;23491:93;23580:3;23491:93;:::i;:::-;23609:2;23604:3;23600:12;23593:19;;23252:366;;;:::o;23624:419::-;23790:4;23828:2;23817:9;23813:18;23805:26;;23877:9;23871:4;23867:20;23863:1;23852:9;23848:17;23841:47;23905:131;24031:4;23905:131;:::i;:::-;23897:139;;23624:419;;;:::o;24049:221::-;24189:34;24185:1;24177:6;24173:14;24166:58;24258:4;24253:2;24245:6;24241:15;24234:29;24049:221;:::o;24276:366::-;24418:3;24439:67;24503:2;24498:3;24439:67;:::i;:::-;24432:74;;24515:93;24604:3;24515:93;:::i;:::-;24633:2;24628:3;24624:12;24617:19;;24276:366;;;:::o;24648:419::-;24814:4;24852:2;24841:9;24837:18;24829:26;;24901:9;24895:4;24891:20;24887:1;24876:9;24872:17;24865:47;24929:131;25055:4;24929:131;:::i;:::-;24921:139;;24648:419;;;:::o;25073:410::-;25113:7;25136:20;25154:1;25136:20;:::i;:::-;25131:25;;25170:20;25188:1;25170:20;:::i;:::-;25165:25;;25225:1;25222;25218:9;25247:30;25265:11;25247:30;:::i;:::-;25236:41;;25426:1;25417:7;25413:15;25410:1;25407:22;25387:1;25380:9;25360:83;25337:139;;25456:18;;:::i;:::-;25337:139;25121:362;25073:410;;;;:::o;25489:180::-;25537:77;25534:1;25527:88;25634:4;25631:1;25624:15;25658:4;25655:1;25648:15;25675:185;25715:1;25732:20;25750:1;25732:20;:::i;:::-;25727:25;;25766:20;25784:1;25766:20;:::i;:::-;25761:25;;25805:1;25795:35;;25810:18;;:::i;:::-;25795:35;25852:1;25849;25845:9;25840:14;;25675:185;;;;:::o;25866:194::-;25906:4;25926:20;25944:1;25926:20;:::i;:::-;25921:25;;25960:20;25978:1;25960:20;:::i;:::-;25955:25;;26004:1;26001;25997:9;25989:17;;26028:1;26022:4;26019:11;26016:37;;;26033:18;;:::i;:::-;26016:37;25866:194;;;;:::o;26066:179::-;26206:31;26202:1;26194:6;26190:14;26183:55;26066:179;:::o;26251:366::-;26393:3;26414:67;26478:2;26473:3;26414:67;:::i;:::-;26407:74;;26490:93;26579:3;26490:93;:::i;:::-;26608:2;26603:3;26599:12;26592:19;;26251:366;;;:::o;26623:419::-;26789:4;26827:2;26816:9;26812:18;26804:26;;26876:9;26870:4;26866:20;26862:1;26851:9;26847:17;26840:47;26904:131;27030:4;26904:131;:::i;:::-;26896:139;;26623:419;;;:::o;27048:224::-;27188:34;27184:1;27176:6;27172:14;27165:58;27257:7;27252:2;27244:6;27240:15;27233:32;27048:224;:::o;27278:366::-;27420:3;27441:67;27505:2;27500:3;27441:67;:::i;:::-;27434:74;;27517:93;27606:3;27517:93;:::i;:::-;27635:2;27630:3;27626:12;27619:19;;27278:366;;;:::o;27650:419::-;27816:4;27854:2;27843:9;27839:18;27831:26;;27903:9;27897:4;27893:20;27889:1;27878:9;27874:17;27867:47;27931:131;28057:4;27931:131;:::i;:::-;27923:139;;27650:419;;;:::o;28075:222::-;28215:34;28211:1;28203:6;28199:14;28192:58;28284:5;28279:2;28271:6;28267:15;28260:30;28075:222;:::o;28303:366::-;28445:3;28466:67;28530:2;28525:3;28466:67;:::i;:::-;28459:74;;28542:93;28631:3;28542:93;:::i;:::-;28660:2;28655:3;28651:12;28644:19;;28303:366;;;:::o;28675:419::-;28841:4;28879:2;28868:9;28864:18;28856:26;;28928:9;28922:4;28918:20;28914:1;28903:9;28899:17;28892:47;28956:131;29082:4;28956:131;:::i;:::-;28948:139;;28675:419;;;:::o;29100:181::-;29240:33;29236:1;29228:6;29224:14;29217:57;29100:181;:::o;29287:366::-;29429:3;29450:67;29514:2;29509:3;29450:67;:::i;:::-;29443:74;;29526:93;29615:3;29526:93;:::i;:::-;29644:2;29639:3;29635:12;29628:19;;29287:366;;;:::o;29659:419::-;29825:4;29863:2;29852:9;29848:18;29840:26;;29912:9;29906:4;29902:20;29898:1;29887:9;29883:17;29876:47;29940:131;30066:4;29940:131;:::i;:::-;29932:139;;29659:419;;;:::o;30084:225::-;30224:34;30220:1;30212:6;30208:14;30201:58;30293:8;30288:2;30280:6;30276:15;30269:33;30084:225;:::o;30315:366::-;30457:3;30478:67;30542:2;30537:3;30478:67;:::i;:::-;30471:74;;30554:93;30643:3;30554:93;:::i;:::-;30672:2;30667:3;30663:12;30656:19;;30315:366;;;:::o;30687:419::-;30853:4;30891:2;30880:9;30876:18;30868:26;;30940:9;30934:4;30930:20;30926:1;30915:9;30911:17;30904:47;30968:131;31094:4;30968:131;:::i;:::-;30960:139;;30687:419;;;:::o;31112:169::-;31252:21;31248:1;31240:6;31236:14;31229:45;31112:169;:::o;31287:366::-;31429:3;31450:67;31514:2;31509:3;31450:67;:::i;:::-;31443:74;;31526:93;31615:3;31526:93;:::i;:::-;31644:2;31639:3;31635:12;31628:19;;31287:366;;;:::o;31659:419::-;31825:4;31863:2;31852:9;31848:18;31840:26;;31912:9;31906:4;31902:20;31898:1;31887:9;31883:17;31876:47;31940:131;32066:4;31940:131;:::i;:::-;31932:139;;31659:419;;;:::o;32084:174::-;32224:26;32220:1;32212:6;32208:14;32201:50;32084:174;:::o;32264:366::-;32406:3;32427:67;32491:2;32486:3;32427:67;:::i;:::-;32420:74;;32503:93;32592:3;32503:93;:::i;:::-;32621:2;32616:3;32612:12;32605:19;;32264:366;;;:::o;32636:419::-;32802:4;32840:2;32829:9;32825:18;32817:26;;32889:9;32883:4;32879:20;32875:1;32864:9;32860:17;32853:47;32917:131;33043:4;32917:131;:::i;:::-;32909:139;;32636:419;;;:::o;33061:173::-;33201:25;33197:1;33189:6;33185:14;33178:49;33061:173;:::o;33240:366::-;33382:3;33403:67;33467:2;33462:3;33403:67;:::i;:::-;33396:74;;33479:93;33568:3;33479:93;:::i;:::-;33597:2;33592:3;33588:12;33581:19;;33240:366;;;:::o;33612:419::-;33778:4;33816:2;33805:9;33801:18;33793:26;;33865:9;33859:4;33855:20;33851:1;33840:9;33836:17;33829:47;33893:131;34019:4;33893:131;:::i;:::-;33885:139;;33612:419;;;:::o

Swarm Source

ipfs://55304274efbf6606ea834f51f0dd433a2be3bbba0b7c36732d64b6ab52afbf66
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.