ETH Price: $3,400.63 (-1.09%)
Gas: 7 Gwei

Token

PLUTUS CAPITAL HOLDINGS (PCH)
 

Overview

Max Total Supply

1,000,000,000 PCH

Holders

93

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Filtered by Token Holder
ethereumint.eth
Balance
1,121,599.676 PCH

Value
$0.00
0x9a5e6ed758a57267b52351caf966ba98180be4d9
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:
PLUTUS

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 2 of 2: Plutus.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
pragma experimental ABIEncoderV2;

import "./DividendTracker.sol";

contract PLUTUS is Ownable, IERC20 {
    address UNISWAPROUTER = address(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
    address DEAD = 0x000000000000000000000000000000000000dEaD;
    address ZERO = 0x0000000000000000000000000000000000000000;

    string private _name = "PLUTUS CAPITAL HOLDINGS";
    string private _symbol = "PCH";

    // Allocations
    uint256 public _tokenomicsTokenAllocation;
    uint256 public _liquidityTokenAllocation;
    uint256 public _dividendsTokenAllocation;

    // Fess
    uint256 public tokenomicsFeeBuyBPS = 600;
    uint256 public liquidityFeeBuyBPS = 100;
    uint256 public dividendFeeBuyBPS = 300;
    uint256 public tokenomicsFeeSellBPS = 1900;
    uint256 public liquidityFeeSellBPS = 100;
    uint256 public dividendFeeSellBPS = 0;
    uint256 public totalFeeBPS =
        tokenomicsFeeBuyBPS +
            liquidityFeeBuyBPS +
            dividendFeeBuyBPS;

    uint256 public swapTokensAtAmount = 100000 * (10**18);
    uint256 public lastSwapTime;
    bool swapAllToken = true;

    bool public swapEnabled = true;
    bool public taxEnabled = true;
    bool public compoundingEnabled = true;

    uint256 private _totalSupply = 1000000000 * (10**18);
    bool private swapping;

    address payable public tokenomicsWallet =
        payable(0x20308B8986D45A1EB50757e03f4DdDD15b22FB0F);

    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;
    mapping(address => bool) private _isExcludedFromFees;
    mapping(address => bool) private _whiteList;
    mapping(address => bool) isBlacklisted;
    mapping(address => bool) private _isExcludedFromMaxTx;
    mapping(address => bool) private _isExcludedFromMaxWallet;

    event SwapAndAddLiquidity(
        uint256 tokensSwapped,
        uint256 nativeReceived,
        uint256 tokensIntoLiquidity
    );
    event SendDividends(uint256 tokensSwapped, uint256 amount);
    event ExcludeFromFees(address indexed account, bool isExcluded);
    event SetAutomatedMarketMakerPair(address indexed pair, bool indexed value);
    event UpdateUniswapV2Router(
        address indexed newAddress,
        address indexed oldAddress
    );
    event SwapEnabled(bool enabled);
    event TaxEnabled(bool enabled);
    event CompoundingEnabled(bool enabled);
    event BlacklistEnabled(bool enabled);

    DividendTracker public dividendTracker;
    IUniswapV2Router02 public uniswapV2Router;

    address public uniswapV2Pair;

    uint256 public maxTxBPS = 50;
    uint256 public maxWalletBPS = 200;

    uint256 tradingOpenDate = 1649279774;

    constructor() {
        dividendTracker = new DividendTracker(address(this), UNISWAPROUTER);

        IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(UNISWAPROUTER);

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

        uniswapV2Router = _uniswapV2Router;
        uniswapV2Pair = _uniswapV2Pair;

        _balances[_msgSender()] += _totalSupply;
        emit Transfer(address(0), _msgSender(), _totalSupply);
    }

    function name() public view returns (string memory) {
        return _name;
    }

    function symbol() public view returns (string memory) {
        return _symbol;
    }

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

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

    function balanceOf(address account)
        public
        view
        virtual
        override
        returns (uint256)
    {
        return _balances[account];
    }

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

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

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

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

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

    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(
            currentAllowance >= amount,
            "PLUTUS: transfer amount exceeds allowance"
        );
        _approve(sender, _msgSender(), currentAllowance - amount);
        return true;
    }

    function setParametersToLaunch() external onlyOwner {
        dividendTracker.excludeFromDividends(address(dividendTracker), true);
        dividendTracker.excludeFromDividends(address(this), true);
        dividendTracker.excludeFromDividends(owner(), true);
        dividendTracker.excludeFromDividends(address(uniswapV2Router), true);
        dividendTracker.excludeFromDividends(address(DEAD), true);

        excludeFromFees(owner(), true);
        excludeFromFees(address(this), true);
        excludeFromFees(address(dividendTracker), true);

        excludeFromMaxTx(owner(), true);
        excludeFromMaxTx(address(this), true);
        excludeFromMaxTx(address(dividendTracker), true);

        excludeFromMaxWallet(owner(), true);
        excludeFromMaxWallet(address(this), true);
        excludeFromMaxWallet(address(dividendTracker), true);
    }

    function setTradingOpenDate(uint256 timestamp) external onlyOwner {
        tradingOpenDate = timestamp;
    }

    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal {
        require(
            tradingOpenDate < block.timestamp ||
                sender == owner() ||
                recipient == owner() ||
                _whiteList[sender] ||
                _whiteList[recipient],
            "PLUTUS: Token isn't tradable yet"
        );

        require(!isBlacklisted[sender], "PLUTUS: Sender is blacklisted");
        require(!isBlacklisted[recipient], "PLUTUS: Recipient is blacklisted");

        require(sender != address(0), "PLUTUS: transfer from the zero address");
        require(
            recipient != address(0),
            "PLUTUS: transfer to the zero address"
        );

        uint256 _maxTxAmount = (totalSupply() * maxTxBPS) / 10000;
        uint256 _maxWallet = (totalSupply() * maxWalletBPS) / 10000;
        require(
            amount <= _maxTxAmount || _isExcludedFromMaxTx[sender],
            "TX Limit Exceeded"
        );

        if (
            sender != owner() &&
            recipient != address(this) &&
            recipient != address(DEAD) &&
            recipient != uniswapV2Pair
        ) {
            uint256 currentBalance = balanceOf(recipient);
            require(
                _isExcludedFromMaxWallet[recipient] ||
                    (currentBalance + amount <= _maxWallet)
            );
        }

        uint256 senderBalance = _balances[sender];
        require(
            senderBalance >= amount,
            "PLUTUS: transfer amount exceeds balance"
        );

        uint256 contractTokenBalance = balanceOf(address(this));
        uint256 contractNativeBalance = address(this).balance;

        bool canSwap = contractTokenBalance >= swapTokensAtAmount;

        if (
            swapEnabled &&
            canSwap &&
            !swapping &&
            sender != address(uniswapV2Router) &&
            sender != owner() &&
            recipient != owner()
        ) {
            swapping = true;

            if (!swapAllToken && contractTokenBalance > swapTokensAtAmount) {
                contractTokenBalance = swapTokensAtAmount;
            }
            _executeSwap(contractTokenBalance, contractNativeBalance);

            lastSwapTime = block.timestamp;
            swapping = false;
        }

        bool takeFee = false;

        if (
            (sender == address(uniswapV2Pair) &&
                recipient != address(uniswapV2Router)) ||
            (recipient == address(uniswapV2Pair) &&
                sender != address(uniswapV2Router))
        ) {
            takeFee = true;
        }

        if (_isExcludedFromFees[sender] || _isExcludedFromFees[recipient]) {
            takeFee = false;
        }

        if (swapping || !taxEnabled) {
            takeFee = false;
        }

        if (takeFee) {
            //Set Fee for Buys
            if (sender == uniswapV2Pair) {
                totalFeeBPS =
                    tokenomicsFeeBuyBPS +
                    liquidityFeeBuyBPS +
                    dividendFeeBuyBPS;

                _tokenomicsTokenAllocation =
                    (amount * tokenomicsFeeBuyBPS) /
                    totalFeeBPS;
                _liquidityTokenAllocation =
                    (amount * liquidityFeeBuyBPS) /
                    totalFeeBPS;
                _dividendsTokenAllocation =
                    (amount * dividendFeeBuyBPS) /
                    totalFeeBPS;
            }

            //Set Fee for Sells
            if (recipient == uniswapV2Pair) {
                totalFeeBPS =
                    tokenomicsFeeSellBPS +
                    liquidityFeeSellBPS +
                    dividendFeeSellBPS;

                _tokenomicsTokenAllocation =
                    (amount * tokenomicsFeeSellBPS) /
                    totalFeeBPS;
                _liquidityTokenAllocation =
                    (amount * liquidityFeeSellBPS) /
                    totalFeeBPS;
                _dividendsTokenAllocation =
                    (amount * dividendFeeSellBPS) /
                    totalFeeBPS;
            }

            uint256 fees = (amount * totalFeeBPS) / 10000;
            amount -= fees;
            _executeTransfer(sender, address(this), fees);
        }

        _executeTransfer(sender, recipient, amount);

        dividendTracker.setBalance(payable(sender), balanceOf(sender));
        dividendTracker.setBalance(payable(recipient), balanceOf(recipient));
    }

    function _executeTransfer(
        address sender,
        address recipient,
        uint256 amount
    ) private {
        require(sender != address(0), "PLUTUS: transfer from the zero address");
        require(
            recipient != address(0),
            "PLUTUS: transfer to the zero address"
        );
        uint256 senderBalance = _balances[sender];
        require(
            senderBalance >= amount,
            "PLUTUS: transfer amount exceeds balance"
        );
        _balances[sender] = senderBalance - amount;
        _balances[recipient] += amount;
        emit Transfer(sender, recipient, amount);
    }

    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) private {
        require(owner != address(0), "PLUTUS: approve from the zero address");
        require(spender != address(0), "PLUTUS: approve to the zero address");
        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    function swapTokensForNative(uint256 tokens) private {
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = uniswapV2Router.WETH();
        _approve(address(this), address(uniswapV2Router), tokens);
        uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokens,
            0, // accept any amount of native
            path,
            address(this),
            block.timestamp
        );
    }

    function addLiquidity(uint256 tokens, uint256 native) private {
        _approve(address(this), address(uniswapV2Router), tokens);
        uniswapV2Router.addLiquidityETH{value: native}(
            address(this),
            tokens,
            0, // slippage unavoidable
            0, // slippage unavoidable
            address(this),
            block.timestamp
        );
    }

    function includeToWhiteList(address[] memory _users) public onlyOwner {
        for (uint8 i = 0; i < _users.length; i++) {
            _whiteList[_users[i]] = true;
        }
    }

    function _executeSwap(uint256 tokens, uint256 native) private {
        if (tokens <= 0) {
            return;
        }

        uint256 totalAllocation = _tokenomicsTokenAllocation +
            _liquidityTokenAllocation +
            _dividendsTokenAllocation;

        // Calculations below might seem redundant, but we need them in case tokens < contract token balance
        uint256 tokensForTokenomics;
        if (address(tokenomicsWallet) != address(0)) {
            tokensForTokenomics =
                (tokens * _tokenomicsTokenAllocation) /
                totalAllocation;
        }

        uint256 tokensForDividends;
        if (dividendTracker.totalSupply() > 0) {
            tokensForDividends =
                (tokens * _dividendsTokenAllocation) /
                totalAllocation;
        }

        uint256 tokensForLiquidity = tokens -
            tokensForTokenomics-
            tokensForDividends;
        uint256 swapTokensLiquidity = tokensForLiquidity / 2;
        uint256 addTokensLiquidity = tokensForLiquidity - swapTokensLiquidity;
        uint256 swapTokensTotal = tokensForTokenomics +
            tokensForDividends +
            swapTokensLiquidity;

        uint256 initNativeBal = address(this).balance;
        swapTokensForNative(swapTokensTotal);
        uint256 nativeSwapped = (address(this).balance - initNativeBal) +
            native;

        uint256 nativeTokenomics = (nativeSwapped * tokensForTokenomics) /
            swapTokensTotal;
        uint256 nativeDividends = (nativeSwapped * tokensForDividends) /
            swapTokensTotal;
        uint256 nativeLiquidity = nativeSwapped -
            nativeTokenomics -
            nativeDividends;

        // Send tokens to treasury
        if (nativeTokenomics > 0) {
            (bool success, ) = tokenomicsWallet.call{value: nativeTokenomics}("");
            require(success, "PLUTUS: Tx failed.");
        }

        // Add liquidity
        addLiquidity(addTokensLiquidity, nativeLiquidity);
        emit SwapAndAddLiquidity(
            swapTokensLiquidity,
            nativeLiquidity,
            addTokensLiquidity
        );

        // Send redis to dividend tracker
        if (nativeDividends > 0) {
            (bool success, ) = address(dividendTracker).call{
                value: nativeDividends
            }("");
            if (success) {
                emit SendDividends(tokensForDividends, nativeDividends);
            }
        }

        _tokenomicsTokenAllocation = 0;
        _liquidityTokenAllocation = 0;
        _dividendsTokenAllocation = 0;
    }

    function manualSwapAndSend() public onlyOwner {
        uint256 contractTokenBalance = balanceOf(address(this));
        uint256 contractNativeBalance = address(this).balance;

        if (!swapAllToken && contractTokenBalance > swapTokensAtAmount) {
            contractTokenBalance = swapTokensAtAmount;
        }
        _executeSwap(contractTokenBalance, contractNativeBalance);
    }

    function excludeFromFees(address account, bool excluded) public onlyOwner {
        require(
            _isExcludedFromFees[account] != excluded,
            "PLUTUS: account is already set to requested state"
        );
        _isExcludedFromFees[account] = excluded;
        emit ExcludeFromFees(account, excluded);
    }

    function isExcludedFromFees(address account) public view returns (bool) {
        return _isExcludedFromFees[account];
    }

    function manualSendDividend(uint256 amount, address holder)
        external
        onlyOwner
    {
        dividendTracker.manualSendDividend(amount, holder);
    }

    function excludeFromDividends(address account, bool excluded)
        public
        onlyOwner
    {
        dividendTracker.excludeFromDividends(account, excluded);
    }

    function isExcludedFromDividends(address account)
        public
        view
        returns (bool)
    {
        return dividendTracker.isExcludedFromDividends(account);
    }

    function setWallets(
        address payable _tokenomicsWallet
    ) external onlyOwner {
        tokenomicsWallet = _tokenomicsWallet;
    }

    function setFee(
        uint256 _tokenomicsFeeBuy,
        uint256 _liquidityFeeBuy,
        uint256 _dividendFeeBuy,
        uint256 _tokenomicsFeeSell,
        uint256 _liquidityFeeSell,
        uint256 _dividendFeeSell
    ) external onlyOwner {
        tokenomicsFeeBuyBPS = _tokenomicsFeeBuy;
        liquidityFeeBuyBPS = _liquidityFeeBuy;
        dividendFeeBuyBPS = _dividendFeeBuy;
        tokenomicsFeeSellBPS = _tokenomicsFeeSell;
        liquidityFeeSellBPS = _liquidityFeeSell;
        dividendFeeSellBPS = _dividendFeeSell;

        totalFeeBPS =
            _tokenomicsFeeBuy +
            _liquidityFeeBuy +
            _dividendFeeBuy;
    }

    function claim() public {
        dividendTracker.processAccount(payable(_msgSender()));
    }

    function compound() public {
        require(compoundingEnabled, "PLUTUS: compounding is not enabled");
        dividendTracker.compoundAccount(payable(_msgSender()));
    }

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

    function withdrawnDividendOf(address account)
        public
        view
        returns (uint256)
    {
        return dividendTracker.withdrawnDividendOf(account);
    }

    function accumulativeDividendOf(address account)
        public
        view
        returns (uint256)
    {
        return dividendTracker.accumulativeDividendOf(account);
    }

    function getAccountInfo(address account)
        public
        view
        returns (
            address,
            uint256,
            uint256,
            uint256,
            uint256
        )
    {
        return dividendTracker.getAccountInfo(account);
    }

    function getLastClaimTime(address account) public view returns (uint256) {
        return dividendTracker.getLastClaimTime(account);
    }

    function setSwapEnabled(bool _enabled) external onlyOwner {
        swapEnabled = _enabled;
        emit SwapEnabled(_enabled);
    }

    function setTaxEnabled(bool _enabled) external onlyOwner {
        taxEnabled = _enabled;
        emit TaxEnabled(_enabled);
    }

    function setCompoundingEnabled(bool _enabled) external onlyOwner {
        compoundingEnabled = _enabled;
        emit CompoundingEnabled(_enabled);
    }

    function updateDividendSettings(
        bool _swapEnabled,
        uint256 _swapTokensAtAmount,
        bool _swapAllToken
    ) external onlyOwner {
        swapEnabled = _swapEnabled;
        swapTokensAtAmount = _swapTokensAtAmount;
        swapAllToken = _swapAllToken;
    }

    function setMaxTxBPS(uint256 bps) external onlyOwner {
        maxTxBPS = bps;
    }

    function excludeFromMaxTx(address account, bool excluded) public onlyOwner {
        _isExcludedFromMaxTx[account] = excluded;
    }

    function isExcludedFromMaxTx(address account) public view returns (bool) {
        return _isExcludedFromMaxTx[account];
    }

    function setMaxWalletBPS(uint256 bps) external onlyOwner {
        maxWalletBPS = bps;
    }

    function excludeFromMaxWallet(address account, bool excluded)
        public
        onlyOwner
    {
        _isExcludedFromMaxWallet[account] = excluded;
    }

    function isExcludedFromMaxWallet(address account)
        public
        view
        returns (bool)
    {
        return _isExcludedFromMaxWallet[account];
    }

    function blackList(address _user, bool blacklist) public onlyOwner {
        require(!isBlacklisted[_user], "user already blacklisted");
        isBlacklisted[_user] = blacklist;
    }

    function blackListMany(address[] memory _users) public onlyOwner {
        for (uint8 i = 0; i < _users.length; i++) {
            isBlacklisted[_users[i]] = true;
        }
    }

    receive() external payable {}
}

File 1 of 2: DividendTracker.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

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

abstract contract Ownable is Context {
    address private _owner;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

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

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

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

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

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

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

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount)
        public
        virtual
        override
        returns (bool)
    {
        _transfer(_msgSender(), recipient, 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}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount)
        public
        virtual
        override
        returns (bool)
    {
        _approve(_msgSender(), 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}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

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

        return true;
    }

    /**
     * @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)
    {
        _approve(
            _msgSender(),
            spender,
            _allowances[_msgSender()][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)
    {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(
            currentAllowance >= subtractedValue,
            "ERC20: decreased allowance below zero"
        );
        unchecked {
            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * 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:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(
            senderBalance >= amount,
            "ERC20: transfer amount exceeds balance"
        );
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);

        _afterTokenTransfer(sender, recipient, amount);
    }

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

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

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

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

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

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

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

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

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

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

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

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

library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(
            address(this).balance >= amount,
            "Address: insufficient balance"
        );

        (bool success, ) = recipient.call{value: amount}("");
        require(
            success,
            "Address: unable to send value, recipient may have reverted"
        );
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data)
        internal
        returns (bytes memory)
    {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return
            functionCallWithValue(
                target,
                data,
                value,
                "Address: low-level call with value failed"
            );
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(
            address(this).balance >= value,
            "Address: insufficient balance for call"
        );
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(
            data
        );
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data)
        internal
        view
        returns (bytes memory)
    {
        return
            functionStaticCall(
                target,
                data,
                "Address: low-level static call failed"
            );
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data)
        internal
        returns (bytes memory)
    {
        return
            functionDelegateCall(
                target,
                data,
                "Address: low-level delegate call failed"
            );
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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

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

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

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

    function decimals() external pure returns (uint8);

    function totalSupply() external view returns (uint256);

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

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

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

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

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

    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function PERMIT_TYPEHASH() external pure returns (bytes32);

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

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

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

    function MINIMUM_LIQUIDITY() external pure returns (uint256);

    function factory() external view returns (address);

    function token0() external view returns (address);

    function token1() external view returns (address);

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

    function price0CumulativeLast() external view returns (uint256);

    function price1CumulativeLast() external view returns (uint256);

    function kLast() external view returns (uint256);

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

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

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

    function skim(address to) external;

    function sync() external;

    function initialize(address, address) external;
}

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

    function WETH() external pure returns (address);

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

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


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

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

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

contract DividendTracker is Ownable, IERC20 {
    address UNISWAPROUTER;

    string private _name = "PLUTUS_DividendTracker";
    string private _symbol = "PLUTUS_DividendTracker";

    uint256 public lastProcessedIndex;

    uint256 private _totalSupply;
    mapping(address => uint256) private _balances;

    uint256 private constant magnitude = 2**128;
    uint256 public immutable minTokenBalanceForDividends;
    uint256 private magnifiedDividendPerShare;
    uint256 public totalDividendsDistributed;
    uint256 public totalDividendsWithdrawn;

    address public tokenAddress;

    mapping(address => bool) public excludedFromDividends;
    mapping(address => int256) private magnifiedDividendCorrections;
    mapping(address => uint256) private withdrawnDividends;
    mapping(address => uint256) private lastClaimTimes;

    event DividendsDistributed(address indexed from, uint256 weiAmount);
    event DividendWithdrawn(address indexed to, uint256 weiAmount);
    event ExcludeFromDividends(address indexed account, bool excluded);
    event Claim(address indexed account, uint256 amount);
    event Compound(address indexed account, uint256 amount, uint256 tokens);

    struct AccountInfo {
        address account;
        uint256 withdrawableDividends;
        uint256 totalDividends;
        uint256 lastClaimTime;
    }

    constructor(address _tokenAddress, address _uniswapRouter) {
        minTokenBalanceForDividends = 10000 * (10**18);
        tokenAddress = _tokenAddress;
        UNISWAPROUTER = _uniswapRouter;
    }

    receive() external payable {
        distributeDividends();
    }

    function distributeDividends() public payable {
        require(_totalSupply > 0);
        if (msg.value > 0) {
            magnifiedDividendPerShare =
                magnifiedDividendPerShare +
                ((msg.value * magnitude) / _totalSupply);
            emit DividendsDistributed(msg.sender, msg.value);
            totalDividendsDistributed += msg.value;
        }
    }

    function setBalance(address payable account, uint256 newBalance)
        external
        onlyOwner
    {
        if (excludedFromDividends[account]) {
            return;
        }
        if (newBalance >= minTokenBalanceForDividends) {
            _setBalance(account, newBalance);
        } else {
            _setBalance(account, 0);
        }
    }

    function excludeFromDividends(address account, bool excluded)
        external
        onlyOwner
    {
        require(
            excludedFromDividends[account] != excluded,
            "PLUTUS_DividendTracker: account already set to requested state"
        );
        excludedFromDividends[account] = excluded;
        if (excluded) {
            _setBalance(account, 0);
        } else {
            uint256 newBalance = IERC20(tokenAddress).balanceOf(account);
            if (newBalance >= minTokenBalanceForDividends) {
                _setBalance(account, newBalance);
            } else {
                _setBalance(account, 0);
            }
        }
        emit ExcludeFromDividends(account, excluded);
    }

    function isExcludedFromDividends(address account)
        public
        view
        returns (bool)
    {
        return excludedFromDividends[account];
    }

    function manualSendDividend(uint256 amount, address holder)
        external
        onlyOwner
    {
        uint256 contractETHBalance = address(this).balance;
        payable(holder).transfer(amount > 0 ? amount : contractETHBalance);
    }

    function _setBalance(address account, uint256 newBalance) internal {
        uint256 currentBalance = _balances[account];
        if (newBalance > currentBalance) {
            uint256 addAmount = newBalance - currentBalance;
            _mint(account, addAmount);
        } else if (newBalance < currentBalance) {
            uint256 subAmount = currentBalance - newBalance;
            _burn(account, subAmount);
        }
    }

    function _mint(address account, uint256 amount) private {
        require(
            account != address(0),
            "PLUTUS_DividendTracker: mint to the zero address"
        );
        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);
        magnifiedDividendCorrections[account] =
            magnifiedDividendCorrections[account] -
            int256(magnifiedDividendPerShare * amount);
    }

    function _burn(address account, uint256 amount) private {
        require(
            account != address(0),
            "PLUTUS_DividendTracker: burn from the zero address"
        );
        uint256 accountBalance = _balances[account];
        require(
            accountBalance >= amount,
            "PLUTUS_DividendTracker: burn amount exceeds balance"
        );
        _balances[account] = accountBalance - amount;
        _totalSupply -= amount;
        emit Transfer(account, address(0), amount);
        magnifiedDividendCorrections[account] =
            magnifiedDividendCorrections[account] +
            int256(magnifiedDividendPerShare * amount);
    }

    function processAccount(address payable account)
        public
        onlyOwner
        returns (bool)
    {
        uint256 amount = _withdrawDividendOfUser(account);
        if (amount > 0) {
            lastClaimTimes[account] = block.timestamp;
            emit Claim(account, amount);
            return true;
        }
        return false;
    }

    function _withdrawDividendOfUser(address payable account)
        private
        returns (uint256)
    {
        uint256 _withdrawableDividend = withdrawableDividendOf(account);
        if (_withdrawableDividend > 0) {
            withdrawnDividends[account] += _withdrawableDividend;
            totalDividendsWithdrawn += _withdrawableDividend;
            emit DividendWithdrawn(account, _withdrawableDividend);
            (bool success, ) = account.call{
                value: _withdrawableDividend,
                gas: 3000
            }("");
            if (!success) {
                withdrawnDividends[account] -= _withdrawableDividend;
                totalDividendsWithdrawn -= _withdrawableDividend;
                return 0;
            }
            return _withdrawableDividend;
        }
        return 0;
    }

    function compoundAccount(address payable account)
        public
        onlyOwner
        returns (bool)
    {
        (uint256 amount, uint256 tokens) = _compoundDividendOfUser(account);
        if (amount > 0) {
            lastClaimTimes[account] = block.timestamp;
            emit Compound(account, amount, tokens);
            return true;
        }
        return false;
    }

    function _compoundDividendOfUser(address payable account)
        private
        returns (uint256, uint256)
    {
        IERC20 mainToken = IERC20(tokenAddress);
        uint256 _withdrawableDividend = withdrawableDividendOf(account);
        if (_withdrawableDividend > 0) {
            withdrawnDividends[account] += _withdrawableDividend;
            totalDividendsWithdrawn += _withdrawableDividend;
            emit DividendWithdrawn(account, _withdrawableDividend);

            IUniswapV2Router02 uniswapV2Router = IUniswapV2Router02(
                UNISWAPROUTER
            );

            address[] memory path = new address[](2);
            path[0] = uniswapV2Router.WETH();
            path[1] = address(tokenAddress);

            bool success;
            uint256 tokens;

            uint256 initTokenBal = mainToken.balanceOf(address(this));
            try
                uniswapV2Router
                    .swapExactETHForTokensSupportingFeeOnTransferTokens{
                    value: _withdrawableDividend
                }(0, path, address(this), block.timestamp)
            {
                success = true;
                tokens = mainToken.balanceOf(address(this)) - initTokenBal;
                success = mainToken.transfer(account, tokens);
            } catch Error(
                string memory /*err*/
            ) {
                success = false;
            }

            if (!success) {
                withdrawnDividends[account] -= _withdrawableDividend;
                totalDividendsWithdrawn -= _withdrawableDividend;
                return (0, 0);
            }

            return (_withdrawableDividend, tokens);
        }
        return (0, 0);
    }

    function withdrawableDividendOf(address account)
        public
        view
        returns (uint256)
    {
        return accumulativeDividendOf(account) - withdrawnDividends[account];
    }

    function withdrawnDividendOf(address account)
        public
        view
        returns (uint256)
    {
        return withdrawnDividends[account];
    }

    function accumulativeDividendOf(address account)
        public
        view
        returns (uint256)
    {
        int256 a = int256(magnifiedDividendPerShare * balanceOf(account));
        int256 b = magnifiedDividendCorrections[account]; // this is an explicit int256 (signed)
        return uint256(a + b) / magnitude;
    }

    function getAccountInfo(address account)
        public
        view
        returns (
            address,
            uint256,
            uint256,
            uint256,
            uint256
        )
    {
        AccountInfo memory info;
        info.account = account;
        info.withdrawableDividends = withdrawableDividendOf(account);
        info.totalDividends = accumulativeDividendOf(account);
        info.lastClaimTime = lastClaimTimes[account];
        return (
            info.account,
            info.withdrawableDividends,
            info.totalDividends,
            info.lastClaimTime,
            totalDividendsWithdrawn
        );
    }

    function getLastClaimTime(address account) public view returns (uint256) {
        return lastClaimTimes[account];
    }

    function name() public view returns (string memory) {
        return _name;
    }

    function symbol() public view returns (string memory) {
        return _symbol;
    }

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

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

    function balanceOf(address account) public view override returns (uint256) {
        return _balances[account];
    }

    function transfer(address, uint256) public pure override returns (bool) {
        revert("PLUTUS_DividendTracker: method not implemented");
    }

    function allowance(address, address)
        public
        pure
        override
        returns (uint256)
    {
        revert("PLUTUS_DividendTracker: method not implemented");
    }

    function approve(address, uint256) public pure override returns (bool) {
        revert("PLUTUS_DividendTracker: method not implemented");
    }

    function transferFrom(
        address,
        address,
        uint256
    ) public pure override returns (bool) {
        revert("PLUTUS_DividendTracker: method not implemented");
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"BlacklistEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"CompoundingEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"ExcludeFromFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokensSwapped","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SendDividends","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pair","type":"address"},{"indexed":true,"internalType":"bool","name":"value","type":"bool"}],"name":"SetAutomatedMarketMakerPair","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokensSwapped","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nativeReceived","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokensIntoLiquidity","type":"uint256"}],"name":"SwapAndAddLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"SwapEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"TaxEnabled","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"},{"inputs":[],"name":"_dividendsTokenAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_liquidityTokenAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_tokenomicsTokenAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"accumulativeDividendOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"bool","name":"blacklist","type":"bool"}],"name":"blackList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"}],"name":"blackListMany","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"compound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"compoundingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dividendFeeBuyBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dividendFeeSellBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dividendTracker","outputs":[{"internalType":"contract DividendTracker","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"excluded","type":"bool"}],"name":"excludeFromDividends","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"excluded","type":"bool"}],"name":"excludeFromFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"excluded","type":"bool"}],"name":"excludeFromMaxTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"excluded","type":"bool"}],"name":"excludeFromMaxWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getAccountInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getLastClaimTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"}],"name":"includeToWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromDividends","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromMaxTx","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromMaxWallet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastSwapTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityFeeBuyBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityFeeSellBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"holder","type":"address"}],"name":"manualSendDividend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"manualSwapAndSend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxTxBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWalletBPS","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":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setCompoundingEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenomicsFeeBuy","type":"uint256"},{"internalType":"uint256","name":"_liquidityFeeBuy","type":"uint256"},{"internalType":"uint256","name":"_dividendFeeBuy","type":"uint256"},{"internalType":"uint256","name":"_tokenomicsFeeSell","type":"uint256"},{"internalType":"uint256","name":"_liquidityFeeSell","type":"uint256"},{"internalType":"uint256","name":"_dividendFeeSell","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"bps","type":"uint256"}],"name":"setMaxTxBPS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"bps","type":"uint256"}],"name":"setMaxWalletBPS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setParametersToLaunch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setSwapEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setTaxEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"setTradingOpenDate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_tokenomicsWallet","type":"address"}],"name":"setWallets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapTokensAtAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenomicsFeeBuyBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenomicsFeeSellBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenomicsWallet","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFeeBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapV2Pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapV2Router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_swapEnabled","type":"bool"},{"internalType":"uint256","name":"_swapTokensAtAmount","type":"uint256"},{"internalType":"bool","name":"_swapAllToken","type":"bool"}],"name":"updateDividendSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"withdrawableDividendOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"withdrawnDividendOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

600180546001600160a01b0319908116737a250d5630b4cf539739df2c5dacb4c659f2488d1790915560028054821661dead17905560038054909116905560c0604052601760808190527f504c55545553204341504954414c20484f4c44494e475300000000000000000060a09081526200007e916004919062000474565b50604080518082019091526003808252620a086960eb1b6020909201918252620000ab9160059162000474565b506102586009556064600a5561012c600b5561076c600c556064600d556000600e55600b54600a54600954620000e291906200055a565b620000ee91906200055a565b600f5569152d02c7e14af68000006010556012805463ffffffff191663010101011790556b033b2e3c9fd0803ce800000060135560148054610100600160a81b0319167420308b8986d45a1eb50757e03f4dddd15b22fb0f001790556032601f5560c860205563624e031e6021553480156200016957600080fd5b50620001753362000424565b60015460405130916001600160a01b031690620001929062000503565b6001600160a01b03928316815291166020820152604001604051809103906000f080158015620001c6573d6000803e3d6000fd5b50601c80546001600160a01b0319166001600160a01b039283161790556001546040805163c45a015560e01b815290519190921691600091839163c45a0155916004808301926020929190829003018186803b1580156200022657600080fd5b505afa1580156200023b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000261919062000528565b6001600160a01b031663c9c6539630846001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b158015620002aa57600080fd5b505afa158015620002bf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002e5919062000528565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381600087803b1580156200032e57600080fd5b505af115801562000343573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000369919062000528565b601d80546001600160a01b038086166001600160a01b031992831617909255601e80549284169290911691909117905560135490915060156000620003ab3390565b6001600160a01b03166001600160a01b031681526020019081526020016000206000828254620003dc91906200055a565b909155505060135460405190815233906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050620005be565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b828054620004829062000581565b90600052602060002090601f016020900481019282620004a65760008555620004f1565b82601f10620004c157805160ff1916838001178555620004f1565b82800160010185558215620004f1579182015b82811115620004f1578251825591602001919060010190620004d4565b50620004ff92915062000511565b5090565b611f0180620039c083390190565b5b80821115620004ff576000815560010162000512565b6000602082840312156200053b57600080fd5b81516001600160a01b03811681146200055357600080fd5b9392505050565b600082198211156200057c57634e487b7160e01b600052601160045260246000fd5b500190565b600181811c908216806200059657607f821691505b60208210811415620005b857634e487b7160e01b600052602260045260246000fd5b50919050565b6133f280620005ce6000396000f3fe6080604052600436106103d25760003560e01c8063744d1591116101fd578063bd9a3b6d11610118578063d8f281b7116100ab578063e4956ce21161007a578063e4956ce214610b95578063e9910b2b14610bb5578063eb50e70e14610bcb578063f2fde38b14610beb578063f69e204614610c0b57600080fd5b8063d8f281b714610b03578063dd62ed3e14610b19578063e01af92c14610b5f578063e2f4560514610b7f57600080fd5b8063c705c569116100e7578063c705c56914610a8d578063c98139e614610aad578063d2fcc00114610ac3578063d4c989d314610ae357600080fd5b8063bd9a3b6d14610a0d578063c024666814610a2d578063c3033aeb14610a4d578063c6af580b14610a6d57600080fd5b8063a457c2d711610190578063a9059cbb1161015f578063a9059cbb14610997578063aa4e8c4a146109b7578063aafd847a146109d7578063af7999cd146109f757600080fd5b8063a457c2d714610917578063a680e0bc14610937578063a68fe71a14610957578063a8b9d2401461097757600080fd5b80638da5cb5b116101cc5780638da5cb5b146108a45780638e126944146108c257806395d89b41146108e25780639c8e841d146108f757600080fd5b8063744d159114610806578063769758e51461081c5780637b510fe814610832578063870bd30b1461088457600080fd5b806337eb1528116102ed57806358076c57116102805780636dd3d39f1161024f5780636dd3d39f146107635780636ddd17131461079c57806370a08231146107bb578063715018a6146107f157600080fd5b806358076c57146106d55780635e843ad2146106ea578063658c27a91461070a57806368c51e351461074357600080fd5b806349bd5a5e116102bc57806349bd5a5e146106515780634e71d92d146106715780634fbee1931461068657806357777d31146106bf57600080fd5b806337eb1528146105f057806339509351146106065780633ee0ce021461062657806340225fce1461063b57600080fd5b806318160ddd1161036557806327ce01471161033457806327ce0147146105735780632c1f5216146105935780632f4504ae146105b3578063313ce567146105d457600080fd5b806318160ddd1461051257806319c76c2514610527578063225e5eb71461053d57806323b872dd1461055357600080fd5b80630dd87157116103a15780630dd871571461047b57806312e652d91461049f57806314d9aa70146104dc5780631694505e146104f257600080fd5b80630483f7a0146103de57806306fdde0314610400578063095ea7b31461042b5780630b6bb6f51461045b57600080fd5b366103d957005b600080fd5b3480156103ea57600080fd5b506103fe6103f9366004612e0d565b610c20565b005b34801561040c57600080fd5b50610415610cbe565b60405161042291906130c0565b60405180910390f35b34801561043757600080fd5b5061044b610446366004612e3b565b610d50565b6040519015158152602001610422565b34801561046757600080fd5b506103fe610476366004612eb0565b610d66565b34801561048757600080fd5b5061049160115481565b604051908152602001610422565b3480156104ab57600080fd5b506014546104c49061010090046001600160a01b031681565b6040516001600160a01b039091168152602001610422565b3480156104e857600080fd5b5061049160095481565b3480156104fe57600080fd5b50601d546104c4906001600160a01b031681565b34801561051e57600080fd5b50601354610491565b34801561053357600080fd5b50610491600c5481565b34801561054957600080fd5b50610491600d5481565b34801561055f57600080fd5b5061044b61056e366004612dcc565b610e02565b34801561057f57600080fd5b5061049161058e366004612d52565b610eb4565b34801561059f57600080fd5b50601c546104c4906001600160a01b031681565b3480156105bf57600080fd5b5060125461044b906301000000900460ff1681565b3480156105e057600080fd5b5060405160128152602001610422565b3480156105fc57600080fd5b50610491600f5481565b34801561061257600080fd5b5061044b610621366004612e3b565b610f39565b34801561063257600080fd5b506103fe610f70565b34801561064757600080fd5b50610491600e5481565b34801561065d57600080fd5b50601e546104c4906001600160a01b031681565b34801561067d57600080fd5b506103fe610fd5565b34801561069257600080fd5b5061044b6106a1366004612d52565b6001600160a01b031660009081526017602052604090205460ff1690565b3480156106cb57600080fd5b50610491601f5481565b3480156106e157600080fd5b506103fe611064565b3480156106f657600080fd5b506103fe610705366004612fb6565b611364565b34801561071657600080fd5b5061044b610725366004612d52565b6001600160a01b03166000908152601a602052604090205460ff1690565b34801561074f57600080fd5b506103fe61075e366004612ff8565b6113bc565b34801561076f57600080fd5b5061044b61077e366004612d52565b6001600160a01b03166000908152601b602052604090205460ff1690565b3480156107a857600080fd5b5060125461044b90610100900460ff1681565b3480156107c757600080fd5b506104916107d6366004612d52565b6001600160a01b031660009081526015602052604090205490565b3480156107fd57600080fd5b506103fe6113eb565b34801561081257600080fd5b5061049160205481565b34801561082857600080fd5b5061049160085481565b34801561083e57600080fd5b5061085261084d366004612d52565b61141f565b604080516001600160a01b0390961686526020860194909452928401919091526060830152608082015260a001610422565b34801561089057600080fd5b5060125461044b9062010000900460ff1681565b3480156108b057600080fd5b506000546001600160a01b03166104c4565b3480156108ce57600080fd5b506103fe6108dd36600461302a565b6114b8565b3480156108ee57600080fd5b5061041561151b565b34801561090357600080fd5b506103fe610912366004612e0d565b61152a565b34801561092357600080fd5b5061044b610932366004612e3b565b6115e8565b34801561094357600080fd5b50610491610952366004612d52565b611684565b34801561096357600080fd5b506103fe610972366004612ff8565b6116b7565b34801561098357600080fd5b50610491610992366004612d52565b6116e6565b3480156109a357600080fd5b5061044b6109b2366004612e3b565b611719565b3480156109c357600080fd5b506103fe6109d2366004612ff8565b611726565b3480156109e357600080fd5b506104916109f2366004612d52565b611755565b348015610a0357600080fd5b50610491600a5481565b348015610a1957600080fd5b506103fe610a2836600461307d565b611788565b348015610a3957600080fd5b506103fe610a48366004612e0d565b6117f0565b348015610a5957600080fd5b506103fe610a68366004612eb0565b611902565b348015610a7957600080fd5b506103fe610a88366004612f7c565b61199a565b348015610a9957600080fd5b5061044b610aa8366004612d52565b611a1a565b348015610ab957600080fd5b5061049160075481565b348015610acf57600080fd5b506103fe610ade366004612e0d565b611a98565b348015610aef57600080fd5b506103fe610afe366004612e0d565b611aed565b348015610b0f57600080fd5b5061049160065481565b348015610b2557600080fd5b50610491610b34366004612d93565b6001600160a01b03918216600090815260166020908152604080832093909416825291909152205490565b348015610b6b57600080fd5b506103fe610b7a366004612f7c565b611b42565b348015610b8b57600080fd5b5061049160105481565b348015610ba157600080fd5b506103fe610bb0366004612f7c565b611bb5565b348015610bc157600080fd5b50610491600b5481565b348015610bd757600080fd5b506103fe610be6366004612d52565b611c2c565b348015610bf757600080fd5b506103fe610c06366004612d52565b611c7e565b348015610c1757600080fd5b506103fe611d16565b6000546001600160a01b03163314610c535760405162461bcd60e51b8152600401610c4a906131e6565b60405180910390fd5b601c5460405162241fbd60e51b81526001600160a01b038481166004830152831515602483015290911690630483f7a0906044015b600060405180830381600087803b158015610ca257600080fd5b505af1158015610cb6573d6000803e3d6000fd5b505050505050565b606060048054610ccd906132fc565b80601f0160208091040260200160405190810160405280929190818152602001828054610cf9906132fc565b8015610d465780601f10610d1b57610100808354040283529160200191610d46565b820191906000526020600020905b815481529060010190602001808311610d2957829003601f168201915b5050505050905090565b6000610d5d338484611d91565b50600192915050565b6000546001600160a01b03163314610d905760405162461bcd60e51b8152600401610c4a906131e6565b60005b81518160ff161015610dfe57600160186000848460ff1681518110610dba57610dba61336d565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580610df681613337565b915050610d93565b5050565b6000610e0f848484611eb8565b6001600160a01b038416600090815260166020908152604080832033845290915290205482811015610e955760405162461bcd60e51b815260206004820152602960248201527f504c555455533a207472616e7366657220616d6f756e74206578636565647320604482015268616c6c6f77616e636560b81b6064820152608401610c4a565b610ea98533610ea486856132e5565b611d91565b506001949350505050565b601c546040516327ce014760e01b81526001600160a01b03838116600483015260009216906327ce0147906024015b60206040518083038186803b158015610efb57600080fd5b505afa158015610f0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f339190613011565b92915050565b3360008181526016602090815260408083206001600160a01b03871684529091528120549091610d5d918590610ea490869061328c565b6000546001600160a01b03163314610f9a5760405162461bcd60e51b8152600401610c4a906131e6565b30600090815260156020526040902054601254479060ff16158015610fc0575060105482115b15610fcb5760105491505b610dfe8282612668565b601c546001600160a01b031663807ab4f7335b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381600087803b15801561102957600080fd5b505af115801561103d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110619190612f99565b50565b6000546001600160a01b0316331461108e5760405162461bcd60e51b8152600401610c4a906131e6565b601c5460405162241fbd60e51b81526001600160a01b03909116600482018190526001602483015290630483f7a090604401600060405180830381600087803b1580156110da57600080fd5b505af11580156110ee573d6000803e3d6000fd5b5050601c5460405162241fbd60e51b8152306004820152600160248201526001600160a01b039091169250630483f7a09150604401600060405180830381600087803b15801561113d57600080fd5b505af1158015611151573d6000803e3d6000fd5b5050601c546001600160a01b03169150630483f7a0905061117a6000546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260016024820152604401600060405180830381600087803b1580156111c257600080fd5b505af11580156111d6573d6000803e3d6000fd5b5050601c54601d5460405162241fbd60e51b81526001600160a01b0391821660048201526001602482015291169250630483f7a09150604401600060405180830381600087803b15801561122957600080fd5b505af115801561123d573d6000803e3d6000fd5b5050601c5460025460405162241fbd60e51b81526001600160a01b0391821660048201526001602482015291169250630483f7a09150604401600060405180830381600087803b15801561129057600080fd5b505af11580156112a4573d6000803e3d6000fd5b505050506112c46112bd6000546001600160a01b031690565b60016117f0565b6112cf3060016117f0565b601c546112e6906001600160a01b031660016117f0565b6113026112fb6000546001600160a01b031690565b6001611aed565b61130d306001611aed565b601c54611324906001600160a01b03166001611aed565b6113406113396000546001600160a01b031690565b6001611a98565b61134b306001611a98565b601c54611362906001600160a01b03166001611a98565b565b6000546001600160a01b0316331461138e5760405162461bcd60e51b8152600401610c4a906131e6565b6012805460109390935590151560ff19931515610100029390931661ffff1990921691909117919091179055565b6000546001600160a01b031633146113e65760405162461bcd60e51b8152600401610c4a906131e6565b602055565b6000546001600160a01b031633146114155760405162461bcd60e51b8152600401610c4a906131e6565b61136260006129e0565b601c54604051630f6a21fd60e31b81526001600160a01b0383811660048301526000928392839283928392911690637b510fe89060240160a06040518083038186803b15801561146e57600080fd5b505afa158015611482573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a69190612e67565b939a9299509097509550909350915050565b6000546001600160a01b031633146114e25760405162461bcd60e51b8152600401610c4a906131e6565b601c546040516323849a5160e21b8152600481018490526001600160a01b03838116602483015290911690638e12694490604401610c88565b606060058054610ccd906132fc565b6000546001600160a01b031633146115545760405162461bcd60e51b8152600401610c4a906131e6565b6001600160a01b03821660009081526019602052604090205460ff16156115bd5760405162461bcd60e51b815260206004820152601860248201527f7573657220616c726561647920626c61636b6c697374656400000000000000006044820152606401610c4a565b6001600160a01b03919091166000908152601960205260409020805460ff1916911515919091179055565b3360009081526016602090815260408083206001600160a01b03861684529091528120548281101561166b5760405162461bcd60e51b815260206004820152602660248201527f504c555455533a2064656372656173656420616c6c6f77616e63652062656c6f60448201526577207a65726f60d01b6064820152608401610c4a565b61167a3385610ea486856132e5565b5060019392505050565b601c546040516329a0382f60e21b81526001600160a01b038381166004830152600092169063a680e0bc90602401610ee3565b6000546001600160a01b031633146116e15760405162461bcd60e51b8152600401610c4a906131e6565b602155565b601c546040516302a2e74960e61b81526001600160a01b038381166004830152600092169063a8b9d24090602401610ee3565b6000610d5d338484611eb8565b6000546001600160a01b031633146117505760405162461bcd60e51b8152600401610c4a906131e6565b601f55565b601c5460405163557ec23d60e11b81526001600160a01b038381166004830152600092169063aafd847a90602401610ee3565b6000546001600160a01b031633146117b25760405162461bcd60e51b8152600401610c4a906131e6565b6009869055600a859055600b849055600c839055600d829055600e819055836117db868861328c565b6117e5919061328c565b600f55505050505050565b6000546001600160a01b0316331461181a5760405162461bcd60e51b8152600401610c4a906131e6565b6001600160a01b03821660009081526017602052604090205460ff16151581151514156118a35760405162461bcd60e51b815260206004820152603160248201527f504c555455533a206163636f756e7420697320616c72656164792073657420746044820152706f2072657175657374656420737461746560781b6064820152608401610c4a565b6001600160a01b038216600081815260176020908152604091829020805460ff191685151590811790915591519182527f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df7910160405180910390a25050565b6000546001600160a01b0316331461192c5760405162461bcd60e51b8152600401610c4a906131e6565b60005b81518160ff161015610dfe57600160196000848460ff16815181106119565761195661336d565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff19169115159190911790558061199281613337565b91505061192f565b6000546001600160a01b031633146119c45760405162461bcd60e51b8152600401610c4a906131e6565b60128054821515620100000262ff0000199091161790556040517f5bb2376cf656637e70e36c01d3da25685bf3b353f18681b8a5e48c7b2effe13390611a0f90831515815260200190565b60405180910390a150565b601c5460405163c705c56960e01b81526001600160a01b038381166004830152600092169063c705c5699060240160206040518083038186803b158015611a6057600080fd5b505afa158015611a74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f339190612f99565b6000546001600160a01b03163314611ac25760405162461bcd60e51b8152600401610c4a906131e6565b6001600160a01b03919091166000908152601b60205260409020805460ff1916911515919091179055565b6000546001600160a01b03163314611b175760405162461bcd60e51b8152600401610c4a906131e6565b6001600160a01b03919091166000908152601a60205260409020805460ff1916911515919091179055565b6000546001600160a01b03163314611b6c5760405162461bcd60e51b8152600401610c4a906131e6565b601280548215156101000261ff00199091161790556040517fb9bbb15e341600c8d067a0cadeba219905d5ba6d422b193c9c32265d26fc51c890611a0f90831515815260200190565b6000546001600160a01b03163314611bdf5760405162461bcd60e51b8152600401610c4a906131e6565b6012805482151563010000000263ff000000199091161790556040517f341322866a3a2c26c27efa4c270c5ba86f6963257118897dd8196f224c002d4390611a0f90831515815260200190565b6000546001600160a01b03163314611c565760405162461bcd60e51b8152600401610c4a906131e6565b601480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6000546001600160a01b03163314611ca85760405162461bcd60e51b8152600401610c4a906131e6565b6001600160a01b038116611d0d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c4a565b611061816129e0565b6012546301000000900460ff16611d7a5760405162461bcd60e51b815260206004820152602260248201527f504c555455533a20636f6d706f756e64696e67206973206e6f7420656e61626c604482015261195960f21b6064820152608401610c4a565b601c546001600160a01b0316636de1a5a933610fe8565b6001600160a01b038316611df55760405162461bcd60e51b815260206004820152602560248201527f504c555455533a20617070726f76652066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610c4a565b6001600160a01b038216611e575760405162461bcd60e51b815260206004820152602360248201527f504c555455533a20617070726f766520746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610c4a565b6001600160a01b0383811660008181526016602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b426021541080611ed557506000546001600160a01b038481169116145b80611eed57506000546001600160a01b038381169116145b80611f1057506001600160a01b03831660009081526018602052604090205460ff165b80611f3357506001600160a01b03821660009081526018602052604090205460ff165b611f7f5760405162461bcd60e51b815260206004820181905260248201527f504c555455533a20546f6b656e2069736e2774207472616461626c65207965746044820152606401610c4a565b6001600160a01b03831660009081526019602052604090205460ff1615611fe85760405162461bcd60e51b815260206004820152601d60248201527f504c555455533a2053656e64657220697320626c61636b6c69737465640000006044820152606401610c4a565b6001600160a01b03821660009081526019602052604090205460ff16156120515760405162461bcd60e51b815260206004820181905260248201527f504c555455533a20526563697069656e7420697320626c61636b6c69737465646044820152606401610c4a565b6001600160a01b0383166120775760405162461bcd60e51b8152600401610c4a90613115565b6001600160a01b03821661209d5760405162461bcd60e51b8152600401610c4a9061315b565b6000612710601f546120ae60135490565b6120b891906132c6565b6120c291906132a4565b905060006127106020546120d560135490565b6120df91906132c6565b6120e991906132a4565b9050818311158061211257506001600160a01b0385166000908152601a602052604090205460ff165b6121525760405162461bcd60e51b8152602060048201526011602482015270151608131a5b5a5d08115e18d959591959607a1b6044820152606401610c4a565b6000546001600160a01b0386811691161480159061217957506001600160a01b0384163014155b801561219357506002546001600160a01b03858116911614155b80156121ad5750601e546001600160a01b03858116911614155b156121f9576001600160a01b038416600090815260156020908152604080832054601b9092529091205460ff16806121ee5750816121eb858361328c565b11155b6121f757600080fd5b505b6001600160a01b038516600090815260156020526040902054838110156122325760405162461bcd60e51b8152600401610c4a9061319f565b30600090815260156020526040902054601054601254479183101590610100900460ff16801561225f5750805b801561226e575060145460ff16155b80156122885750601d546001600160a01b038a8116911614155b80156122a257506000546001600160a01b038a8116911614155b80156122bc57506000546001600160a01b03898116911614155b15612306576014805460ff1916600117905560125460ff161580156122e2575060105483115b156122ed5760105492505b6122f78383612668565b426011556014805460ff191690555b601e546000906001600160a01b038b811691161480156123345750601d546001600160a01b038a8116911614155b806123655750601e546001600160a01b038a811691161480156123655750601d546001600160a01b038b8116911614155b1561236e575060015b6001600160a01b038a1660009081526017602052604090205460ff16806123ad57506001600160a01b03891660009081526017602052604090205460ff165b156123b6575060005b60145460ff16806123d0575060125462010000900460ff16155b156123d9575060005b801561253157601e546001600160a01b038b81169116141561246c57600b54600a54600954612408919061328c565b612412919061328c565b600f819055600954612424908a6132c6565b61242e91906132a4565b600655600f54600a54612441908a6132c6565b61244b91906132a4565b600755600f54600b5461245e908a6132c6565b61246891906132a4565b6008555b601e546001600160a01b038a8116911614156124f957600e54600d54600c54612495919061328c565b61249f919061328c565b600f819055600c546124b1908a6132c6565b6124bb91906132a4565b600655600f54600d546124ce908a6132c6565b6124d891906132a4565b600755600f54600e546124eb908a6132c6565b6124f591906132a4565b6008555b6000612710600f548a61250c91906132c6565b61251691906132a4565b9050612522818a6132e5565b985061252f8b3083612a30565b505b61253c8a8a8a612a30565b601c546001600160a01b031663e30443bc8b61256d816001600160a01b031660009081526015602052604090205490565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156125b357600080fd5b505af11580156125c7573d6000803e3d6000fd5b5050601c546001600160a01b0316915063e30443bc90508a6125fe816001600160a01b031660009081526015602052604090205490565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561264457600080fd5b505af1158015612658573d6000803e3d6000fd5b5050505050505050505050505050565b60008211612674575050565b6000600854600754600654612689919061328c565b612693919061328c565b60145490915060009061010090046001600160a01b0316156126cb5781600654856126be91906132c6565b6126c891906132a4565b90505b600080601c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561271c57600080fd5b505afa158015612730573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127549190613011565b111561277657826008548661276991906132c6565b61277391906132a4565b90505b60008161278384886132e5565b61278d91906132e5565b9050600061279c6002836132a4565b905060006127aa82846132e5565b90506000826127b9868861328c565b6127c3919061328c565b9050476127cf82612b4f565b6000896127dc83476132e5565b6127e6919061328c565b90506000836127f58a846132c6565b6127ff91906132a4565b905060008461280e8a856132c6565b61281891906132a4565b905060008161282784866132e5565b61283191906132e5565b905082156128d85760145460405160009161010090046001600160a01b03169085908381818185875af1925050503d806000811461288b576040519150601f19603f3d011682016040523d82523d6000602084013e612890565b606091505b50509050806128d65760405162461bcd60e51b815260206004820152601260248201527128262aaa2aa99d102a3c103330b4b632b21760711b6044820152606401610c4a565b505b6128e28782612c82565b60408051898152602081018390529081018890527fb63dc6f50047533abe2d6adf180d38d524c8d98e55ad199aac8d6b9801bbe24a9060600160405180910390a181156129c157601c546040516000916001600160a01b03169084908381818185875af1925050503d8060008114612976576040519150601f19603f3d011682016040523d82523d6000602084013e61297b565b606091505b5050905080156129bf57604080518c8152602081018590527f80195cc573b02cc48460cbca6e6e4cc85ddb91959d946e1c3025ea3d87942dc3910160405180910390a15b505b5050600060068190556007819055600855505050505050505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038316612a565760405162461bcd60e51b8152600401610c4a90613115565b6001600160a01b038216612a7c5760405162461bcd60e51b8152600401610c4a9061315b565b6001600160a01b03831660009081526015602052604090205481811015612ab55760405162461bcd60e51b8152600401610c4a9061319f565b612abf82826132e5565b6001600160a01b038086166000908152601560205260408082209390935590851681529081208054849290612af590849061328c565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612b4191815260200190565b60405180910390a350505050565b6040805160028082526060820183526000926020830190803683370190505090503081600081518110612b8457612b8461336d565b6001600160a01b03928316602091820292909201810191909152601d54604080516315ab88c960e31b81529051919093169263ad5c4648926004808301939192829003018186803b158015612bd857600080fd5b505afa158015612bec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c109190612d76565b81600181518110612c2357612c2361336d565b6001600160a01b039283166020918202929092010152601d54612c499130911684611d91565b601d5460405163791ac94760e01b81526001600160a01b039091169063791ac94790610c8890859060009086903090429060040161321b565b601d54612c9a9030906001600160a01b031684611d91565b601d5460405163f305d71960e01b8152306004820181905260248201859052600060448301819052606483015260848201524260a48201526001600160a01b039091169063f305d71990839060c4016060604051808303818588803b158015612d0257600080fd5b505af1158015612d16573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612d3b919061304f565b5050505050565b8035612d4d81613399565b919050565b600060208284031215612d6457600080fd5b8135612d6f81613399565b9392505050565b600060208284031215612d8857600080fd5b8151612d6f81613399565b60008060408385031215612da657600080fd5b8235612db181613399565b91506020830135612dc181613399565b809150509250929050565b600080600060608486031215612de157600080fd5b8335612dec81613399565b92506020840135612dfc81613399565b929592945050506040919091013590565b60008060408385031215612e2057600080fd5b8235612e2b81613399565b91506020830135612dc1816133ae565b60008060408385031215612e4e57600080fd5b8235612e5981613399565b946020939093013593505050565b600080600080600060a08688031215612e7f57600080fd5b8551612e8a81613399565b602087015160408801516060890151608090990151929a91995097965090945092505050565b60006020808385031215612ec357600080fd5b823567ffffffffffffffff80821115612edb57600080fd5b818501915085601f830112612eef57600080fd5b813581811115612f0157612f01613383565b8060051b604051601f19603f83011681018181108582111715612f2657612f26613383565b604052828152858101935084860182860187018a1015612f4557600080fd5b600095505b83861015612f6f57612f5b81612d42565b855260019590950194938601938601612f4a565b5098975050505050505050565b600060208284031215612f8e57600080fd5b8135612d6f816133ae565b600060208284031215612fab57600080fd5b8151612d6f816133ae565b600080600060608486031215612fcb57600080fd5b8335612fd6816133ae565b9250602084013591506040840135612fed816133ae565b809150509250925092565b60006020828403121561300a57600080fd5b5035919050565b60006020828403121561302357600080fd5b5051919050565b6000806040838503121561303d57600080fd5b823591506020830135612dc181613399565b60008060006060848603121561306457600080fd5b8351925060208401519150604084015190509250925092565b60008060008060008060c0878903121561309657600080fd5b505084359660208601359650604086013595606081013595506080810135945060a0013592509050565b600060208083528351808285015260005b818110156130ed578581018301518582016040015282016130d1565b818111156130ff576000604083870101525b50601f01601f1916929092016040019392505050565b60208082526026908201527f504c555455533a207472616e736665722066726f6d20746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526024908201527f504c555455533a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526027908201527f504c555455533a207472616e7366657220616d6f756e7420657863656564732060408201526662616c616e636560c81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b8181101561326b5784516001600160a01b031683529383019391830191600101613246565b50506001600160a01b03969096166060850152505050608001529392505050565b6000821982111561329f5761329f613357565b500190565b6000826132c157634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156132e0576132e0613357565b500290565b6000828210156132f7576132f7613357565b500390565b600181811c9082168061331057607f821691505b6020821081141561333157634e487b7160e01b600052602260045260246000fd5b50919050565b600060ff821660ff81141561334e5761334e613357565b60010192915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461106157600080fd5b801515811461106157600080fdfea2646970667358221220f3a835d6eae0246c1dba2aaddb7a9c0d09eb6dac6c5e08d705328d0cd17b9ffa64736f6c6343000807003360e0604052601660a08190527f504c555455535f4469766964656e64547261636b65720000000000000000000060c090815262000040916002919062000153565b506040805180820190915260168082527f504c555455535f4469766964656e64547261636b6572000000000000000000006020909201918252620000879160039162000153565b503480156200009557600080fd5b5060405162001f0138038062001f01833981016040819052620000b89162000216565b620000c33362000103565b69021e19e0c9bab2400000608052600a80546001600160a01b039384166001600160a01b031991821617909155600180549290931691161790556200028b565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805462000161906200024e565b90600052602060002090601f016020900481019282620001855760008555620001d0565b82601f10620001a057805160ff1916838001178555620001d0565b82800160010185558215620001d0579182015b82811115620001d0578251825591602001919060010190620001b3565b50620001de929150620001e2565b5090565b5b80821115620001de5760008155600101620001e3565b80516001600160a01b03811681146200021157600080fd5b919050565b600080604083850312156200022a57600080fd5b6200023583620001f9565b91506200024560208401620001f9565b90509250929050565b600181811c908216806200026357607f821691505b602082108114156200028557634e487b7160e01b600052602260045260246000fd5b50919050565b608051611c4c620002b5600039600081816105520152818161081e0152610d310152611c4c6000f3fe6080604052600436106101d15760003560e01c806385a6b3ae116100f7578063a8b9d24011610095578063c705c56911610064578063c705c56914610574578063dd62ed3e146105ad578063e30443bc146105c8578063f2fde38b146105e857600080fd5b8063a8b9d240146104ea578063a9059cbb14610238578063aafd847a1461050a578063c49af5f01461054057600080fd5b806395d89b41116100d157806395d89b41146104695780639d76ea581461047e5780639e1e06611461049e578063a680e0bc146104b457600080fd5b806385a6b3ae146104015780638da5cb5b146104175780638e1269441461044957600080fd5b80633009a6091161016f57806370a082311161013e57806370a0823114610344578063715018a61461037a5780637b510fe81461038f578063807ab4f7146103e157600080fd5b80633009a609146102c2578063313ce567146102d85780634e7b827f146102f45780636de1a5a91461032457600080fd5b8063095ea7b3116101ab578063095ea7b31461023857806318160ddd1461026857806323b872dd1461028757806327ce0147146102a257600080fd5b806303c83302146101e55780630483f7a0146101ed57806306fdde031461020d57600080fd5b366101e0576101de610608565b005b600080fd5b6101de610608565b3480156101f957600080fd5b506101de61020836600461183e565b610697565b34801561021957600080fd5b506102226108a8565b60405161022f9190611931565b60405180910390f35b34801561024457600080fd5b50610258610253366004611798565b61093a565b604051901515815260200161022f565b34801561027457600080fd5b506005545b60405190815260200161022f565b34801561029357600080fd5b506102586102533660046117fd565b3480156102ae57600080fd5b506102796102bd366004611757565b61099c565b3480156102ce57600080fd5b5061027960045481565b3480156102e457600080fd5b506040516012815260200161022f565b34801561030057600080fd5b5061025861030f366004611757565b600b6020526000908152604090205460ff1681565b34801561033057600080fd5b5061025861033f366004611757565b610a00565b34801561035057600080fd5b5061027961035f366004611757565b6001600160a01b031660009081526006602052604090205490565b34801561038657600080fd5b506101de610aab565b34801561039b57600080fd5b506103af6103aa366004611757565b610adf565b604080516001600160a01b0390961686526020860194909452928401919091526060830152608082015260a00161022f565b3480156103ed57600080fd5b506102586103fc366004611757565b610b87565b34801561040d57600080fd5b5061027960085481565b34801561042357600080fd5b506000546001600160a01b03165b6040516001600160a01b03909116815260200161022f565b34801561045557600080fd5b506101de6104643660046118a2565b610c2c565b34801561047557600080fd5b50610222610c9f565b34801561048a57600080fd5b50600a54610431906001600160a01b031681565b3480156104aa57600080fd5b5061027960095481565b3480156104c057600080fd5b506102796104cf366004611757565b6001600160a01b03166000908152600e602052604090205490565b3480156104f657600080fd5b50610279610505366004611757565b610cae565b34801561051657600080fd5b50610279610525366004611757565b6001600160a01b03166000908152600d602052604090205490565b34801561054c57600080fd5b506102797f000000000000000000000000000000000000000000000000000000000000000081565b34801561058057600080fd5b5061025861058f366004611757565b6001600160a01b03166000908152600b602052604090205460ff1690565b3480156105b957600080fd5b506102796102533660046117c4565b3480156105d457600080fd5b506101de6105e3366004611798565b610ce0565b3480156105f457600080fd5b506101de610603366004611757565b610d6f565b60006005541161061757600080fd5b34156106955760055461062e600160801b34611a36565b6106389190611a14565b60075461064591906119fc565b60075560405134815233907fa493a9229478c3fcd73f66d2cdeb7f94fd0f341da924d1054236d784541165119060200160405180910390a2346008600082825461068f91906119fc565b90915550505b565b6000546001600160a01b031633146106ca5760405162461bcd60e51b81526004016106c190611986565b60405180910390fd5b6001600160a01b0382166000908152600b602052604090205460ff161515811515141561075f5760405162461bcd60e51b815260206004820152603e60248201527f504c555455535f4469766964656e64547261636b65723a206163636f756e742060448201527f616c72656164792073657420746f20726571756573746564207374617465000060648201526084016106c1565b6001600160a01b0382166000908152600b60205260409020805460ff1916821580159190911790915561079c57610797826000610e0a565b61085f565b600a546040516370a0823160e01b81526001600160a01b03848116600483015260009216906370a082319060240160206040518083038186803b1580156107e257600080fd5b505afa1580156107f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081a9190611889565b90507f000000000000000000000000000000000000000000000000000000000000000081106108525761084d8382610e0a565b61085d565b61085d836000610e0a565b505b816001600160a01b03167fa3c7c11b2e12c4144b09a7813f3393ba646392788638998c97be8da908cf04be8260405161089c911515815260200190565b60405180910390a25050565b6060600280546108b790611aab565b80601f01602080910402602001604051908101604052809291908181526020018280546108e390611aab565b80156109305780601f1061090557610100808354040283529160200191610930565b820191906000526020600020905b81548152906001019060200180831161091357829003601f168201915b5050505050905090565b60405162461bcd60e51b815260206004820152602e60248201527f504c555455535f4469766964656e64547261636b65723a206d6574686f64206e60448201526d1bdd081a5b5c1b195b595b9d195960921b60648201526000906084016106c1565b6001600160a01b03811660009081526006602052604081205460075482916109c391611a36565b6001600160a01b0384166000908152600c6020526040902054909150600160801b6109ee82846119bb565b6109f89190611a14565b949350505050565b600080546001600160a01b03163314610a2b5760405162461bcd60e51b81526004016106c190611986565b600080610a3784610e68565b90925090508115610aa1576001600160a01b0384166000818152600e602090815260409182902042905581518581529081018490527f0e311a2c6dbfb0153ec3a8a5bdca09070b3e5f60768fdc10a20453f38d186873910160405180910390a25060019392505050565b5060009392505050565b6000546001600160a01b03163314610ad55760405162461bcd60e51b81526004016106c190611986565b61069560006112ad565b6000806000806000610b1b604051806080016040528060006001600160a01b031681526020016000815260200160008152602001600081525090565b6001600160a01b0387168152610b3087610cae565b6020820152610b3e8761099c565b60408281019182526001600160a01b03989098166000908152600e6020908152989020546060830181905282519890920151905160095498999198909750919550909350915050565b600080546001600160a01b03163314610bb25760405162461bcd60e51b81526004016106c190611986565b6000610bbd836112fd565b90508015610c23576001600160a01b0383166000818152600e602052604090819020429055517f47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d490610c129084815260200190565b60405180910390a250600192915050565b50600092915050565b6000546001600160a01b03163314610c565760405162461bcd60e51b81526004016106c190611986565b476001600160a01b0382166108fc84610c6f5782610c71565b845b6040518115909202916000818181858888f19350505050158015610c99573d6000803e3d6000fd5b50505050565b6060600380546108b790611aab565b6001600160a01b0381166000908152600d6020526040812054610cd08361099c565b610cda9190611a94565b92915050565b6000546001600160a01b03163314610d0a5760405162461bcd60e51b81526004016106c190611986565b6001600160a01b0382166000908152600b602052604090205460ff1615610d2f575050565b7f00000000000000000000000000000000000000000000000000000000000000008110610d6457610d608282610e0a565b5050565b610d60826000610e0a565b6000546001600160a01b03163314610d995760405162461bcd60e51b81526004016106c190611986565b6001600160a01b038116610dfe5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016106c1565b610e07816112ad565b50565b6001600160a01b03821660009081526006602052604090205480821115610e43576000610e378284611a94565b9050610c99848261144c565b80821015610e63576000610e578383611a94565b9050610c998482611591565b505050565b600a5460009081906001600160a01b031681610e8385610cae565b905080156112a0576001600160a01b0385166000908152600d602052604081208054839290610eb39084906119fc565b925050819055508060096000828254610ecc91906119fc565b90915550506040518181526001600160a01b038616907fee503bee2bb6a87e57bc57db795f98137327401a0e7b7ce42e37926cc1a9ca4d9060200160405180910390a26001546040805160028082526060820183526001600160a01b0390931692600092602083019080368337019050509050816001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b158015610f7857600080fd5b505afa158015610f8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb0919061177b565b81600081518110610fc357610fc3611b37565b6001600160a01b039283166020918202929092010152600a54825191169082906001908110610ff457610ff4611b37565b6001600160a01b0392831660209182029290920101526040516370a0823160e01b8152306004820152600091829182918816906370a082319060240160206040518083038186803b15801561104857600080fd5b505afa15801561105c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110809190611889565b9050846001600160a01b031663b6f9de958760008730426040518663ffffffff1660e01b81526004016110b694939291906118c7565b6000604051808303818588803b1580156110cf57600080fd5b505af1935050505080156110e1575060015b611123576110ed611b4d565b806308c379a014156111175750611102611b69565b8061110d5750611119565b6000935050611233565b505b3d6000803e3d6000fd5b6040516370a0823160e01b81523060048201526001935081906001600160a01b038916906370a082319060240160206040518083038186803b15801561116857600080fd5b505afa15801561117c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a09190611889565b6111aa9190611a94565b60405163a9059cbb60e01b81526001600160a01b038c81166004830152602482018390529193509088169063a9059cbb90604401602060405180830381600087803b1580156111f857600080fd5b505af115801561120c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611230919061186c565b92505b82611290576001600160a01b038a166000908152600d602052604081208054889290611260908490611a94565b9250508190555085600960008282546112799190611a94565b9091555060009b8c9b509950505050505050505050565b5093989397509295505050505050565b5060009485945092505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008061130983610cae565b90508015610c23576001600160a01b0383166000908152600d6020526040812080548392906113399084906119fc565b92505081905550806009600082825461135291906119fc565b90915550506040518181526001600160a01b038416907fee503bee2bb6a87e57bc57db795f98137327401a0e7b7ce42e37926cc1a9ca4d9060200160405180910390a26000836001600160a01b031682610bb890604051600060405180830381858888f193505050503d80600081146113e7576040519150601f19603f3d011682016040523d82523d6000602084013e6113ec565b606091505b5050905080611445576001600160a01b0384166000908152600d60205260408120805484929061141d908490611a94565b9250508190555081600960008282546114369190611a94565b90915550600095945050505050565b5092915050565b6001600160a01b0382166114bb5760405162461bcd60e51b815260206004820152603060248201527f504c555455535f4469766964656e64547261636b65723a206d696e7420746f2060448201526f746865207a65726f206164647265737360801b60648201526084016106c1565b80600560008282546114cd91906119fc565b90915550506001600160a01b038216600090815260066020526040812080548392906114fa9084906119fc565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a38060075461154e9190611a36565b6001600160a01b0383166000908152600c60205260409020546115719190611a55565b6001600160a01b039092166000908152600c602052604090209190915550565b6001600160a01b0382166116025760405162461bcd60e51b815260206004820152603260248201527f504c555455535f4469766964656e64547261636b65723a206275726e2066726f6044820152716d20746865207a65726f206164647265737360701b60648201526084016106c1565b6001600160a01b038216600090815260066020526040902054818110156116875760405162461bcd60e51b815260206004820152603360248201527f504c555455535f4469766964656e64547261636b65723a206275726e20616d6f604482015272756e7420657863656564732062616c616e636560681b60648201526084016106c1565b6116918282611a94565b6001600160a01b038416600090815260066020526040812091909155600580548492906116bf908490611a94565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3816007546117139190611a36565b6001600160a01b0384166000908152600c602052604090205461173691906119bb565b6001600160a01b039093166000908152600c60205260409020929092555050565b60006020828403121561176957600080fd5b813561177481611bf3565b9392505050565b60006020828403121561178d57600080fd5b815161177481611bf3565b600080604083850312156117ab57600080fd5b82356117b681611bf3565b946020939093013593505050565b600080604083850312156117d757600080fd5b82356117e281611bf3565b915060208301356117f281611bf3565b809150509250929050565b60008060006060848603121561181257600080fd5b833561181d81611bf3565b9250602084013561182d81611bf3565b929592945050506040919091013590565b6000806040838503121561185157600080fd5b823561185c81611bf3565b915060208301356117f281611c08565b60006020828403121561187e57600080fd5b815161177481611c08565b60006020828403121561189b57600080fd5b5051919050565b600080604083850312156118b557600080fd5b8235915060208301356117f281611bf3565b600060808201868352602060808185015281875180845260a086019150828901935060005b818110156119115784516001600160a01b0316835293830193918301916001016118ec565b50506001600160a01b039690961660408501525050506060015292915050565b600060208083528351808285015260005b8181101561195e57858101830151858201604001528201611942565b81811115611970576000604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600080821280156001600160ff1b03849003851316156119dd576119dd611b21565b600160ff1b83900384128116156119f6576119f6611b21565b50500190565b60008219821115611a0f57611a0f611b21565b500190565b600082611a3157634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615611a5057611a50611b21565b500290565b60008083128015600160ff1b850184121615611a7357611a73611b21565b6001600160ff1b0384018313811615611a8e57611a8e611b21565b50500390565b600082821015611aa657611aa6611b21565b500390565b600181811c90821680611abf57607f821691505b60208210811415611ae057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8201601f1916810167ffffffffffffffff81118282101715611b1a57634e487b7160e01b600052604160045260246000fd5b6040525050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060033d1115611b665760046000803e5060005160e01c5b90565b600060443d1015611b775790565b6040516003193d81016004833e81513d67ffffffffffffffff8160248401118184111715611ba757505050505090565b8285019150815181811115611bbf5750505050505090565b843d8701016020828501011115611bd95750505050505090565b611be860208286010187611ae6565b509095945050505050565b6001600160a01b0381168114610e0757600080fd5b8015158114610e0757600080fdfea2646970667358221220caa2ebafd5602df2b762601a919ad7855dc5ef98b168e5397241f8c74fead4a664736f6c63430008070033

Deployed Bytecode

0x6080604052600436106103d25760003560e01c8063744d1591116101fd578063bd9a3b6d11610118578063d8f281b7116100ab578063e4956ce21161007a578063e4956ce214610b95578063e9910b2b14610bb5578063eb50e70e14610bcb578063f2fde38b14610beb578063f69e204614610c0b57600080fd5b8063d8f281b714610b03578063dd62ed3e14610b19578063e01af92c14610b5f578063e2f4560514610b7f57600080fd5b8063c705c569116100e7578063c705c56914610a8d578063c98139e614610aad578063d2fcc00114610ac3578063d4c989d314610ae357600080fd5b8063bd9a3b6d14610a0d578063c024666814610a2d578063c3033aeb14610a4d578063c6af580b14610a6d57600080fd5b8063a457c2d711610190578063a9059cbb1161015f578063a9059cbb14610997578063aa4e8c4a146109b7578063aafd847a146109d7578063af7999cd146109f757600080fd5b8063a457c2d714610917578063a680e0bc14610937578063a68fe71a14610957578063a8b9d2401461097757600080fd5b80638da5cb5b116101cc5780638da5cb5b146108a45780638e126944146108c257806395d89b41146108e25780639c8e841d146108f757600080fd5b8063744d159114610806578063769758e51461081c5780637b510fe814610832578063870bd30b1461088457600080fd5b806337eb1528116102ed57806358076c57116102805780636dd3d39f1161024f5780636dd3d39f146107635780636ddd17131461079c57806370a08231146107bb578063715018a6146107f157600080fd5b806358076c57146106d55780635e843ad2146106ea578063658c27a91461070a57806368c51e351461074357600080fd5b806349bd5a5e116102bc57806349bd5a5e146106515780634e71d92d146106715780634fbee1931461068657806357777d31146106bf57600080fd5b806337eb1528146105f057806339509351146106065780633ee0ce021461062657806340225fce1461063b57600080fd5b806318160ddd1161036557806327ce01471161033457806327ce0147146105735780632c1f5216146105935780632f4504ae146105b3578063313ce567146105d457600080fd5b806318160ddd1461051257806319c76c2514610527578063225e5eb71461053d57806323b872dd1461055357600080fd5b80630dd87157116103a15780630dd871571461047b57806312e652d91461049f57806314d9aa70146104dc5780631694505e146104f257600080fd5b80630483f7a0146103de57806306fdde0314610400578063095ea7b31461042b5780630b6bb6f51461045b57600080fd5b366103d957005b600080fd5b3480156103ea57600080fd5b506103fe6103f9366004612e0d565b610c20565b005b34801561040c57600080fd5b50610415610cbe565b60405161042291906130c0565b60405180910390f35b34801561043757600080fd5b5061044b610446366004612e3b565b610d50565b6040519015158152602001610422565b34801561046757600080fd5b506103fe610476366004612eb0565b610d66565b34801561048757600080fd5b5061049160115481565b604051908152602001610422565b3480156104ab57600080fd5b506014546104c49061010090046001600160a01b031681565b6040516001600160a01b039091168152602001610422565b3480156104e857600080fd5b5061049160095481565b3480156104fe57600080fd5b50601d546104c4906001600160a01b031681565b34801561051e57600080fd5b50601354610491565b34801561053357600080fd5b50610491600c5481565b34801561054957600080fd5b50610491600d5481565b34801561055f57600080fd5b5061044b61056e366004612dcc565b610e02565b34801561057f57600080fd5b5061049161058e366004612d52565b610eb4565b34801561059f57600080fd5b50601c546104c4906001600160a01b031681565b3480156105bf57600080fd5b5060125461044b906301000000900460ff1681565b3480156105e057600080fd5b5060405160128152602001610422565b3480156105fc57600080fd5b50610491600f5481565b34801561061257600080fd5b5061044b610621366004612e3b565b610f39565b34801561063257600080fd5b506103fe610f70565b34801561064757600080fd5b50610491600e5481565b34801561065d57600080fd5b50601e546104c4906001600160a01b031681565b34801561067d57600080fd5b506103fe610fd5565b34801561069257600080fd5b5061044b6106a1366004612d52565b6001600160a01b031660009081526017602052604090205460ff1690565b3480156106cb57600080fd5b50610491601f5481565b3480156106e157600080fd5b506103fe611064565b3480156106f657600080fd5b506103fe610705366004612fb6565b611364565b34801561071657600080fd5b5061044b610725366004612d52565b6001600160a01b03166000908152601a602052604090205460ff1690565b34801561074f57600080fd5b506103fe61075e366004612ff8565b6113bc565b34801561076f57600080fd5b5061044b61077e366004612d52565b6001600160a01b03166000908152601b602052604090205460ff1690565b3480156107a857600080fd5b5060125461044b90610100900460ff1681565b3480156107c757600080fd5b506104916107d6366004612d52565b6001600160a01b031660009081526015602052604090205490565b3480156107fd57600080fd5b506103fe6113eb565b34801561081257600080fd5b5061049160205481565b34801561082857600080fd5b5061049160085481565b34801561083e57600080fd5b5061085261084d366004612d52565b61141f565b604080516001600160a01b0390961686526020860194909452928401919091526060830152608082015260a001610422565b34801561089057600080fd5b5060125461044b9062010000900460ff1681565b3480156108b057600080fd5b506000546001600160a01b03166104c4565b3480156108ce57600080fd5b506103fe6108dd36600461302a565b6114b8565b3480156108ee57600080fd5b5061041561151b565b34801561090357600080fd5b506103fe610912366004612e0d565b61152a565b34801561092357600080fd5b5061044b610932366004612e3b565b6115e8565b34801561094357600080fd5b50610491610952366004612d52565b611684565b34801561096357600080fd5b506103fe610972366004612ff8565b6116b7565b34801561098357600080fd5b50610491610992366004612d52565b6116e6565b3480156109a357600080fd5b5061044b6109b2366004612e3b565b611719565b3480156109c357600080fd5b506103fe6109d2366004612ff8565b611726565b3480156109e357600080fd5b506104916109f2366004612d52565b611755565b348015610a0357600080fd5b50610491600a5481565b348015610a1957600080fd5b506103fe610a2836600461307d565b611788565b348015610a3957600080fd5b506103fe610a48366004612e0d565b6117f0565b348015610a5957600080fd5b506103fe610a68366004612eb0565b611902565b348015610a7957600080fd5b506103fe610a88366004612f7c565b61199a565b348015610a9957600080fd5b5061044b610aa8366004612d52565b611a1a565b348015610ab957600080fd5b5061049160075481565b348015610acf57600080fd5b506103fe610ade366004612e0d565b611a98565b348015610aef57600080fd5b506103fe610afe366004612e0d565b611aed565b348015610b0f57600080fd5b5061049160065481565b348015610b2557600080fd5b50610491610b34366004612d93565b6001600160a01b03918216600090815260166020908152604080832093909416825291909152205490565b348015610b6b57600080fd5b506103fe610b7a366004612f7c565b611b42565b348015610b8b57600080fd5b5061049160105481565b348015610ba157600080fd5b506103fe610bb0366004612f7c565b611bb5565b348015610bc157600080fd5b50610491600b5481565b348015610bd757600080fd5b506103fe610be6366004612d52565b611c2c565b348015610bf757600080fd5b506103fe610c06366004612d52565b611c7e565b348015610c1757600080fd5b506103fe611d16565b6000546001600160a01b03163314610c535760405162461bcd60e51b8152600401610c4a906131e6565b60405180910390fd5b601c5460405162241fbd60e51b81526001600160a01b038481166004830152831515602483015290911690630483f7a0906044015b600060405180830381600087803b158015610ca257600080fd5b505af1158015610cb6573d6000803e3d6000fd5b505050505050565b606060048054610ccd906132fc565b80601f0160208091040260200160405190810160405280929190818152602001828054610cf9906132fc565b8015610d465780601f10610d1b57610100808354040283529160200191610d46565b820191906000526020600020905b815481529060010190602001808311610d2957829003601f168201915b5050505050905090565b6000610d5d338484611d91565b50600192915050565b6000546001600160a01b03163314610d905760405162461bcd60e51b8152600401610c4a906131e6565b60005b81518160ff161015610dfe57600160186000848460ff1681518110610dba57610dba61336d565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580610df681613337565b915050610d93565b5050565b6000610e0f848484611eb8565b6001600160a01b038416600090815260166020908152604080832033845290915290205482811015610e955760405162461bcd60e51b815260206004820152602960248201527f504c555455533a207472616e7366657220616d6f756e74206578636565647320604482015268616c6c6f77616e636560b81b6064820152608401610c4a565b610ea98533610ea486856132e5565b611d91565b506001949350505050565b601c546040516327ce014760e01b81526001600160a01b03838116600483015260009216906327ce0147906024015b60206040518083038186803b158015610efb57600080fd5b505afa158015610f0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f339190613011565b92915050565b3360008181526016602090815260408083206001600160a01b03871684529091528120549091610d5d918590610ea490869061328c565b6000546001600160a01b03163314610f9a5760405162461bcd60e51b8152600401610c4a906131e6565b30600090815260156020526040902054601254479060ff16158015610fc0575060105482115b15610fcb5760105491505b610dfe8282612668565b601c546001600160a01b031663807ab4f7335b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381600087803b15801561102957600080fd5b505af115801561103d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110619190612f99565b50565b6000546001600160a01b0316331461108e5760405162461bcd60e51b8152600401610c4a906131e6565b601c5460405162241fbd60e51b81526001600160a01b03909116600482018190526001602483015290630483f7a090604401600060405180830381600087803b1580156110da57600080fd5b505af11580156110ee573d6000803e3d6000fd5b5050601c5460405162241fbd60e51b8152306004820152600160248201526001600160a01b039091169250630483f7a09150604401600060405180830381600087803b15801561113d57600080fd5b505af1158015611151573d6000803e3d6000fd5b5050601c546001600160a01b03169150630483f7a0905061117a6000546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260016024820152604401600060405180830381600087803b1580156111c257600080fd5b505af11580156111d6573d6000803e3d6000fd5b5050601c54601d5460405162241fbd60e51b81526001600160a01b0391821660048201526001602482015291169250630483f7a09150604401600060405180830381600087803b15801561122957600080fd5b505af115801561123d573d6000803e3d6000fd5b5050601c5460025460405162241fbd60e51b81526001600160a01b0391821660048201526001602482015291169250630483f7a09150604401600060405180830381600087803b15801561129057600080fd5b505af11580156112a4573d6000803e3d6000fd5b505050506112c46112bd6000546001600160a01b031690565b60016117f0565b6112cf3060016117f0565b601c546112e6906001600160a01b031660016117f0565b6113026112fb6000546001600160a01b031690565b6001611aed565b61130d306001611aed565b601c54611324906001600160a01b03166001611aed565b6113406113396000546001600160a01b031690565b6001611a98565b61134b306001611a98565b601c54611362906001600160a01b03166001611a98565b565b6000546001600160a01b0316331461138e5760405162461bcd60e51b8152600401610c4a906131e6565b6012805460109390935590151560ff19931515610100029390931661ffff1990921691909117919091179055565b6000546001600160a01b031633146113e65760405162461bcd60e51b8152600401610c4a906131e6565b602055565b6000546001600160a01b031633146114155760405162461bcd60e51b8152600401610c4a906131e6565b61136260006129e0565b601c54604051630f6a21fd60e31b81526001600160a01b0383811660048301526000928392839283928392911690637b510fe89060240160a06040518083038186803b15801561146e57600080fd5b505afa158015611482573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a69190612e67565b939a9299509097509550909350915050565b6000546001600160a01b031633146114e25760405162461bcd60e51b8152600401610c4a906131e6565b601c546040516323849a5160e21b8152600481018490526001600160a01b03838116602483015290911690638e12694490604401610c88565b606060058054610ccd906132fc565b6000546001600160a01b031633146115545760405162461bcd60e51b8152600401610c4a906131e6565b6001600160a01b03821660009081526019602052604090205460ff16156115bd5760405162461bcd60e51b815260206004820152601860248201527f7573657220616c726561647920626c61636b6c697374656400000000000000006044820152606401610c4a565b6001600160a01b03919091166000908152601960205260409020805460ff1916911515919091179055565b3360009081526016602090815260408083206001600160a01b03861684529091528120548281101561166b5760405162461bcd60e51b815260206004820152602660248201527f504c555455533a2064656372656173656420616c6c6f77616e63652062656c6f60448201526577207a65726f60d01b6064820152608401610c4a565b61167a3385610ea486856132e5565b5060019392505050565b601c546040516329a0382f60e21b81526001600160a01b038381166004830152600092169063a680e0bc90602401610ee3565b6000546001600160a01b031633146116e15760405162461bcd60e51b8152600401610c4a906131e6565b602155565b601c546040516302a2e74960e61b81526001600160a01b038381166004830152600092169063a8b9d24090602401610ee3565b6000610d5d338484611eb8565b6000546001600160a01b031633146117505760405162461bcd60e51b8152600401610c4a906131e6565b601f55565b601c5460405163557ec23d60e11b81526001600160a01b038381166004830152600092169063aafd847a90602401610ee3565b6000546001600160a01b031633146117b25760405162461bcd60e51b8152600401610c4a906131e6565b6009869055600a859055600b849055600c839055600d829055600e819055836117db868861328c565b6117e5919061328c565b600f55505050505050565b6000546001600160a01b0316331461181a5760405162461bcd60e51b8152600401610c4a906131e6565b6001600160a01b03821660009081526017602052604090205460ff16151581151514156118a35760405162461bcd60e51b815260206004820152603160248201527f504c555455533a206163636f756e7420697320616c72656164792073657420746044820152706f2072657175657374656420737461746560781b6064820152608401610c4a565b6001600160a01b038216600081815260176020908152604091829020805460ff191685151590811790915591519182527f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df7910160405180910390a25050565b6000546001600160a01b0316331461192c5760405162461bcd60e51b8152600401610c4a906131e6565b60005b81518160ff161015610dfe57600160196000848460ff16815181106119565761195661336d565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff19169115159190911790558061199281613337565b91505061192f565b6000546001600160a01b031633146119c45760405162461bcd60e51b8152600401610c4a906131e6565b60128054821515620100000262ff0000199091161790556040517f5bb2376cf656637e70e36c01d3da25685bf3b353f18681b8a5e48c7b2effe13390611a0f90831515815260200190565b60405180910390a150565b601c5460405163c705c56960e01b81526001600160a01b038381166004830152600092169063c705c5699060240160206040518083038186803b158015611a6057600080fd5b505afa158015611a74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f339190612f99565b6000546001600160a01b03163314611ac25760405162461bcd60e51b8152600401610c4a906131e6565b6001600160a01b03919091166000908152601b60205260409020805460ff1916911515919091179055565b6000546001600160a01b03163314611b175760405162461bcd60e51b8152600401610c4a906131e6565b6001600160a01b03919091166000908152601a60205260409020805460ff1916911515919091179055565b6000546001600160a01b03163314611b6c5760405162461bcd60e51b8152600401610c4a906131e6565b601280548215156101000261ff00199091161790556040517fb9bbb15e341600c8d067a0cadeba219905d5ba6d422b193c9c32265d26fc51c890611a0f90831515815260200190565b6000546001600160a01b03163314611bdf5760405162461bcd60e51b8152600401610c4a906131e6565b6012805482151563010000000263ff000000199091161790556040517f341322866a3a2c26c27efa4c270c5ba86f6963257118897dd8196f224c002d4390611a0f90831515815260200190565b6000546001600160a01b03163314611c565760405162461bcd60e51b8152600401610c4a906131e6565b601480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6000546001600160a01b03163314611ca85760405162461bcd60e51b8152600401610c4a906131e6565b6001600160a01b038116611d0d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c4a565b611061816129e0565b6012546301000000900460ff16611d7a5760405162461bcd60e51b815260206004820152602260248201527f504c555455533a20636f6d706f756e64696e67206973206e6f7420656e61626c604482015261195960f21b6064820152608401610c4a565b601c546001600160a01b0316636de1a5a933610fe8565b6001600160a01b038316611df55760405162461bcd60e51b815260206004820152602560248201527f504c555455533a20617070726f76652066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610c4a565b6001600160a01b038216611e575760405162461bcd60e51b815260206004820152602360248201527f504c555455533a20617070726f766520746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610c4a565b6001600160a01b0383811660008181526016602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b426021541080611ed557506000546001600160a01b038481169116145b80611eed57506000546001600160a01b038381169116145b80611f1057506001600160a01b03831660009081526018602052604090205460ff165b80611f3357506001600160a01b03821660009081526018602052604090205460ff165b611f7f5760405162461bcd60e51b815260206004820181905260248201527f504c555455533a20546f6b656e2069736e2774207472616461626c65207965746044820152606401610c4a565b6001600160a01b03831660009081526019602052604090205460ff1615611fe85760405162461bcd60e51b815260206004820152601d60248201527f504c555455533a2053656e64657220697320626c61636b6c69737465640000006044820152606401610c4a565b6001600160a01b03821660009081526019602052604090205460ff16156120515760405162461bcd60e51b815260206004820181905260248201527f504c555455533a20526563697069656e7420697320626c61636b6c69737465646044820152606401610c4a565b6001600160a01b0383166120775760405162461bcd60e51b8152600401610c4a90613115565b6001600160a01b03821661209d5760405162461bcd60e51b8152600401610c4a9061315b565b6000612710601f546120ae60135490565b6120b891906132c6565b6120c291906132a4565b905060006127106020546120d560135490565b6120df91906132c6565b6120e991906132a4565b9050818311158061211257506001600160a01b0385166000908152601a602052604090205460ff165b6121525760405162461bcd60e51b8152602060048201526011602482015270151608131a5b5a5d08115e18d959591959607a1b6044820152606401610c4a565b6000546001600160a01b0386811691161480159061217957506001600160a01b0384163014155b801561219357506002546001600160a01b03858116911614155b80156121ad5750601e546001600160a01b03858116911614155b156121f9576001600160a01b038416600090815260156020908152604080832054601b9092529091205460ff16806121ee5750816121eb858361328c565b11155b6121f757600080fd5b505b6001600160a01b038516600090815260156020526040902054838110156122325760405162461bcd60e51b8152600401610c4a9061319f565b30600090815260156020526040902054601054601254479183101590610100900460ff16801561225f5750805b801561226e575060145460ff16155b80156122885750601d546001600160a01b038a8116911614155b80156122a257506000546001600160a01b038a8116911614155b80156122bc57506000546001600160a01b03898116911614155b15612306576014805460ff1916600117905560125460ff161580156122e2575060105483115b156122ed5760105492505b6122f78383612668565b426011556014805460ff191690555b601e546000906001600160a01b038b811691161480156123345750601d546001600160a01b038a8116911614155b806123655750601e546001600160a01b038a811691161480156123655750601d546001600160a01b038b8116911614155b1561236e575060015b6001600160a01b038a1660009081526017602052604090205460ff16806123ad57506001600160a01b03891660009081526017602052604090205460ff165b156123b6575060005b60145460ff16806123d0575060125462010000900460ff16155b156123d9575060005b801561253157601e546001600160a01b038b81169116141561246c57600b54600a54600954612408919061328c565b612412919061328c565b600f819055600954612424908a6132c6565b61242e91906132a4565b600655600f54600a54612441908a6132c6565b61244b91906132a4565b600755600f54600b5461245e908a6132c6565b61246891906132a4565b6008555b601e546001600160a01b038a8116911614156124f957600e54600d54600c54612495919061328c565b61249f919061328c565b600f819055600c546124b1908a6132c6565b6124bb91906132a4565b600655600f54600d546124ce908a6132c6565b6124d891906132a4565b600755600f54600e546124eb908a6132c6565b6124f591906132a4565b6008555b6000612710600f548a61250c91906132c6565b61251691906132a4565b9050612522818a6132e5565b985061252f8b3083612a30565b505b61253c8a8a8a612a30565b601c546001600160a01b031663e30443bc8b61256d816001600160a01b031660009081526015602052604090205490565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156125b357600080fd5b505af11580156125c7573d6000803e3d6000fd5b5050601c546001600160a01b0316915063e30443bc90508a6125fe816001600160a01b031660009081526015602052604090205490565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561264457600080fd5b505af1158015612658573d6000803e3d6000fd5b5050505050505050505050505050565b60008211612674575050565b6000600854600754600654612689919061328c565b612693919061328c565b60145490915060009061010090046001600160a01b0316156126cb5781600654856126be91906132c6565b6126c891906132a4565b90505b600080601c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561271c57600080fd5b505afa158015612730573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127549190613011565b111561277657826008548661276991906132c6565b61277391906132a4565b90505b60008161278384886132e5565b61278d91906132e5565b9050600061279c6002836132a4565b905060006127aa82846132e5565b90506000826127b9868861328c565b6127c3919061328c565b9050476127cf82612b4f565b6000896127dc83476132e5565b6127e6919061328c565b90506000836127f58a846132c6565b6127ff91906132a4565b905060008461280e8a856132c6565b61281891906132a4565b905060008161282784866132e5565b61283191906132e5565b905082156128d85760145460405160009161010090046001600160a01b03169085908381818185875af1925050503d806000811461288b576040519150601f19603f3d011682016040523d82523d6000602084013e612890565b606091505b50509050806128d65760405162461bcd60e51b815260206004820152601260248201527128262aaa2aa99d102a3c103330b4b632b21760711b6044820152606401610c4a565b505b6128e28782612c82565b60408051898152602081018390529081018890527fb63dc6f50047533abe2d6adf180d38d524c8d98e55ad199aac8d6b9801bbe24a9060600160405180910390a181156129c157601c546040516000916001600160a01b03169084908381818185875af1925050503d8060008114612976576040519150601f19603f3d011682016040523d82523d6000602084013e61297b565b606091505b5050905080156129bf57604080518c8152602081018590527f80195cc573b02cc48460cbca6e6e4cc85ddb91959d946e1c3025ea3d87942dc3910160405180910390a15b505b5050600060068190556007819055600855505050505050505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038316612a565760405162461bcd60e51b8152600401610c4a90613115565b6001600160a01b038216612a7c5760405162461bcd60e51b8152600401610c4a9061315b565b6001600160a01b03831660009081526015602052604090205481811015612ab55760405162461bcd60e51b8152600401610c4a9061319f565b612abf82826132e5565b6001600160a01b038086166000908152601560205260408082209390935590851681529081208054849290612af590849061328c565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612b4191815260200190565b60405180910390a350505050565b6040805160028082526060820183526000926020830190803683370190505090503081600081518110612b8457612b8461336d565b6001600160a01b03928316602091820292909201810191909152601d54604080516315ab88c960e31b81529051919093169263ad5c4648926004808301939192829003018186803b158015612bd857600080fd5b505afa158015612bec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c109190612d76565b81600181518110612c2357612c2361336d565b6001600160a01b039283166020918202929092010152601d54612c499130911684611d91565b601d5460405163791ac94760e01b81526001600160a01b039091169063791ac94790610c8890859060009086903090429060040161321b565b601d54612c9a9030906001600160a01b031684611d91565b601d5460405163f305d71960e01b8152306004820181905260248201859052600060448301819052606483015260848201524260a48201526001600160a01b039091169063f305d71990839060c4016060604051808303818588803b158015612d0257600080fd5b505af1158015612d16573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612d3b919061304f565b5050505050565b8035612d4d81613399565b919050565b600060208284031215612d6457600080fd5b8135612d6f81613399565b9392505050565b600060208284031215612d8857600080fd5b8151612d6f81613399565b60008060408385031215612da657600080fd5b8235612db181613399565b91506020830135612dc181613399565b809150509250929050565b600080600060608486031215612de157600080fd5b8335612dec81613399565b92506020840135612dfc81613399565b929592945050506040919091013590565b60008060408385031215612e2057600080fd5b8235612e2b81613399565b91506020830135612dc1816133ae565b60008060408385031215612e4e57600080fd5b8235612e5981613399565b946020939093013593505050565b600080600080600060a08688031215612e7f57600080fd5b8551612e8a81613399565b602087015160408801516060890151608090990151929a91995097965090945092505050565b60006020808385031215612ec357600080fd5b823567ffffffffffffffff80821115612edb57600080fd5b818501915085601f830112612eef57600080fd5b813581811115612f0157612f01613383565b8060051b604051601f19603f83011681018181108582111715612f2657612f26613383565b604052828152858101935084860182860187018a1015612f4557600080fd5b600095505b83861015612f6f57612f5b81612d42565b855260019590950194938601938601612f4a565b5098975050505050505050565b600060208284031215612f8e57600080fd5b8135612d6f816133ae565b600060208284031215612fab57600080fd5b8151612d6f816133ae565b600080600060608486031215612fcb57600080fd5b8335612fd6816133ae565b9250602084013591506040840135612fed816133ae565b809150509250925092565b60006020828403121561300a57600080fd5b5035919050565b60006020828403121561302357600080fd5b5051919050565b6000806040838503121561303d57600080fd5b823591506020830135612dc181613399565b60008060006060848603121561306457600080fd5b8351925060208401519150604084015190509250925092565b60008060008060008060c0878903121561309657600080fd5b505084359660208601359650604086013595606081013595506080810135945060a0013592509050565b600060208083528351808285015260005b818110156130ed578581018301518582016040015282016130d1565b818111156130ff576000604083870101525b50601f01601f1916929092016040019392505050565b60208082526026908201527f504c555455533a207472616e736665722066726f6d20746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526024908201527f504c555455533a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526027908201527f504c555455533a207472616e7366657220616d6f756e7420657863656564732060408201526662616c616e636560c81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b8181101561326b5784516001600160a01b031683529383019391830191600101613246565b50506001600160a01b03969096166060850152505050608001529392505050565b6000821982111561329f5761329f613357565b500190565b6000826132c157634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156132e0576132e0613357565b500290565b6000828210156132f7576132f7613357565b500390565b600181811c9082168061331057607f821691505b6020821081141561333157634e487b7160e01b600052602260045260246000fd5b50919050565b600060ff821660ff81141561334e5761334e613357565b60010192915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461106157600080fd5b801515811461106157600080fdfea2646970667358221220f3a835d6eae0246c1dba2aaddb7a9c0d09eb6dac6c5e08d705328d0cd17b9ffa64736f6c63430008070033

Deployed Bytecode Sourcemap

124:20986:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16777:171;;;;;;;;;;-1:-1:-1;16777:171:1;;;;;:::i;:::-;;:::i;:::-;;3260:81;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4004:202;;;;;;;;;;-1:-1:-1;4004:202:1;;;;;:::i;:::-;;:::i;:::-;;;9096:14:2;;9089:22;9071:41;;9059:2;9044:18;4004:202:1;8931:187:2;12967:181:1;;;;;;;;;;-1:-1:-1;12967:181:1;;;;;:::i;:::-;;:::i;1094:27::-;;;;;;;;;;;;;;;;;;;16908:25:2;;;16896:2;16881:18;1094:27:1;16762:177:2;1359:101:1;;;;;;;;;;-1:-1:-1;1359:101:1;;;;;;;-1:-1:-1;;;;;1359:101:1;;;;;;-1:-1:-1;;;;;6973:32:2;;;6955:51;;6943:2;6928:18;1359:101:1;6809:203:2;635:40:1;;;;;;;;;;;;;;;;2531:41;;;;;;;;;;-1:-1:-1;2531:41:1;;;;-1:-1:-1;;;;;2531:41:1;;;3518:106;;;;;;;;;;-1:-1:-1;3605:12:1;;3518:106;;770:42;;;;;;;;;;;;;;;;818:40;;;;;;;;;;;;;;;;5125:477;;;;;;;;;;-1:-1:-1;5125:477:1;;;;;:::i;:::-;;:::i;18589:178::-;;;;;;;;;;-1:-1:-1;18589:178:1;;;;;:::i;:::-;;:::i;2487:38::-;;;;;;;;;;-1:-1:-1;2487:38:1;;;;-1:-1:-1;;;;;2487:38:1;;;1229:37;;;;;;;;;;-1:-1:-1;1229:37:1;;;;;;;;;;;3438:74;;;;;;;;;;-1:-1:-1;3438:74:1;;3503:2;18927:36:2;;18915:2;18900:18;3438:74:1;18785:184:2;907:121:1;;;;;;;;;;;;;;;;4212:270;;;;;;;;;;-1:-1:-1;4212:270:1;;;;;:::i;:::-;;:::i;15750:388::-;;;;;;;;;;;;;:::i;864:37::-;;;;;;;;;;;;;;;;2579:28;;;;;;;;;;-1:-1:-1;2579:28:1;;;;-1:-1:-1;;;;;2579:28:1;;;17948:94;;;;;;;;;;;;;:::i;16475:124::-;;;;;;;;;;-1:-1:-1;16475:124:1;;;;;:::i;:::-;-1:-1:-1;;;;;16564:28:1;16541:4;16564:28;;;:19;:28;;;;;;;;;16475:124;2614:28;;;;;;;;;;;;;;;;5608:860;;;;;;;;;;;;;:::i;19626:280::-;;;;;;;;;;-1:-1:-1;19626:280:1;;;;;:::i;:::-;;:::i;20140:126::-;;;;;;;;;;-1:-1:-1;20140:126:1;;;;;:::i;:::-;-1:-1:-1;;;;;20230:29:1;20207:4;20230:29;;;:20;:29;;;;;;;;;20140:126;20272:92;;;;;;;;;;-1:-1:-1;20272:92:1;;;;;:::i;:::-;;:::i;20536:162::-;;;;;;;;;;-1:-1:-1;20536:162:1;;;;;:::i;:::-;-1:-1:-1;;;;;20658:33:1;20631:4;20658:33;;;:24;:33;;;;;;;;;20536:162;1158:30;;;;;;;;;;-1:-1:-1;1158:30:1;;;;;;;;;;;3630:169;;;;;;;;;;-1:-1:-1;3630:169:1;;;;;:::i;:::-;-1:-1:-1;;;;;3774:18:1;3744:7;3774:18;;;:9;:18;;;;;;;3630:169;1345:101:0;;;;;;;;;;;;;:::i;2648:33:1:-;;;;;;;;;;;;;;;;576:40;;;;;;;;;;;;;;;;18773:268;;;;;;;;;;-1:-1:-1;18773:268:1;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;8714:32:2;;;8696:51;;8778:2;8763:18;;8756:34;;;;8806:18;;;8799:34;;;;8864:2;8849:18;;8842:34;8907:3;8892:19;;8885:35;8683:3;8668:19;18773:268:1;8437:489:2;1194:29:1;;;;;;;;;;-1:-1:-1;1194:29:1;;;;;;;;;;;713:85:0;;;;;;;;;;-1:-1:-1;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;713:85;;16605:166:1;;;;;;;;;;-1:-1:-1;16605:166:1;;;;;:::i;:::-;;:::i;3347:85::-;;;;;;;;;;;;;:::i;20704:184::-;;;;;;;;;;-1:-1:-1;20704:184:1;;;;;:::i;:::-;;:::i;4488:417::-;;;;;;;;;;-1:-1:-1;4488:417:1;;;;;:::i;:::-;;:::i;19047:138::-;;;;;;;;;;-1:-1:-1;19047:138:1;;;;;:::i;:::-;;:::i;6474:110::-;;;;;;;;;;-1:-1:-1;6474:110:1;;;;;:::i;:::-;;:::i;18227:178::-;;;;;;;;;;-1:-1:-1;18227:178:1;;;;;:::i;:::-;;:::i;4911:208::-;;;;;;;;;;-1:-1:-1;4911:208:1;;;;;:::i;:::-;;:::i;19912:84::-;;;;;;;;;;-1:-1:-1;19912:84:1;;;;;:::i;:::-;;:::i;18411:172::-;;;;;;;;;;-1:-1:-1;18411:172:1;;;;;:::i;:::-;;:::i;681:39::-;;;;;;;;;;;;;;;;17284:658;;;;;;;;;;-1:-1:-1;17284:658:1;;;;;:::i;:::-;;:::i;16144:325::-;;;;;;;;;;-1:-1:-1;16144:325:1;;;;;:::i;:::-;;:::i;20894:179::-;;;;;;;;;;-1:-1:-1;20894:179:1;;;;;:::i;:::-;;:::i;19330:130::-;;;;;;;;;;-1:-1:-1;19330:130:1;;;;;:::i;:::-;;:::i;16954:177::-;;;;;;;;;;-1:-1:-1;16954:177:1;;;;;:::i;:::-;;:::i;530:40::-;;;;;;;;;;;;;;;;20370:160;;;;;;;;;;-1:-1:-1;20370:160:1;;;;;:::i;:::-;;:::i;20002:132::-;;;;;;;;;;-1:-1:-1;20002:132:1;;;;;:::i;:::-;;:::i;483:41::-;;;;;;;;;;;;;;;;3805:193;;;;;;;;;;-1:-1:-1;3805:193:1;;;;;:::i;:::-;-1:-1:-1;;;;;3964:18:1;;;3934:7;3964:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;3805:193;19191:133;;;;;;;;;;-1:-1:-1;19191:133:1;;;;;:::i;:::-;;:::i;1035:53::-;;;;;;;;;;;;;;;;19466:154;;;;;;;;;;-1:-1:-1;19466:154:1;;;;;:::i;:::-;;:::i;726:38::-;;;;;;;;;;;;;;;;17137:141;;;;;;;;;;-1:-1:-1;17137:141:1;;;;;:::i;:::-;;:::i;1595:232:0:-;;;;;;;;;;-1:-1:-1;1595:232:0;;;;;:::i;:::-;;:::i;18048:173:1:-;;;;;;;;;;;;;:::i;16777:171::-;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;;;;;;;;;16886:15:1::1;::::0;:55:::1;::::0;-1:-1:-1;;;16886:55:1;;-1:-1:-1;;;;;7722:32:2;;;16886:55:1::1;::::0;::::1;7704:51:2::0;7798:14;;7791:22;7771:18;;;7764:50;16886:15:1;;::::1;::::0;:36:::1;::::0;7677:18:2;;16886:55:1::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;16777:171:::0;;:::o;3260:81::-;3297:13;3329:5;3322:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3260:81;:::o;4004:202::-;4119:4;4139:39;168:10:0;4162:7:1;4171:6;4139:8;:39::i;:::-;-1:-1:-1;4195:4:1;4004:202;;;;:::o;12967:181::-;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;13052:7:1::1;13047:95;13069:6;:13;13065:1;:17;;;13047:95;;;13127:4;13103:10;:21;13114:6;13121:1;13114:9;;;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;;;13103:21:1::1;::::0;;;::::1;::::0;;;;;;-1:-1:-1;13103:21:1;:28;;-1:-1:-1;;13103:28:1::1;::::0;::::1;;::::0;;;::::1;::::0;;13084:3;::::1;::::0;::::1;:::i;:::-;;;;13047:95;;;;12967:181:::0;:::o;5125:477::-;5261:4;5277:36;5287:6;5295:9;5306:6;5277:9;:36::i;:::-;-1:-1:-1;;;;;5350:19:1;;5323:24;5350:19;;;:11;:19;;;;;;;;168:10:0;5350:33:1;;;;;;;;5414:26;;;;5393:114;;;;-1:-1:-1;;;5393:114:1;;13093:2:2;5393:114:1;;;13075:21:2;13132:2;13112:18;;;13105:30;13171:34;13151:18;;;13144:62;-1:-1:-1;;;13222:18:2;;;13215:39;13271:19;;5393:114:1;12891:405:2;5393:114:1;5517:57;5526:6;168:10:0;5548:25:1;5567:6;5548:16;:25;:::i;:::-;5517:8;:57::i;:::-;-1:-1:-1;5591:4:1;;5125:477;-1:-1:-1;;;;5125:477:1:o;18589:178::-;18713:15;;:47;;-1:-1:-1;;;18713:47:1;;-1:-1:-1;;;;;6973:32:2;;;18713:47:1;;;6955:51:2;18683:7:1;;18713:15;;:38;;6928:18:2;;18713:47:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18706:54;18589:178;-1:-1:-1;;18589:178:1:o;4212:270::-;168:10:0;4308:4:1;4397:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;4397:34:1;;;;;;;;;;4308:4;;4328:126;;4376:7;;4397:47;;4434:10;;4397:47;:::i;15750:388::-;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;15855:4:1::1;15806:28;3774:18:::0;;;:9;:18;;;;;;15940:12:::1;::::0;15903:21:::1;::::0;15940:12:::1;;15939:13;:58:::0;::::1;;;;15979:18;;15956:20;:41;15939:58;15935:130;;;16036:18;;16013:41;;15935:130;16074:57;16087:20;16109:21;16074:12;:57::i;17948:94::-:0;17982:15;;-1:-1:-1;;;;;17982:15:1;:30;168:10:0;18021:12:1;17982:53;;-1:-1:-1;;;;;;17982:53:1;;;;;;;-1:-1:-1;;;;;6973:32:2;;;17982:53:1;;;6955:51:2;6928:18;;17982:53:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;17948:94::o;5608:860::-;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;5670:15:1::1;::::0;:68:::1;::::0;-1:-1:-1;;;5670:68:1;;-1:-1:-1;;;;;5670:15:1;;::::1;:68;::::0;::::1;7704:51:2::0;;;5670:15:1;7771:18:2;;;7764:50;5670:15:1;:36:::1;::::0;7677:18:2;;5670:68:1::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;5748:15:1::1;::::0;:57:::1;::::0;-1:-1:-1;;;5748:57:1;;5793:4:::1;5748:57;::::0;::::1;7704:51:2::0;5748:15:1;7771:18:2;;;7764:50;-1:-1:-1;;;;;5748:15:1;;::::1;::::0;-1:-1:-1;5748:36:1::1;::::0;-1:-1:-1;7677:18:2;;5748:57:1::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;5815:15:1::1;::::0;-1:-1:-1;;;;;5815:15:1::1;::::0;-1:-1:-1;5815:36:1::1;::::0;-1:-1:-1;5852:7:1::1;759::0::0;785:6;-1:-1:-1;;;;;785:6:0;;713:85;5852:7:1::1;5815:51;::::0;-1:-1:-1;;;;;;5815:51:1::1;::::0;;;;;;-1:-1:-1;;;;;7722:32:2;;;5815:51:1::1;::::0;::::1;7704::2::0;5861:4:1::1;7771:18:2::0;;;7764:50;7677:18;;5815:51:1::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;5876:15:1::1;::::0;5921::::1;::::0;5876:68:::1;::::0;-1:-1:-1;;;5876:68:1;;-1:-1:-1;;;;;5921:15:1;;::::1;5876:68;::::0;::::1;7704:51:2::0;5876:15:1;7771:18:2;;;7764:50;5876:15:1;::::1;::::0;-1:-1:-1;5876:36:1::1;::::0;-1:-1:-1;7677:18:2;;5876:68:1::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;5954:15:1::1;::::0;5999:4:::1;::::0;5954:57:::1;::::0;-1:-1:-1;;;5954:57:1;;-1:-1:-1;;;;;5999:4:1;;::::1;5954:57;::::0;::::1;7704:51:2::0;5954:15:1;7771:18:2;;;7764:50;5954:15:1;::::1;::::0;-1:-1:-1;5954:36:1::1;::::0;-1:-1:-1;7677:18:2;;5954:57:1::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;6022:30;6038:7;759::0::0;785:6;-1:-1:-1;;;;;785:6:0;;713:85;6038:7:1::1;6047:4;6022:15;:30::i;:::-;6062:36;6086:4;6093;6062:15;:36::i;:::-;6132:15;::::0;6108:47:::1;::::0;-1:-1:-1;;;;;6132:15:1::1;::::0;6108::::1;:47::i;:::-;6166:31;6183:7;759::0::0;785:6;-1:-1:-1;;;;;785:6:0;;713:85;6183:7:1::1;6192:4;6166:16;:31::i;:::-;6207:37;6232:4;6239;6207:16;:37::i;:::-;6279:15;::::0;6254:48:::1;::::0;-1:-1:-1;;;;;6279:15:1::1;::::0;6254:16:::1;:48::i;:::-;6313:35;6334:7;759::0::0;785:6;-1:-1:-1;;;;;785:6:0;;713:85;6334:7:1::1;6343:4;6313:20;:35::i;:::-;6358:41;6387:4;6394;6358:20;:41::i;:::-;6438:15;::::0;6409:52:::1;::::0;-1:-1:-1;;;;;6438:15:1::1;::::0;6409:20:::1;:52::i;:::-;5608:860::o:0;19626:280::-;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;19785:11:1::1;:26:::0;;19821:18:::1;:40:::0;;;;19871:28;::::1;;-1:-1:-1::0;;19785:26:1;::::1;;;;19871:28:::0;;;;-1:-1:-1;;19871:28:1;;;;;;;;;;::::1;::::0;;19626:280::o;20272:92::-;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;20339:12:1::1;:18:::0;20272:92::o;1345:101:0:-;759:7;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;1409:30:::1;1436:1;1409:18;:30::i;18773:268:1:-:0;18995:15;;:39;;-1:-1:-1;;;18995:39:1;;-1:-1:-1;;;;;6973:32:2;;;18995:39:1;;;6955:51:2;18872:7:1;;;;;;;;;;18995:15;;;:30;;6928:18:2;;18995:39:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18988:46;;;;-1:-1:-1;18988:46:1;;-1:-1:-1;18988:46:1;-1:-1:-1;18988:46:1;;-1:-1:-1;18773:268:1;-1:-1:-1;;18773:268:1:o;16605:166::-;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;16714:15:1::1;::::0;:50:::1;::::0;-1:-1:-1;;;16714:50:1;;::::1;::::0;::::1;17118:25:2::0;;;-1:-1:-1;;;;;17179:32:2;;;17159:18;;;17152:60;16714:15:1;;::::1;::::0;:34:::1;::::0;17091:18:2;;16714:50:1::1;16944:274:2::0;3347:85:1;3386:13;3418:7;3411:14;;;;;:::i;20704:184::-;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;20790:20:1;::::1;;::::0;;;:13:::1;:20;::::0;;;;;::::1;;20789:21;20781:58;;;::::0;-1:-1:-1;;;20781:58:1;;14673:2:2;20781:58:1::1;::::0;::::1;14655:21:2::0;14712:2;14692:18;;;14685:30;14751:26;14731:18;;;14724:54;14795:18;;20781:58:1::1;14471:348:2::0;20781:58:1::1;-1:-1:-1::0;;;;;20849:20:1;;;::::1;;::::0;;;:13:::1;:20;::::0;;;;:32;;-1:-1:-1;;20849:32:1::1;::::0;::::1;;::::0;;;::::1;::::0;;20704:184::o;4488:417::-;168:10:0;4589:4:1;4636:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;4636:34:1;;;;;;;;;;4701:35;;;;4680:120;;;;-1:-1:-1;;;4680:120:1;;15026:2:2;4680:120:1;;;15008:21:2;15065:2;15045:18;;;15038:30;15104:34;15084:18;;;15077:62;-1:-1:-1;;;15155:18:2;;;15148:36;15201:19;;4680:120:1;14824:402:2;4680:120:1;4810:67;168:10:0;4833:7:1;4842:34;4861:15;4842:16;:34;:::i;4810:67::-;-1:-1:-1;4894:4:1;;4488:417;-1:-1:-1;;;4488:417:1:o;19047:138::-;19137:15;;:41;;-1:-1:-1;;;19137:41:1;;-1:-1:-1;;;;;6973:32:2;;;19137:41:1;;;6955:51:2;19111:7:1;;19137:15;;:32;;6928:18:2;;19137:41:1;6809:203:2;6474:110:1;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;6550:15:1::1;:27:::0;6474:110::o;18227:178::-;18351:15;;:47;;-1:-1:-1;;;18351:47:1;;-1:-1:-1;;;;;6973:32:2;;;18351:47:1;;;6955:51:2;18321:7:1;;18351:15;;:38;;6928:18:2;;18351:47:1;6809:203:2;4911:208:1;5029:4;5049:42;168:10:0;5073:9:1;5084:6;5049:9;:42::i;19912:84::-;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;19975:8:1::1;:14:::0;19912:84::o;18411:172::-;18532:15;;:44;;-1:-1:-1;;;18532:44:1;;-1:-1:-1;;;;;6973:32:2;;;18532:44:1;;;6955:51:2;18502:7:1;;18532:15;;:35;;6928:18:2;;18532:44:1;6809:203:2;17284:658:1;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;17542:19:1::1;:39:::0;;;17591:18:::1;:37:::0;;;17638:17:::1;:35:::0;;;17683:20:::1;:41:::0;;;17734:19:::1;:39:::0;;;17783:18:::1;:37:::0;;;17658:15;17857:48:::1;17612:16:::0;17564:17;17857:48:::1;:::i;:::-;:78;;;;:::i;:::-;17831:11;:104:::0;-1:-1:-1;;;;;;17284:658:1:o;16144:325::-;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;16249:28:1;::::1;;::::0;;;:19:::1;:28;::::0;;;;;::::1;;:40;;::::0;::::1;;;;16228:136;;;::::0;-1:-1:-1;;;16228:136:1;;10809:2:2;16228:136:1::1;::::0;::::1;10791:21:2::0;10848:2;10828:18;;;10821:30;10887:34;10867:18;;;10860:62;-1:-1:-1;;;10938:18:2;;;10931:47;10995:19;;16228:136:1::1;10607:413:2::0;16228:136:1::1;-1:-1:-1::0;;;;;16374:28:1;::::1;;::::0;;;:19:::1;:28;::::0;;;;;;;;:39;;-1:-1:-1;;16374:39:1::1;::::0;::::1;;::::0;;::::1;::::0;;;16428:34;;9071:41:2;;;16428:34:1::1;::::0;9044:18:2;16428:34:1::1;;;;;;;16144:325:::0;;:::o;20894:179::-;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;20974:7:1::1;20969:98;20991:6;:13;20987:1;:17;;;20969:98;;;21052:4;21025:13;:24;21039:6;21046:1;21039:9;;;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;;;21025:24:1::1;::::0;;;::::1;::::0;;;;;;-1:-1:-1;21025:24:1;:31;;-1:-1:-1;;21025:31:1::1;::::0;::::1;;::::0;;;::::1;::::0;;21006:3;::::1;::::0;::::1;:::i;:::-;;;;20969:98;;19330:130:::0;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;19397:10:1::1;:21:::0;;;::::1;;::::0;::::1;-1:-1:-1::0;;19397:21:1;;::::1;;::::0;;19433:20:::1;::::0;::::1;::::0;::::1;::::0;19410:8;9096:14:2;9089:22;9071:41;;9059:2;9044:18;;8931:187;19433:20:1::1;;;;;;;;19330:130:::0;:::o;16954:177::-;17076:15;;:48;;-1:-1:-1;;;17076:48:1;;-1:-1:-1;;;;;6973:32:2;;;17076:48:1;;;6955:51:2;17049:4:1;;17076:15;;:39;;6928:18:2;;17076:48:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;20370:160::-;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;20479:33:1;;;::::1;;::::0;;;:24:::1;:33;::::0;;;;:44;;-1:-1:-1;;20479:44:1::1;::::0;::::1;;::::0;;;::::1;::::0;;20370:160::o;20002:132::-;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;20087:29:1;;;::::1;;::::0;;;:20:::1;:29;::::0;;;;:40;;-1:-1:-1;;20087:40:1::1;::::0;::::1;;::::0;;;::::1;::::0;;20002:132::o;19191:133::-;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;19259:11:1::1;:22:::0;;;::::1;;;;-1:-1:-1::0;;19259:22:1;;::::1;;::::0;;19296:21:::1;::::0;::::1;::::0;::::1;::::0;19273:8;9096:14:2;9089:22;9071:41;;9059:2;9044:18;;8931:187;19466:154:1;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;19541:18:1::1;:29:::0;;;::::1;;::::0;::::1;-1:-1:-1::0;;19541:29:1;;::::1;;::::0;;19585:28:::1;::::0;::::1;::::0;::::1;::::0;19562:8;9096:14:2;9089:22;9071:41;;9059:2;9044:18;;8931:187;17137:141:1;759:7:0;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;17235:16:1::1;:36:::0;;-1:-1:-1;;;;;17235:36:1;;::::1;;;-1:-1:-1::0;;;;;;17235:36:1;;::::1;::::0;;;::::1;::::0;;17137:141::o;1595:232:0:-;759:7;785:6;-1:-1:-1;;;;;785:6:0;168:10;925:23;917:68;;;;-1:-1:-1;;;917:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;1696:22:0;::::1;1675:107;;;::::0;-1:-1:-1;;;1675:107:0;;11934:2:2;1675:107:0::1;::::0;::::1;11916:21:2::0;11973:2;11953:18;;;11946:30;12012:34;11992:18;;;11985:62;-1:-1:-1;;;12063:18:2;;;12056:36;12109:19;;1675:107:0::1;11732:402:2::0;1675:107:0::1;1792:28;1811:8;1792:18;:28::i;18048:173:1:-:0;18093:18;;;;;;;18085:65;;;;-1:-1:-1;;;18085:65:1;;16155:2:2;18085:65:1;;;16137:21:2;16194:2;16174:18;;;16167:30;16233:34;16213:18;;;16206:62;-1:-1:-1;;;16284:18:2;;;16277:32;16326:19;;18085:65:1;15953:398:2;18085:65:1;18160:15;;-1:-1:-1;;;;;18160:15:1;:31;168:10:0;18200:12:1;89:96:0;11726:362:1;-1:-1:-1;;;;;11848:19:1;;11840:69;;;;-1:-1:-1;;;11840:69:1;;16558:2:2;11840:69:1;;;16540:21:2;16597:2;16577:18;;;16570:30;16636:34;16616:18;;;16609:62;-1:-1:-1;;;16687:18:2;;;16680:35;16732:19;;11840:69:1;16356:401:2;11840:69:1;-1:-1:-1;;;;;11927:21:1;;11919:69;;;;-1:-1:-1;;;11919:69:1;;13861:2:2;11919:69:1;;;13843:21:2;13900:2;13880:18;;;13873:30;13939:34;13919:18;;;13912:62;-1:-1:-1;;;13990:18:2;;;13983:33;14033:19;;11919:69:1;13659:399:2;11919:69:1;-1:-1:-1;;;;;11998:18:1;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;12049:32;;16908:25:2;;;12049:32:1;;16881:18:2;12049:32:1;;;;;;;11726:362;;;:::o;6590:4493::-;6748:15;6730;;:33;:70;;;-1:-1:-1;759:7:0;785:6;-1:-1:-1;;;;;6783:17:1;;;785:6:0;;6783:17:1;6730:70;:110;;;-1:-1:-1;759:7:0;785:6;-1:-1:-1;;;;;6820:20:1;;;785:6:0;;6820:20:1;6730:110;:148;;;-1:-1:-1;;;;;;6860:18:1;;;;;;:10;:18;;;;;;;;6730:148;:189;;;-1:-1:-1;;;;;;6898:21:1;;;;;;:10;:21;;;;;;;;6730:189;6709:268;;;;-1:-1:-1;;;6709:268:1;;15794:2:2;6709:268:1;;;15776:21:2;;;15813:18;;;15806:30;15872:34;15852:18;;;15845:62;15924:18;;6709:268:1;15592:356:2;6709:268:1;-1:-1:-1;;;;;6997:21:1;;;;;;:13;:21;;;;;;;;6996:22;6988:64;;;;-1:-1:-1;;;6988:64:1;;13503:2:2;6988:64:1;;;13485:21:2;13542:2;13522:18;;;13515:30;13581:31;13561:18;;;13554:59;13630:18;;6988:64:1;13301:353:2;6988:64:1;-1:-1:-1;;;;;7071:24:1;;;;;;:13;:24;;;;;;;;7070:25;7062:70;;;;-1:-1:-1;;;7062:70:1;;11573:2:2;7062:70:1;;;11555:21:2;;;11592:18;;;11585:30;11651:34;11631:18;;;11624:62;11703:18;;7062:70:1;11371:356:2;7062:70:1;-1:-1:-1;;;;;7151:20:1;;7143:71;;;;-1:-1:-1;;;7143:71:1;;;;;;;:::i;:::-;-1:-1:-1;;;;;7245:23:1;;7224:106;;;;-1:-1:-1;;;7224:106:1;;;;;;;:::i;:::-;7341:20;7393:5;7381:8;;7365:13;3605:12;;;3518:106;7365:13;:24;;;;:::i;:::-;7364:34;;;;:::i;:::-;7341:57;;7408:18;7462:5;7446:12;;7430:13;3605:12;;;3518:106;7430:13;:28;;;;:::i;:::-;7429:38;;;;:::i;:::-;7408:59;;7508:12;7498:6;:22;;:54;;;-1:-1:-1;;;;;;7524:28:1;;;;;;:20;:28;;;;;;;;7498:54;7477:118;;;;-1:-1:-1;;;7477:118:1;;11227:2:2;7477:118:1;;;11209:21:2;11266:2;11246:18;;;11239:30;-1:-1:-1;;;11285:18:2;;;11278:47;11342:18;;7477:118:1;11025:341:2;7477:118:1;759:7:0;785:6;-1:-1:-1;;;;;7623:17:1;;;785:6:0;;7623:17:1;;;;:59;;-1:-1:-1;;;;;;7656:26:1;;7677:4;7656:26;;7623:59;:101;;;;-1:-1:-1;7719:4:1;;-1:-1:-1;;;;;7698:26:1;;;7719:4;;7698:26;;7623:101;:143;;;;-1:-1:-1;7753:13:1;;-1:-1:-1;;;;;7740:26:1;;;7753:13;;7740:26;;7623:143;7606:392;;;-1:-1:-1;;;;;3774:18:1;;7791:22;3774:18;;;:9;:18;;;;;;;;;7875:24;:35;;;;;;;;;;:98;;-1:-1:-1;7962:10:1;7935:23;7952:6;7935:14;:23;:::i;:::-;:37;;7875:98;7850:137;;;;;;7777:221;7606:392;-1:-1:-1;;;;;8032:17:1;;8008:21;8032:17;;;:9;:17;;;;;;8080:23;;;;8059:109;;;;-1:-1:-1;;;8059:109:1;;;;;;;:::i;:::-;8228:4;8179:28;3774:18;;;:9;:18;;;;;;8347;;8393:11;;8276:21;;8323:42;;;;8393:11;;;;;:34;;;;;8420:7;8393:34;:59;;;;-1:-1:-1;8444:8:1;;;;8443:9;8393:59;:109;;;;-1:-1:-1;8486:15:1;;-1:-1:-1;;;;;8468:34:1;;;8486:15;;8468:34;;8393:109;:142;;;;-1:-1:-1;759:7:0;785:6;-1:-1:-1;;;;;8518:17:1;;;785:6:0;;8518:17:1;;8393:142;:178;;;;-1:-1:-1;759:7:0;785:6;-1:-1:-1;;;;;8551:20:1;;;785:6:0;;8551:20:1;;8393:178;8376:544;;;8596:8;:15;;-1:-1:-1;;8596:15:1;8607:4;8596:15;;;8631:12;;8596:15;8631:12;8630:13;:58;;;;;8670:18;;8647:20;:41;8630:58;8626:138;;;8731:18;;8708:41;;8626:138;8777:57;8790:20;8812:21;8777:12;:57::i;:::-;8864:15;8849:12;:30;8893:8;:16;;-1:-1:-1;;8893:16:1;;;8376:544;8997:13;;8930:12;;-1:-1:-1;;;;;8979:32:1;;;8997:13;;8979:32;:89;;;;-1:-1:-1;9052:15:1;;-1:-1:-1;;;;;9031:37:1;;;9052:15;;9031:37;;8979:89;8978:198;;;-1:-1:-1;9107:13:1;;-1:-1:-1;;;;;9086:35:1;;;9107:13;;9086:35;:89;;;;-1:-1:-1;9159:15:1;;-1:-1:-1;;;;;9141:34:1;;;9159:15;;9141:34;;9086:89;8961:265;;;-1:-1:-1;9211:4:1;8961:265;-1:-1:-1;;;;;9240:27:1;;;;;;:19;:27;;;;;;;;;:61;;-1:-1:-1;;;;;;9271:30:1;;;;;;:19;:30;;;;;;;;9240:61;9236:107;;;-1:-1:-1;9327:5:1;9236:107;9357:8;;;;;:23;;-1:-1:-1;9370:10:1;;;;;;;9369:11;9357:23;9353:69;;;-1:-1:-1;9406:5:1;9353:69;9436:7;9432:1440;;;9504:13;;-1:-1:-1;;;;;9494:23:1;;;9504:13;;9494:23;9490:585;;;9654:17;;9613:18;;9571:19;;:60;;;;:::i;:::-;:100;;;;:::i;:::-;9537:11;:134;;;9749:19;;9740:28;;:6;:28;:::i;:::-;9739:64;;;;:::i;:::-;9690:26;:113;9921:11;;9879:18;;9870:27;;:6;:27;:::i;:::-;9869:63;;;;:::i;:::-;9821:25;:111;10049:11;;10008:17;;9999:26;;:6;:26;:::i;:::-;9998:62;;;;:::i;:::-;9950:25;:110;9490:585;10138:13;;-1:-1:-1;;;;;10125:26:1;;;10138:13;;10125:26;10121:594;;;10290:18;;10248:19;;10205:20;;:62;;;;:::i;:::-;:103;;;;:::i;:::-;10171:11;:137;;;10386:20;;10377:29;;:6;:29;:::i;:::-;10376:65;;;;:::i;:::-;10327:26;:114;10560:11;;10517:19;;10508:28;;:6;:28;:::i;:::-;10507:64;;;;:::i;:::-;10459:25;:112;10689:11;;10647:18;;10638:27;;:6;:27;:::i;:::-;10637:63;;;;:::i;:::-;10589:25;:111;10121:594;10729:12;10769:5;10754:11;;10745:6;:20;;;;:::i;:::-;10744:30;;;;:::i;:::-;10729:45;-1:-1:-1;10788:14:1;10729:45;10788:14;;:::i;:::-;;;10816:45;10833:6;10849:4;10856;10816:16;:45::i;:::-;9445:1427;9432:1440;10882:43;10899:6;10907:9;10918:6;10882:16;:43::i;:::-;10936:15;;-1:-1:-1;;;;;10936:15:1;:26;10971:6;10980:17;10971:6;-1:-1:-1;;;;;3774:18:1;3744:7;3774:18;;;:9;:18;;;;;;;3630:169;10980:17;10936:62;;-1:-1:-1;;;;;;10936:62:1;;;;;;;-1:-1:-1;;;;;7449:32:2;;;10936:62:1;;;7431:51:2;7498:18;;;7491:34;7404:18;;10936:62:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;11008:15:1;;-1:-1:-1;;;;;11008:15:1;;-1:-1:-1;11008:26:1;;-1:-1:-1;11043:9:1;11055:20;11043:9;-1:-1:-1;;;;;3774:18:1;3744:7;3774:18;;;:9;:18;;;;;;;3630:169;11055:20;11008:68;;-1:-1:-1;;;;;;11008:68:1;;;;;;;-1:-1:-1;;;;;7449:32:2;;;11008:68:1;;;7431:51:2;7498:18;;;7491:34;7404:18;;11008:68:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6699:4384;;;;;;;6590:4493;;;:::o;13154:2590::-;13240:1;13230:6;:11;13226:48;;13154:2590;;:::o;13226:48::-;13284:23;13391:25;;13351;;13310:26;;:66;;;;:::i;:::-;:106;;;;:::i;:::-;13585:16;;13284:132;;-1:-1:-1;13536:27:1;;13585:16;;;-1:-1:-1;;;;;13585:16:1;13577:39;13573:179;;13726:15;13680:26;;13671:6;:35;;;;:::i;:::-;13670:71;;;;:::i;:::-;13632:109;;13573:179;13762:26;13834:1;13802:15;;;;;;;;;-1:-1:-1;;;;;13802:15:1;-1:-1:-1;;;;;13802:27:1;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:33;13798:171;;;13943:15;13898:25;;13889:6;:34;;;;:::i;:::-;13888:70;;;;:::i;:::-;13851:107;;13798:171;13979:26;14062:18;14008:40;14029:19;14008:6;:40;:::i;:::-;:72;;;;:::i;:::-;13979:101;-1:-1:-1;14090:27:1;14120:22;14141:1;13979:101;14120:22;:::i;:::-;14090:52;-1:-1:-1;14152:26:1;14181:40;14090:52;14181:18;:40;:::i;:::-;14152:69;-1:-1:-1;14231:23:1;14324:19;14257:52;14291:18;14257:19;:52;:::i;:::-;:86;;;;:::i;:::-;14231:112;-1:-1:-1;14378:21:1;14409:36;14231:112;14409:19;:36::i;:::-;14455:21;14533:6;14480:37;14504:13;14480:21;:37;:::i;:::-;14479:60;;;;:::i;:::-;14455:84;-1:-1:-1;14550:24:1;14629:15;14578:35;14594:19;14455:84;14578:35;:::i;:::-;14577:67;;;;:::i;:::-;14550:94;-1:-1:-1;14654:23:1;14731:15;14681:34;14697:18;14681:13;:34;:::i;:::-;14680:66;;;;:::i;:::-;14654:92;-1:-1:-1;14756:23:1;14654:92;14782:44;14810:16;14782:13;:44;:::i;:::-;:74;;;;:::i;:::-;14756:100;-1:-1:-1;14906:20:1;;14902:172;;14961:16;;:50;;14943:12;;14961:16;;;-1:-1:-1;;;;;14961:16:1;;14990;;14943:12;14961:50;14943:12;14961:50;14990:16;14961;:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14942:69;;;15033:7;15025:38;;;;-1:-1:-1;;;15025:38:1;;12341:2:2;15025:38:1;;;12323:21:2;12380:2;12360:18;;;12353:30;-1:-1:-1;;;12399:18:2;;;12392:48;12457:18;;15025:38:1;12139:342:2;15025:38:1;14928:146;14902:172;15109:49;15122:18;15142:15;15109:12;:49::i;:::-;15173:123;;;18663:25:2;;;18719:2;18704:18;;18697:34;;;18747:18;;;18740:34;;;15173:123:1;;18651:2:2;18636:18;15173:123:1;;;;;;;15353:19;;15349:270;;15415:15;;15407:87;;15389:12;;-1:-1:-1;;;;;15415:15:1;;15461;;15389:12;15407:87;15389:12;15407:87;15461:15;15415;15407:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15388:106;;;15512:7;15508:101;;;15544:50;;;18382:25:2;;;18438:2;18423:18;;18416:34;;;15544:50:1;;18355:18:2;15544:50:1;;;;;;;15508:101;15374:245;15349:270;-1:-1:-1;;15658:1:1;15629:26;:30;;;15669:25;:29;;;15708:25;:29;-1:-1:-1;;;;;;;;;;;;13154:2590:1:o;1981:187:0:-;2054:16;2073:6;;-1:-1:-1;;;;;2089:17:0;;;-1:-1:-1;;;;;;2089:17:0;;;;;;2121:40;;2073:6;;;;;;;2121:40;;2054:16;2121:40;2044:124;1981:187;:::o;11089:631:1:-;-1:-1:-1;;;;;11222:20:1;;11214:71;;;;-1:-1:-1;;;11214:71:1;;;;;;;:::i;:::-;-1:-1:-1;;;;;11316:23:1;;11295:106;;;;-1:-1:-1;;;11295:106:1;;;;;;;:::i;:::-;-1:-1:-1;;;;;11435:17:1;;11411:21;11435:17;;;:9;:17;;;;;;11483:23;;;;11462:109;;;;-1:-1:-1;;;11462:109:1;;;;;;;:::i;:::-;11601:22;11617:6;11601:13;:22;:::i;:::-;-1:-1:-1;;;;;11581:17:1;;;;;;;:9;:17;;;;;;:42;;;;11633:20;;;;;;;;:30;;11657:6;;11581:17;11633:30;;11657:6;;11633:30;:::i;:::-;;;;;;;;11695:9;-1:-1:-1;;;;;11678:35:1;11687:6;-1:-1:-1;;;;;11678:35:1;;11706:6;11678:35;;;;16908:25:2;;16896:2;16881:18;;16762:177;11678:35:1;;;;;;;;11204:516;11089:631;;;:::o;12094:478::-;12181:16;;;12195:1;12181:16;;;;;;;;12157:21;;12181:16;;;;;;;;;;-1:-1:-1;12181:16:1;12157:40;;12225:4;12207;12212:1;12207:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;12207:23:1;;;:7;;;;;;;;;;:23;;;;12250:15;;:22;;;-1:-1:-1;;;12250:22:1;;;;:15;;;;;:20;;:22;;;;;12207:7;;12250:22;;;;;:15;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12240:4;12245:1;12240:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;12240:32:1;;;:7;;;;;;;;;:32;12314:15;;12282:57;;12299:4;;12314:15;12332:6;12282:8;:57::i;:::-;12349:15;;:216;;-1:-1:-1;;;12349:216:1;;-1:-1:-1;;;;;12349:15:1;;;;:66;;:216;;12429:6;;12349:15;;12495:4;;12521;;12540:15;;12349:216;;;:::i;12578:383::-;12682:15;;12650:57;;12667:4;;-1:-1:-1;;;;;12682:15:1;12700:6;12650:8;:57::i;:::-;12717:15;;:237;;-1:-1:-1;;;12717:237:1;;12785:4;12717:237;;;8166:34:2;;;8216:18;;;8209:34;;;12717:15:1;8259:18:2;;;8252:34;;;8302:18;;;8295:34;8345:19;;;8338:44;12929:15:1;8398:19:2;;;8391:35;-1:-1:-1;;;;;12717:15:1;;;;:31;;12756:6;;8100:19:2;;12717:237:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;12578:383;;:::o;14:134:2:-;82:20;;111:31;82:20;111:31;:::i;:::-;14:134;;;:::o;153:247::-;212:6;265:2;253:9;244:7;240:23;236:32;233:52;;;281:1;278;271:12;233:52;320:9;307:23;339:31;364:5;339:31;:::i;:::-;389:5;153:247;-1:-1:-1;;;153:247:2:o;405:251::-;475:6;528:2;516:9;507:7;503:23;499:32;496:52;;;544:1;541;534:12;496:52;576:9;570:16;595:31;620:5;595:31;:::i;921:388::-;989:6;997;1050:2;1038:9;1029:7;1025:23;1021:32;1018:52;;;1066:1;1063;1056:12;1018:52;1105:9;1092:23;1124:31;1149:5;1124:31;:::i;:::-;1174:5;-1:-1:-1;1231:2:2;1216:18;;1203:32;1244:33;1203:32;1244:33;:::i;:::-;1296:7;1286:17;;;921:388;;;;;:::o;1314:456::-;1391:6;1399;1407;1460:2;1448:9;1439:7;1435:23;1431:32;1428:52;;;1476:1;1473;1466:12;1428:52;1515:9;1502:23;1534:31;1559:5;1534:31;:::i;:::-;1584:5;-1:-1:-1;1641:2:2;1626:18;;1613:32;1654:33;1613:32;1654:33;:::i;:::-;1314:456;;1706:7;;-1:-1:-1;;;1760:2:2;1745:18;;;;1732:32;;1314:456::o;1775:382::-;1840:6;1848;1901:2;1889:9;1880:7;1876:23;1872:32;1869:52;;;1917:1;1914;1907:12;1869:52;1956:9;1943:23;1975:31;2000:5;1975:31;:::i;:::-;2025:5;-1:-1:-1;2082:2:2;2067:18;;2054:32;2095:30;2054:32;2095:30;:::i;2162:315::-;2230:6;2238;2291:2;2279:9;2270:7;2266:23;2262:32;2259:52;;;2307:1;2304;2297:12;2259:52;2346:9;2333:23;2365:31;2390:5;2365:31;:::i;:::-;2415:5;2467:2;2452:18;;;;2439:32;;-1:-1:-1;;;2162:315:2:o;2482:497::-;2588:6;2596;2604;2612;2620;2673:3;2661:9;2652:7;2648:23;2644:33;2641:53;;;2690:1;2687;2680:12;2641:53;2722:9;2716:16;2741:31;2766:5;2741:31;:::i;:::-;2836:2;2821:18;;2815:25;2880:2;2865:18;;2859:25;2924:2;2909:18;;2903:25;2968:3;2953:19;;;2947:26;2791:5;;2815:25;;-1:-1:-1;2859:25:2;2903;-1:-1:-1;2947:26:2;;-1:-1:-1;2482:497:2;-1:-1:-1;;;2482:497:2:o;2984:1132::-;3068:6;3099:2;3142;3130:9;3121:7;3117:23;3113:32;3110:52;;;3158:1;3155;3148:12;3110:52;3198:9;3185:23;3227:18;3268:2;3260:6;3257:14;3254:34;;;3284:1;3281;3274:12;3254:34;3322:6;3311:9;3307:22;3297:32;;3367:7;3360:4;3356:2;3352:13;3348:27;3338:55;;3389:1;3386;3379:12;3338:55;3425:2;3412:16;3447:2;3443;3440:10;3437:36;;;3453:18;;:::i;:::-;3499:2;3496:1;3492:10;3531:2;3525:9;3594:2;3590:7;3585:2;3581;3577:11;3573:25;3565:6;3561:38;3649:6;3637:10;3634:22;3629:2;3617:10;3614:18;3611:46;3608:72;;;3660:18;;:::i;:::-;3696:2;3689:22;3746:18;;;3780:15;;;;-1:-1:-1;3815:11:2;;;3845;;;3841:20;;3838:33;-1:-1:-1;3835:53:2;;;3884:1;3881;3874:12;3835:53;3906:1;3897:10;;3916:169;3930:2;3927:1;3924:9;3916:169;;;3987:23;4006:3;3987:23;:::i;:::-;3975:36;;3948:1;3941:9;;;;;4031:12;;;;4063;;3916:169;;;-1:-1:-1;4104:6:2;2984:1132;-1:-1:-1;;;;;;;;2984:1132:2:o;4121:241::-;4177:6;4230:2;4218:9;4209:7;4205:23;4201:32;4198:52;;;4246:1;4243;4236:12;4198:52;4285:9;4272:23;4304:28;4326:5;4304:28;:::i;4367:245::-;4434:6;4487:2;4475:9;4466:7;4462:23;4458:32;4455:52;;;4503:1;4500;4493:12;4455:52;4535:9;4529:16;4554:28;4576:5;4554:28;:::i;4617:444::-;4688:6;4696;4704;4757:2;4745:9;4736:7;4732:23;4728:32;4725:52;;;4773:1;4770;4763:12;4725:52;4812:9;4799:23;4831:28;4853:5;4831:28;:::i;:::-;4878:5;-1:-1:-1;4930:2:2;4915:18;;4902:32;;-1:-1:-1;4986:2:2;4971:18;;4958:32;4999:30;4958:32;4999:30;:::i;:::-;5048:7;5038:17;;;4617:444;;;;;:::o;5066:180::-;5125:6;5178:2;5166:9;5157:7;5153:23;5149:32;5146:52;;;5194:1;5191;5184:12;5146:52;-1:-1:-1;5217:23:2;;5066:180;-1:-1:-1;5066:180:2:o;5251:184::-;5321:6;5374:2;5362:9;5353:7;5349:23;5345:32;5342:52;;;5390:1;5387;5380:12;5342:52;-1:-1:-1;5413:16:2;;5251:184;-1:-1:-1;5251:184:2:o;5440:315::-;5508:6;5516;5569:2;5557:9;5548:7;5544:23;5540:32;5537:52;;;5585:1;5582;5575:12;5537:52;5621:9;5608:23;5598:33;;5681:2;5670:9;5666:18;5653:32;5694:31;5719:5;5694:31;:::i;5760:306::-;5848:6;5856;5864;5917:2;5905:9;5896:7;5892:23;5888:32;5885:52;;;5933:1;5930;5923:12;5885:52;5962:9;5956:16;5946:26;;6012:2;6001:9;5997:18;5991:25;5981:35;;6056:2;6045:9;6041:18;6035:25;6025:35;;5760:306;;;;;:::o;6071:523::-;6175:6;6183;6191;6199;6207;6215;6268:3;6256:9;6247:7;6243:23;6239:33;6236:53;;;6285:1;6282;6275:12;6236:53;-1:-1:-1;;6308:23:2;;;6378:2;6363:18;;6350:32;;-1:-1:-1;6429:2:2;6414:18;;6401:32;;6480:2;6465:18;;6452:32;;-1:-1:-1;6531:3:2;6516:19;;6503:33;;-1:-1:-1;6583:3:2;6568:19;6555:33;;-1:-1:-1;6071:523:2;-1:-1:-1;6071:523:2:o;9598:597::-;9710:4;9739:2;9768;9757:9;9750:21;9800:6;9794:13;9843:6;9838:2;9827:9;9823:18;9816:34;9868:1;9878:140;9892:6;9889:1;9886:13;9878:140;;;9987:14;;;9983:23;;9977:30;9953:17;;;9972:2;9949:26;9942:66;9907:10;;9878:140;;;10036:6;10033:1;10030:13;10027:91;;;10106:1;10101:2;10092:6;10081:9;10077:22;10073:31;10066:42;10027:91;-1:-1:-1;10179:2:2;10158:15;-1:-1:-1;;10154:29:2;10139:45;;;;10186:2;10135:54;;9598:597;-1:-1:-1;;;9598:597:2:o;10200:402::-;10402:2;10384:21;;;10441:2;10421:18;;;10414:30;10480:34;10475:2;10460:18;;10453:62;-1:-1:-1;;;10546:2:2;10531:18;;10524:36;10592:3;10577:19;;10200:402::o;12486:400::-;12688:2;12670:21;;;12727:2;12707:18;;;12700:30;12766:34;12761:2;12746:18;;12739:62;-1:-1:-1;;;12832:2:2;12817:18;;12810:34;12876:3;12861:19;;12486:400::o;14063:403::-;14265:2;14247:21;;;14304:2;14284:18;;;14277:30;14343:34;14338:2;14323:18;;14316:62;-1:-1:-1;;;14409:2:2;14394:18;;14387:37;14456:3;14441:19;;14063:403::o;15231:356::-;15433:2;15415:21;;;15452:18;;;15445:30;15511:34;15506:2;15491:18;;15484:62;15578:2;15563:18;;15231:356::o;17223:980::-;17485:4;17533:3;17522:9;17518:19;17564:6;17553:9;17546:25;17590:2;17628:6;17623:2;17612:9;17608:18;17601:34;17671:3;17666:2;17655:9;17651:18;17644:31;17695:6;17730;17724:13;17761:6;17753;17746:22;17799:3;17788:9;17784:19;17777:26;;17838:2;17830:6;17826:15;17812:29;;17859:1;17869:195;17883:6;17880:1;17877:13;17869:195;;;17948:13;;-1:-1:-1;;;;;17944:39:2;17932:52;;18039:15;;;;18004:12;;;;17980:1;17898:9;17869:195;;;-1:-1:-1;;;;;;;18120:32:2;;;;18115:2;18100:18;;18093:60;-1:-1:-1;;;18184:3:2;18169:19;18162:35;18081:3;17223:980;-1:-1:-1;;;17223:980:2:o;18974:128::-;19014:3;19045:1;19041:6;19038:1;19035:13;19032:39;;;19051:18;;:::i;:::-;-1:-1:-1;19087:9:2;;18974:128::o;19107:217::-;19147:1;19173;19163:132;;19217:10;19212:3;19208:20;19205:1;19198:31;19252:4;19249:1;19242:15;19280:4;19277:1;19270:15;19163:132;-1:-1:-1;19309:9:2;;19107:217::o;19329:168::-;19369:7;19435:1;19431;19427:6;19423:14;19420:1;19417:21;19412:1;19405:9;19398:17;19394:45;19391:71;;;19442:18;;:::i;:::-;-1:-1:-1;19482:9:2;;19329:168::o;19502:125::-;19542:4;19570:1;19567;19564:8;19561:34;;;19575:18;;:::i;:::-;-1:-1:-1;19612:9:2;;19502:125::o;19632:380::-;19711:1;19707:12;;;;19754;;;19775:61;;19829:4;19821:6;19817:17;19807:27;;19775:61;19882:2;19874:6;19871:14;19851:18;19848:38;19845:161;;;19928:10;19923:3;19919:20;19916:1;19909:31;19963:4;19960:1;19953:15;19991:4;19988:1;19981:15;19845:161;;19632:380;;;:::o;20017:175::-;20054:3;20098:4;20091:5;20087:16;20127:4;20118:7;20115:17;20112:43;;;20135:18;;:::i;:::-;20184:1;20171:15;;20017:175;-1:-1:-1;;20017:175:2:o;20197:127::-;20258:10;20253:3;20249:20;20246:1;20239:31;20289:4;20286:1;20279:15;20313:4;20310:1;20303:15;20329:127;20390:10;20385:3;20381:20;20378:1;20371:31;20421:4;20418:1;20411:15;20445:4;20442:1;20435:15;20461:127;20522:10;20517:3;20513:20;20510:1;20503:31;20553:4;20550:1;20543:15;20577:4;20574:1;20567:15;20593:131;-1:-1:-1;;;;;20668:31:2;;20658:42;;20648:70;;20714:1;20711;20704:12;20729:118;20815:5;20808:13;20801:21;20794:5;20791:32;20781:60;;20837:1;20834;20827:12

Swarm Source

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