ETH Price: $3,456.01 (-0.89%)

Token

ApplePYE (APPLEPYE)
 

Overview

Max Total Supply

31,517,761.478755253983021605 APPLEPYE

Holders

157

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
64,788.481874236872428067 APPLEPYE

Value
$0.00
0xb1de99e4c808d5a01930b233b841f352ddc56d11
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:
APPLE

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
Yes with 999999 runs

Other Settings:
default evmVersion, MIT license
File 1 of 17 : Apple3.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/utils/Arrays.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "./interfaces/IPYESwapFactory.sol";
import "./interfaces/IPYESwapRouter.sol";


contract APPLE is AccessControl, ERC20 {
    using SafeMath for uint256;

    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
    bytes32 public constant FEE_SETTER_ROLE = keccak256("FEE_SETTER_ROLE");

    // staked struct	
    struct Staked {	
        uint256 amount;	
    }	
    address[] holders;	
    mapping (address => uint256) holderIndexes;	
    uint256 public totalStaked;

    // Fees
    // Add and remove fee types and destinations here as needed
    struct Fees {
        uint256 developmentFee;
        uint256 buybackFee;
        address developmentAddress;
    }

    // Transaction fee values
    // Add and remove fee value types here as needed
    struct FeeValues {
        uint256 transferAmount;
        uint256 development;
        uint256 buyback;
    }

    // Token details
    mapping (address => uint256) _balances;
    mapping (address => mapping (address => uint256)) private _allowances;
    mapping (address => Staked) public staked;

    // denylist and staking contract mappings	
    mapping (address => bool) isDenylisted; 	
    mapping (address => bool) isStakingContract; 
    
    // Allowed Callers of Snapshot()
    mapping (address => bool) public isSnapshotter;

    // Set total supply here
    uint256 private _tTotal;

    // Tracker for total burned amount
    uint256 private _bTotal;

    // auto set buyback to false. additional buyback params. blockPeriod acts as a time delay in the shouldAutoBuyback(). Last uint represents last block for buyback occurance.
    struct Settings {
        bool autoBuybackEnabled;
        uint256 autoBuybackCap;
        uint256 autoBuybackAccumulator;
        uint256 autoBuybackAmount;
        uint256 autoBuybackBlockPeriod;
        uint256 autoBuybackBlockLast;
        uint256 minimumBuyBackThreshold;
    }

    // Users states
    mapping (address => bool) private _isExcludedFromFee;

    // Outside Swap Pairs
    mapping (address => bool) private _includeSwapFee;


    // Pair Details
    mapping (uint256 => address) private pairs;
    mapping (uint256 => address) private tokens;
    uint256 private pairsLength;
    mapping (address => bool) public _isPairAddress;


    // Set the name, symbol, and decimals here
    string constant _name = "ApplePYE";
    string constant _symbol = "APPLEPYE";
    uint8 constant _decimals = 18;

    Fees private _defaultFees;
    Fees private _previousFees;
    Fees private _emptyFees;
    Fees public _buyFees;
    Fees public _sellFees;
    Fees private _outsideBuyFees;
    Fees private _outsideSellFees;

    Settings public _buyback;

    IPYESwapRouter public pyeSwapRouter;
    address public pyeSwapPair;
    address public WETH;
    address public constant _burnAddress = 0x000000000000000000000000000000000000dEaD;

    bool public swapEnabled = true;
    bool inSwap;

    modifier swapping() { inSwap = true; _; inSwap = false; }
    modifier onlyExchange() {
        bool isPair = false;
        for(uint i = 0; i < pairsLength; i++) {
            if(pairs[i] == msg.sender) isPair = true;
        }
        require(
            msg.sender == address(pyeSwapRouter)
            || isPair
            , "PYE: NOT_ALLOWED"
        );
        _;
    }


    /// @notice The EIP-712 typehash for the contract's domain
    bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");

    // Edit the constructor in order to declare default fees on deployment
    constructor (address _router, address _development, uint256 _developmentFeeBuy, uint256 _buybackFeeBuy, uint256 _developmentFeeSell, uint256 _buybackFeeSell) ERC20("","") {
        _setupRole(MINTER_ROLE, msg.sender);
        _setupRole(BURNER_ROLE, msg.sender);
        _setupRole(FEE_SETTER_ROLE, msg.sender);
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);

        pyeSwapRouter = IPYESwapRouter(_router);
        WETH = pyeSwapRouter.WETH();
        pyeSwapPair = IPYESwapFactory(pyeSwapRouter.factory())
        .createPair(address(this), WETH, true, address(this));

        tokens[pairsLength] = WETH;
        pairs[pairsLength] = pyeSwapPair;
        pairsLength += 1;
        _isPairAddress[pyeSwapPair] = true;

        _isExcludedFromFee[_msgSender()] = true;
        _isExcludedFromFee[pyeSwapPair] = true;
        _isExcludedFromFee[address(this)] = true;
        _isExcludedFromFee[_burnAddress] = true;

        isSnapshotter[msg.sender] = true;

        // This should match the struct Fee
        _defaultFees = Fees(
            _developmentFeeBuy,
            _buybackFeeBuy,
            _development
        );

        _buyFees = Fees(
            _developmentFeeBuy,
            _buybackFeeBuy,
            _development
        );

        _sellFees = Fees(
            _developmentFeeSell,
            _buybackFeeSell,
            _development
        );

        _outsideBuyFees = Fees(
            _developmentFeeBuy.add(_buybackFeeBuy),
            0,
            _development
        );

        _outsideSellFees = Fees(
            _developmentFeeSell.add(_buybackFeeSell),
            0,
            _development
        );
    }

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

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

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

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

    function totalBurned() public view returns (uint256) {
        return _balances[_burnAddress].add(_bTotal);
    }

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

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

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

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

    function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

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

    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual override returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    function excludeFromFee(address account) public {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        _isExcludedFromFee[account] = true;
    }

    function includeInFee(address account) public {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        _isExcludedFromFee[account] = false;
    }

    function addOutsideSwapPair(address account) public {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        _includeSwapFee[account] = true;
    }

    function removeOutsideSwapPair(address account) public {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        _includeSwapFee[account] = false;
    }

    // Functions to update fees and addresses 

    function setBuyFees(uint256 _developmentFee, uint256 _buybackFee) external {
        require(hasRole(FEE_SETTER_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        require(_developmentFee.add(_buybackFee) <= 2500, "Fees exceed max limit");
        _defaultFees.developmentFee = _developmentFee;
        _defaultFees.buybackFee = _buybackFee;

        _buyFees.developmentFee = _developmentFee;
        _buyFees.buybackFee = _buybackFee;

        _outsideBuyFees.developmentFee = _developmentFee.add(_buybackFee);
    }

    function setSellFees(uint256 _developmentFee, uint256 _buybackFee) external {
        require(hasRole(FEE_SETTER_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        require(_developmentFee.add(_buybackFee) <= 2500, "Fees exceed max limit");
        _sellFees.developmentFee = _developmentFee;
        _sellFees.buybackFee = _buybackFee;

        _outsideSellFees.developmentFee = _developmentFee.add(_buybackFee);
    }

    function setdevelopmentAddress(address _development) external {
        require(hasRole(FEE_SETTER_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        require(_development != address(0), "PYE: Address Zero is not allowed");
        _defaultFees.developmentAddress = _development;
        _buyFees.developmentAddress = _development;
        _sellFees.developmentAddress = _development;
        _outsideBuyFees.developmentAddress = _development;
        _outsideSellFees.developmentAddress = _development;
    }

    function updateRouterAndPair(address _router, address _pair) public {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        _isExcludedFromFee[pyeSwapPair] = false;
        pyeSwapRouter = IPYESwapRouter(_router);
        pyeSwapPair = _pair;
        WETH = pyeSwapRouter.WETH();

        _isPairAddress[pyeSwapPair] = true;
        _isExcludedFromFee[pyeSwapPair] = true;

        pairs[0] = pyeSwapPair;
        tokens[0] = WETH;
    }

    //to receive ETH from pyeRouter when swapping
    receive() external payable {}

    function _getValues(uint256 tAmount) private view returns (FeeValues memory) {
        FeeValues memory values = FeeValues(
            0,
            calculateFee(tAmount, _defaultFees.developmentFee),
            calculateFee(tAmount, _defaultFees.buybackFee)
        );

        values.transferAmount = tAmount.sub(values.development).sub(values.buyback);
        return values;
    }

    function calculateFee(uint256 _amount, uint256 _fee) private pure returns (uint256) {
        if(_fee == 0) return 0;
        return _amount.mul(_fee).div(
            10**4
        );
    }

    function removeAllFee() private {
        _previousFees = _defaultFees;
        _defaultFees = _emptyFees;
    }

    function setSellFee() private {
        _defaultFees = _sellFees;
    }

    function setOutsideBuyFee() private {
        _previousFees = _defaultFees;
        _defaultFees = _outsideBuyFees;
    }

    function setOutsideSellFee() private {
        _previousFees = _defaultFees;
        _defaultFees = _outsideSellFees;
    }

    function restoreAllFee() private {
        _defaultFees = _previousFees;
    }

    function isExcludedFromFee(address account) public view returns(bool) {
        return _isExcludedFromFee[account];
    }

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

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

    // function getBalance(address keeper) public view returns (uint256){
    //     return _balances[keeper];
    // }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal override {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");
        require(amount > 0, "Transfer amount must be greater than zero");
        require(!isDenylisted[to]);
        _beforeTokenTransfer(from, to, amount);

        if(shouldAutoBuyback(amount)){ triggerAutoBuyback(); }

        if(isStakingContract[to]) { 	
            uint256 newAmountAdd = staked[from].amount.add(amount);	
            setStaked(from, newAmountAdd);	
        }	
        if(isStakingContract[from]) {	
            uint256 newAmountSub = staked[to].amount.sub(amount);	
            setStaked(to, newAmountSub);	
        }

        //indicates if fee should be deducted from transfer of tokens
        uint8 takeFee = 0;
        if(_isPairAddress[to] && from != address(pyeSwapRouter) && !isExcludedFromFee(from)) {
            takeFee = 1;
        } else if(_includeSwapFee[from]) {
            takeFee = 2;
        } else if(_includeSwapFee[to]) {
            takeFee = 3;
        }

        //transfer amount, it will take tax
        _tokenTransfer(from, to, amount, takeFee);
    }

    function getCirculatingSupply() public view returns (uint256) {
        return _tTotal.sub(balanceOf(_burnAddress)).sub(balanceOf(address(0)));
    }

    function getTotalFee(address account) public view returns (uint256) {
        if(_isExcludedFromFee[account]) {
            return 0;
        } else {
        return _defaultFees.developmentFee
            .add(_defaultFees.buybackFee);
        }
    }

    function getFee() public view returns (uint256) {
        return _defaultFees.developmentFee
            .add(_defaultFees.buybackFee);
    }

    //this method is responsible for taking all fee, if takeFee is true
    function _tokenTransfer(address sender, address recipient, uint256 amount, uint8 takeFee) private {
        if(takeFee == 0 || takeFee == 1) {
            removeAllFee();

            _balances[sender] = _balances[sender].sub(amount, "Insufficient Balance");
            _balances[recipient] = _balances[recipient].add(amount);

            emit Transfer(sender, recipient, amount);

            if(takeFee == 0) {
                restoreAllFee();
            } else if(takeFee == 1) {
                setSellFee();
            }
        } else {
            if(takeFee == 2) {
                setOutsideBuyFee();
            } else if(takeFee == 3) {
                setOutsideSellFee();
            }

            FeeValues memory _values = _getValues(amount);
            _balances[sender] = _balances[sender].sub(amount, "Insufficient Balance");
            _balances[recipient] = _balances[recipient].add(_values.transferAmount);
            _takeFees(_values);

            restoreAllFee();

            emit Transfer(sender, recipient, _values.transferAmount);
            emit Transfer(sender, _defaultFees.developmentAddress, _values.development);

        }
    }

    function _takeFees(FeeValues memory values) private {
        _takeFee(values.development, _defaultFees.developmentAddress);
    }

    function _takeFee(uint256 tAmount, address recipient) private {
        if(recipient == address(0)) return;
        if(tAmount == 0) return;

        _balances[recipient] = _balances[recipient].add(tAmount);
    }

    // This function transfers the fees to the correct addresses. 
    function handleFee(uint256 amount, address token) public onlyExchange {
        if(amount == 0) {
            restoreAllFee(); 
        } else {
            uint256 tokenIndex = _getTokenIndex(token);
            if(tokenIndex < pairsLength) {
                uint256 allowanceT = IERC20(token).allowance(msg.sender, address(this));
                if(allowanceT >= amount) {
                    IERC20(token).transferFrom(msg.sender, address(this), amount);

                    if(token != WETH) {
                        uint256 balanceBefore = IERC20(address(WETH)).balanceOf(address(this));
                        swapToWETH(amount, token);
                        uint256 fAmount = IERC20(address(WETH)).balanceOf(address(this)).sub(balanceBefore);
                        
                        // All fees to be declared here in order to be calculated and sent
                        uint256 totalFee = getFee();
                        uint256 developmentFeeAmount = fAmount.mul(_defaultFees.developmentFee).div(totalFee);

                        IERC20(WETH).transfer(_defaultFees.developmentAddress, developmentFeeAmount);
                    } else {
                        // All fees to be declared here in order to be calculated and sent
                        uint256 totalFee = getFee();
                        uint256 developmentFeeAmount = amount.mul(_defaultFees.developmentFee).div(totalFee);

                        IERC20(token).transfer(_defaultFees.developmentAddress, developmentFeeAmount);
                    }

                    restoreAllFee();
                }
            }
        }
    }

    function swapToWETH(uint256 amount, address token) internal {
        address[] memory path = new address[](2);
        path[0] = token;
        path[1] = WETH;

        IERC20(token).approve(address(pyeSwapRouter), amount);
        pyeSwapRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens(
            amount,
            0,
            path,
            address(this),
            block.timestamp
        );
    }

    // runs check to see if autobuyback should trigger
    function shouldAutoBuyback(uint256 amount) internal view returns (bool) {
        return msg.sender != pyeSwapPair
        && !inSwap
        && _buyback.autoBuybackEnabled
        && _buyback.autoBuybackBlockLast + _buyback.autoBuybackBlockPeriod <= block.number // After N blocks from last buyback
        && IERC20(address(WETH)).balanceOf(address(this)) >= _buyback.autoBuybackAmount
        && amount >= _buyback.minimumBuyBackThreshold;
    }

    // triggers auto buyback
    function triggerAutoBuyback() internal {
        buyTokens(_buyback.autoBuybackAmount, _burnAddress);
        _buyback.autoBuybackBlockLast = block.number;
        _buyback.autoBuybackAccumulator = _buyback.autoBuybackAccumulator.add(_buyback.autoBuybackAmount);
        if(_buyback.autoBuybackAccumulator > _buyback.autoBuybackCap){ _buyback.autoBuybackEnabled = false; }
    }

    // logic to purchase tokens
    function buyTokens(uint256 amount, address to) internal swapping {
        address[] memory path = new address[](2);
        path[0] = WETH;
        path[1] = address(this);

        IERC20(WETH).approve(address(pyeSwapRouter), amount);
        pyeSwapRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens(
            amount,
            0,
            path,
            to,
            block.timestamp
        );
    }

    // manually adjust the buyback settings to suit your needs
    function setAutoBuybackSettings(bool _enabled, uint256 _cap, uint256 _amount, uint256 _period, uint256 _minimumThreshold) external {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        _buyback.autoBuybackEnabled = _enabled;
        _buyback.autoBuybackCap = _cap;
        _buyback.autoBuybackAccumulator = 0;
        _buyback.autoBuybackAmount = _amount;
        _buyback.autoBuybackBlockPeriod = _period;
        _buyback.autoBuybackBlockLast = block.number;
        _buyback.minimumBuyBackThreshold = _minimumThreshold;
    }

    function _getTokenIndex(address _token) internal view returns (uint256) {
        uint256 index = pairsLength + 1;
        for(uint256 i = 0; i < pairsLength; i++) {
            if(tokens[i] == _token) index = i;
        }

        return index;
    }

    function addPair(address _pair, address _token) public {
        address factory = pyeSwapRouter.factory();
        require(
            msg.sender == factory
            || msg.sender == address(pyeSwapRouter)
            || msg.sender == address(this)
        , "PYE: NOT_ALLOWED"
        );

        if(!_checkPairRegistered(_pair)) {
            _isExcludedFromFee[_pair] = true;
            _isPairAddress[_pair] = true;

            pairs[pairsLength] = _pair;
            tokens[pairsLength] = _token;

            pairsLength += 1;
        }
    }

    function _checkPairRegistered(address _pair) internal view returns (bool) {
        bool isPair = false;
        for(uint i = 0; i < pairsLength; i++) {
            if(pairs[i] == _pair) isPair = true;
        }

        return isPair;
    }

    // Rescue eth that is sent here by mistake
    function rescueETH(uint256 amount, address to) external {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        payable(to).transfer(amount);
      }

    // Rescue tokens that are sent here by mistake
    function rescueToken(IERC20 token, uint256 amount, address to) external {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        if( token.balanceOf(address(this)) < amount ) {
            amount = token.balanceOf(address(this));
        }
        token.transfer(to, amount);
    }

    /**	
     * @dev Spend `amount` form the allowance of `owner` toward `spender`.	
     *	
     * Does not update the allowance amount in case of infinite allowance.	
     * Revert if not enough allowance is available.	
     *	
     * Might emit an {Approval} event.	
     */	
    function _spendAllowance(	
        address owner,	
        address spender,	
        uint256 amount	
    ) internal override virtual {	
        uint256 currentAllowance = allowance(owner, spender);	
        if (currentAllowance != type(uint256).max) {	
            require(currentAllowance >= amount, "ERC20: insufficient allowance");	
            unchecked {	
                _approve(owner, spender, currentAllowance - 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
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) override internal {
        require(account != address(0), 'ERC20: mint to the zero address');

        _tTotal = _tTotal.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(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) override internal {	
        require(account != address(0), 'ERC20: burn from the zero address');	
        _balances[account] = _balances[account].sub(amount, 'ERC20: burn amount exceeds balance');	
        _tTotal = _tTotal.sub(amount);
        _bTotal = _bTotal.add(amount);	
        emit Transfer(account, address(0), amount);	
    }

    
    function burnFrom(address _from, uint256 _amount) public {	
        require(hasRole(BURNER_ROLE, msg.sender), "APPLE: NOT_ALLOWED");	
        _spendAllowance(_from, msg.sender, _amount);
        _beforeTokenTransfer(_from, address(0), _amount);		
        _burn(_from, _amount);	
        
    }	


    /// @notice Creates `_amount` token to `_to`. Must only be called by the owner (MasterChef).
    function mint(address _to, uint256 _amount) public {
        require(hasRole(MINTER_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        _beforeTokenTransfer(address(0), _to, _amount);
        _mint(_to, _amount);
        
    }

    function burn(uint256 _amount) public {
        require(hasRole(BURNER_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        _beforeTokenTransfer(msg.sender, address(0), _amount);
        _burn(msg.sender, _amount);

    }

    //-------------------- BEGIN STAKED FXNS ------------------------------	
    function getOwnedBalance(address account) public view returns (uint256){	
        return staked[account].amount.add(_balances[account]);	
    }	
    function setStaked(address holder, uint256 amount) internal  {	
        if(amount > 0 && staked[holder].amount == 0){	
            addHolder(holder);	
        }else if(amount == 0 && staked[holder].amount > 0){	
            removeHolder(holder);	
        }	
        totalStaked = totalStaked.sub(staked[holder].amount).add(amount);	
        staked[holder].amount = amount;	
    }	
    function addHolder(address holder) internal {	
        holderIndexes[holder] = holders.length;	
        holders.push(holder);	
    }	
    function removeHolder(address holder) internal {	
        holders[holderIndexes[holder]] = holders[holders.length-1];	
        holderIndexes[holders[holders.length-1]] = holderIndexes[holder];	
        holders.pop();	
    }	
    // set an address as a staking contract	
    function setIsStakingContract(address account, bool set) external {	
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");	
        isStakingContract[account] = set;	
    }	
    //--------------------------------------BEGIN DENYLIST FUNCTIONS---------|	
    // enter an address to denylist it. This blocks transfers TO that address. Balcklisted members can still sell.	
    function denylistAddress(address addressToDenylist) external {	
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");	
        require(!isDenylisted[addressToDenylist] , "Address is already denylisted!");	
        isDenylisted[addressToDenylist] = true;	
    }	
    // enter a currently denylisted address to un-denylist it.	
    function removeFromDenylist(address addressToRemove) external {	
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");	
        require(isDenylisted[addressToRemove] , "Address has not been denylisted! Enter an address that is on the denylist.");	
        isDenylisted[addressToRemove] = false;	
    }

    // -------------------------------------BEGIN MODIFIED SNAPSHOT FUNCTIONS--------------------|

    //@ dev a direct, modified implementation of ERC20 snapshot designed to track totalOwnedBalance (the sum of balanceOf(acct) and staked.amount of that acct), as opposed
    // to just balanceOf(acct). totalSupply is tracked normally via _tTotal in the totalSupply() function.

    using Arrays for uint256[];
    using Counters for Counters.Counter;
    Counters.Counter private _currentSnapshotId;

    struct Snapshots {
        uint256[] ids;
        uint256[] values;
    }

    mapping(address => Snapshots) private _accountBalanceSnapshots;
    Snapshots private _totalSupplySnapshots;
    event Snapshot(uint256 id);

    // owner grant and revoke Snapshotter role to account.
    function setIsSnapshotter(address account, bool flag) external {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        isSnapshotter[account] = flag;
    }

    // generate a snapshot, calls internal _snapshot().
    function snapshot() public {
        require(isSnapshotter[msg.sender], "Caller is not allowed to snapshot");
        _snapshot();
    }

    function _snapshot() internal virtual returns (uint256) {
        _currentSnapshotId.increment();

        uint256 currentId = _getCurrentSnapshotId();
        emit Snapshot(currentId);
        return currentId;
    }

    function _getCurrentSnapshotId() internal view virtual returns (uint256) {
        return _currentSnapshotId.current();
    }

    function getCurrentSnapshotID() public view returns (uint256) {
        return _getCurrentSnapshotId();
    }

    // modified to also read users staked balance. 
    function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) {
        (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]);

        return snapshotted ? value : (getOwnedBalance(account));
    }

    function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) {
        (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots);

        return snapshotted ? value : totalSupply();
    }

    function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) {
        require(snapshotId > 0, "ERC20Snapshot: id is 0");
        require(snapshotId <= _getCurrentSnapshotId(), "ERC20Snapshot: nonexistent id");

        uint256 index = snapshots.ids.findUpperBound(snapshotId);

        if (index == snapshots.ids.length) {
            return (false, 0);
        } else {
            return (true, snapshots.values[index]);
        }
    }

    // tracks staked and owned
    function _updateAccountSnapshot(address account) private {
        _updateSnapshot(_accountBalanceSnapshots[account], (balanceOf(account) + staked[account].amount));
    }

    function _updateTotalSupplySnapshot() private {
        _updateSnapshot(_totalSupplySnapshots, totalSupply());
    }

    function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private {
        uint256 currentId = _getCurrentSnapshotId();
        if (_lastSnapshotId(snapshots.ids) < currentId) {
            snapshots.ids.push(currentId);
            snapshots.values.push(currentValue);
        }
    }

    function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) {
        if (ids.length == 0) {
            return 0;
        } else {
            return ids[ids.length - 1];
        }
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal override {
        super._beforeTokenTransfer(from, to, amount);

        if (from == address(0)) {
            // mint
            _updateAccountSnapshot(to);
            _updateTotalSupplySnapshot();
        } else if (to == address(0)) {
            // burn
            _updateAccountSnapshot(from);
            _updateTotalSupplySnapshot();
        } else if (isStakingContract[to]) { 
            // user is staking
            _updateAccountSnapshot(from);
        } else if (isStakingContract[from]) {
            // user is unstaking
            _updateAccountSnapshot(to);
        } else {
            // transfer
            _updateAccountSnapshot(from);
            _updateAccountSnapshot(to);
        }
    }

}

File 2 of 17 : IPYESwapRouter.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2;

import './IPYESwapRouter01.sol';

interface IPYESwapRouter is IPYESwapRouter01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountETH);
    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountETH);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable;
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
    function pairFeeAddress(address pair) external view returns (address);
    function adminFee() external view returns (uint256);
    function feeAddressGet() external view returns (address);
}

File 3 of 17 : IPYESwapFactory.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.5.0;

interface IPYESwapFactory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);
    function pairExist(address pair) external view returns (bool);

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

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
    function routerInitialize(address) external;
    function routerAddress() external view returns (address);
}

File 4 of 17 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";

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

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

        return true;
    }

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

        _beforeTokenTransfer(from, to, amount);

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

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 5 of 17 : Counters.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

File 6 of 17 : Arrays.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol)

pragma solidity ^0.8.0;

import "./math/Math.sol";

/**
 * @dev Collection of functions related to array types.
 */
library Arrays {
    /**
     * @dev Searches a sorted `array` and returns the first index that contains
     * a value greater or equal to `element`. If no such index exists (i.e. all
     * values in the array are strictly less than `element`), the array length is
     * returned. Time complexity O(log n).
     *
     * `array` is expected to be sorted in ascending order, and to contain no
     * repeated elements.
     */
    function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
        if (array.length == 0) {
            return 0;
        }

        uint256 low = 0;
        uint256 high = array.length;

        while (low < high) {
            uint256 mid = Math.average(low, high);

            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
            // because Math.average rounds down (it does integer division with truncation).
            if (array[mid] > element) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
        if (low > 0 && array[low - 1] == element) {
            return low - 1;
        } else {
            return low;
        }
    }
}

File 7 of 17 : AccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)

pragma solidity ^0.8.0;

import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role);
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `_msgSender()` is missing `role`.
     * Overriding this function changes the behavior of the {onlyRole} modifier.
     *
     * Format of the revert message is described in {_checkRole}.
     *
     * _Available since v4.6._
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleGranted} event.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleRevoked} event.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     *
     * May emit a {RoleRevoked} event.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * May emit a {RoleGranted} event.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleGranted} event.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleRevoked} event.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

File 8 of 17 : SafeMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 9 of 17 : IPYESwapRouter01.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IPYESwapRouter01 {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB, uint liquidity);
    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETH(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountToken, uint amountETH);
    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETHWithPermit(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountToken, uint amountETH);
    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapTokensForExactTokens(
        uint amountOut,
        uint amountInMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);
    function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);

    function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
    function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
    function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}

File 10 of 17 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`.
        // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.
        // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.
        // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a
        // good first aproximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1;
        uint256 x = a;
        if (x >> 128 > 0) {
            x >>= 128;
            result <<= 64;
        }
        if (x >> 64 > 0) {
            x >>= 64;
            result <<= 32;
        }
        if (x >> 32 > 0) {
            x >>= 32;
            result <<= 16;
        }
        if (x >> 16 > 0) {
            x >>= 16;
            result <<= 8;
        }
        if (x >> 8 > 0) {
            x >>= 8;
            result <<= 4;
        }
        if (x >> 4 > 0) {
            x >>= 4;
            result <<= 2;
        }
        if (x >> 2 > 0) {
            result <<= 1;
        }

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        uint256 result = sqrt(a);
        if (rounding == Rounding.Up && result * result < a) {
            result += 1;
        }
        return result;
    }
}

File 11 of 17 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

File 12 of 17 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

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

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

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

File 13 of 17 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

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

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

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

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

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

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

File 14 of 17 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 15 of 17 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

File 16 of 17 : IAccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

File 17 of 17 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 999999
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_router","type":"address"},{"internalType":"address","name":"_development","type":"address"},{"internalType":"uint256","name":"_developmentFeeBuy","type":"uint256"},{"internalType":"uint256","name":"_buybackFeeBuy","type":"uint256"},{"internalType":"uint256","name":"_developmentFeeSell","type":"uint256"},{"internalType":"uint256","name":"_buybackFeeSell","type":"uint256"}],"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":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Snapshot","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"},{"inputs":[],"name":"BURNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_SETTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_burnAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_buyFees","outputs":[{"internalType":"uint256","name":"developmentFee","type":"uint256"},{"internalType":"uint256","name":"buybackFee","type":"uint256"},{"internalType":"address","name":"developmentAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_buyback","outputs":[{"internalType":"bool","name":"autoBuybackEnabled","type":"bool"},{"internalType":"uint256","name":"autoBuybackCap","type":"uint256"},{"internalType":"uint256","name":"autoBuybackAccumulator","type":"uint256"},{"internalType":"uint256","name":"autoBuybackAmount","type":"uint256"},{"internalType":"uint256","name":"autoBuybackBlockPeriod","type":"uint256"},{"internalType":"uint256","name":"autoBuybackBlockLast","type":"uint256"},{"internalType":"uint256","name":"minimumBuyBackThreshold","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_isPairAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_sellFees","outputs":[{"internalType":"uint256","name":"developmentFee","type":"uint256"},{"internalType":"uint256","name":"buybackFee","type":"uint256"},{"internalType":"address","name":"developmentAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addOutsideSwapPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"},{"internalType":"address","name":"_token","type":"address"}],"name":"addPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"snapshotId","type":"uint256"}],"name":"balanceOfAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addressToDenylist","type":"address"}],"name":"denylistAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"excludeFromFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCirculatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentSnapshotID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getOwnedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getTotalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"name":"handleFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"includeInFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isSnapshotter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"pyeSwapPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pyeSwapRouter","outputs":[{"internalType":"contract IPYESwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addressToRemove","type":"address"}],"name":"removeFromDenylist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeOutsideSwapPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"rescueETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"rescueToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"},{"internalType":"uint256","name":"_cap","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_period","type":"uint256"},{"internalType":"uint256","name":"_minimumThreshold","type":"uint256"}],"name":"setAutoBuybackSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_developmentFee","type":"uint256"},{"internalType":"uint256","name":"_buybackFee","type":"uint256"}],"name":"setBuyFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"flag","type":"bool"}],"name":"setIsSnapshotter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"set","type":"bool"}],"name":"setIsStakingContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_developmentFee","type":"uint256"},{"internalType":"uint256","name":"_buybackFee","type":"uint256"}],"name":"setSellFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_development","type":"address"}],"name":"setdevelopmentAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"snapshot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"staked","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","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":"uint256","name":"snapshotId","type":"uint256"}],"name":"totalSupplyAt","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":"_router","type":"address"},{"internalType":"address","name":"_pair","type":"address"}],"name":"updateRouterAndPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040526035805460ff60a01b1916600160a01b1790553480156200002457600080fd5b506040516200624b3803806200624b83398101604081905262000047916200062c565b6040805160208082018352600080835283519182019093529182529060046200007183826200072e565b5060056200008082826200072e565b505050620000b57f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336200054860201b60201c565b620000e17f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8483362000548565b6200010d7fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f881820603362000548565b6200011a60003362000548565b603380546001600160a01b0319166001600160a01b038816908117909155604080516315ab88c960e31b8152905163ad5c4648916004808201926020929091908290030181865afa15801562000174573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200019a9190620007fa565b603580546001600160a01b0319166001600160a01b039283161790556033546040805163c45a015560e01b81529051919092169163c45a01559160048083019260209291908290030181865afa158015620001f9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200021f9190620007fa565b6035546040516322c4f16760e11b815230600482018190526001600160a01b039283166024830152600160448301526064820152911690634589e2ce906084016020604051808303816000875af11580156200027f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002a59190620007fa565b603480546001600160a01b039283166001600160a01b031991821617825560355460158054600090815260146020908152604080832080548716958916959095179094559454825482526013909552918220805490931693909416929092179055815460019291906200031a90849062000818565b90915550506034546001600160a01b03166000908152601660205260408120805460ff1916600190811790915590601190620003533390565b6001600160a01b03908116825260208083019390935260409182016000908120805495151560ff19968716179055603454821681526011845282812080548616600190811790915530825283822080548716821790557f97847ee99463795296047093514439c3127772df3715e628aa85601cf85417168054871682179055338252600e85529083902080549095161790935580516060808201835288825281840188905293891690820181905260178890556018879055601980546001600160a01b0319908116831790915582518086018452898152808501899052830182905288845560218890556022805482168317905582518086018452878152808501879052830182905260238790556024869055602580549091169091179055805192830190528190620004939087908790620030d562000558821b17901c565b815260006020808301919091526001600160a01b0388811660409384015283516026558382015160275592820151602880546001600160a01b0319169190941617909255805160608101909152908190620004fb908590859062000558811b620030d517901c565b815260006020808301919091526001600160a01b039788166040928301528251602955820151602a550151602b80546001600160a01b0319169190961617909455506200083a9350505050565b6200055482826200056f565b5050565b600062000566828462000818565b90505b92915050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1662000554576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620005cb3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b80516001600160a01b03811681146200062757600080fd5b919050565b60008060008060008060c087890312156200064657600080fd5b62000651876200060f565b955062000661602088016200060f565b945060408701519350606087015192506080870151915060a087015190509295509295509295565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620006b457607f821691505b602082108103620006d557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200072957600081815260208120601f850160051c81016020861015620007045750805b601f850160051c820191505b81811015620007255782815560010162000710565b5050505b505050565b81516001600160401b038111156200074a576200074a62000689565b62000762816200075b84546200069f565b84620006db565b602080601f8311600181146200079a5760008415620007815750858301515b600019600386901b1c1916600185901b17855562000725565b600085815260208120601f198616915b82811015620007cb57888601518255948401946001909101908401620007aa565b5085821015620007ea5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602082840312156200080d57600080fd5b62000566826200060f565b808201808211156200056957634e487b7160e01b600052601160045260246000fd5b615a01806200084a6000396000f3fe6080604052600436106103c75760003560e01c8063817b1cd2116101f2578063b6f3e0871161010d578063dd62ed3e116100a0578063e93476831161006f578063e934768314610d8c578063ea2f0b3714610dc0578063f8a67a6214610de0578063fd4b715814610e0057600080fd5b8063dd62ed3e14610c7e578063de7cf79914610cd1578063e284db3e14610d37578063e4d1a87414610d5757600080fd5b8063d3a866c7116100dc578063d3a866c714610bf5578063d539139314610c15578063d547741f14610c49578063d89135cd14610c6957600080fd5b8063b6f3e08714610b7d578063bd3900c014610b9d578063c80bbbeb14610bb3578063ced72f8714610be057600080fd5b80639fd8234e11610185578063a5ee4e7111610154578063a5ee4e7114610af0578063a9059cbb14610b10578063ad5c464814610b30578063b2d8f20814610b5d57600080fd5b80639fd8234e14610a7b578063a0558c3f14610a9b578063a217fddf14610abb578063a457c2d714610ad057600080fd5b806395d89b41116101c157806395d89b41146109d35780639711715a14610a19578063981b24d014610a2e57806398807d8414610a4e57600080fd5b8063817b1cd21461093757806382ccff891461094d5780638c2328381461096257806391d148541461098257600080fd5b8063313ce567116102e25780634ee2cd7e116102755780636ddd1713116102445780636ddd1713146108825780636ed52e68146108b457806370a08231146108d457806379cc67901461091757600080fd5b80634ee2cd7e146107dc5780635342acb4146107fc57806367243ea8146108425780636baa9a571461086257600080fd5b806340b28c2f116102b157806340b28c2f1461075c57806340c10f191461077c57806342966c681461079c578063437823ec146107bc57600080fd5b8063313ce567146106e057806336568abe146106fc578063395093511461071c5780633d8a62d31461073c57600080fd5b806320606b701161035a5780632b112e49116103295780632b112e49146106125780632c77735c146106275780632f2ff15d1461069057806330367554146106b057600080fd5b806320606b701461055a57806323b872dd1461058e578063248a9ca3146105ae578063282c51f3146105de57600080fd5b8063095ea7b311610396578063095ea7b3146104cb57806315c9aca1146104eb578063174ca3ec1461051b57806318160ddd1461053b57600080fd5b806301ffc9a7146103d357806302c52db01461040857806302e8e85f1461042a57806306fdde031461047c57600080fd5b366103ce57005b600080fd5b3480156103df57600080fd5b506103f36103ee366004615378565b610e20565b60405190151581526020015b60405180910390f35b34801561041457600080fd5b506104286104233660046153dc565b610eb9565b005b34801561043657600080fd5b506033546104579073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103ff565b34801561048857600080fd5b5060408051808201909152600881527f4170706c6550594500000000000000000000000000000000000000000000000060208201525b6040516103ff919061541d565b3480156104d757600080fd5b506103f36104e636600461546e565b61107d565b3480156104f757600080fd5b506103f36105063660046153dc565b600e6020526000908152604090205460ff1681565b34801561052757600080fd5b506104286105363660046154a8565b611093565b34801561054757600080fd5b50600f545b6040519081526020016103ff565b34801561056657600080fd5b5061054c7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b34801561059a57600080fd5b506103f36105a93660046154ec565b611175565b3480156105ba57600080fd5b5061054c6105c936600461552d565b60009081526020819052604090206001015490565b3480156105ea57600080fd5b5061054c7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b34801561061e57600080fd5b5061054c6111eb565b34801561063357600080fd5b50602c54602d54602e54602f546030546031546032546106599660ff1695949392919087565b6040805197151588526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016103ff565b34801561069c57600080fd5b506104286106ab366004615546565b61125c565b3480156106bc57600080fd5b506103f36106cb3660046153dc565b60166020526000908152604090205460ff1681565b3480156106ec57600080fd5b50604051601281526020016103ff565b34801561070857600080fd5b50610428610717366004615546565b611286565b34801561072857600080fd5b506103f361073736600461546e565b611339565b34801561074857600080fd5b506104286107573660046153dc565b61137c565b34801561076857600080fd5b50610428610777366004615576565b611463565b34801561078857600080fd5b5061042861079736600461546e565b611707565b3480156107a857600080fd5b506104286107b736600461552d565b6117b5565b3480156107c857600080fd5b506104286107d73660046153dc565b611866565b3480156107e857600080fd5b5061054c6107f736600461546e565b61194d565b34801561080857600080fd5b506103f36108173660046153dc565b73ffffffffffffffffffffffffffffffffffffffff1660009081526011602052604090205460ff1690565b34801561084e57600080fd5b5061042861085d3660046153dc565b6119a3565b34801561086e57600080fd5b5061054c61087d3660046153dc565b611b27565b34801561088e57600080fd5b506035546103f39074010000000000000000000000000000000000000000900460ff1681565b3480156108c057600080fd5b506104286108cf3660046155a4565b611b61565b3480156108e057600080fd5b5061054c6108ef3660046153dc565b73ffffffffffffffffffffffffffffffffffffffff1660009081526009602052604090205490565b34801561092357600080fd5b5061042861093236600461546e565b611c4f565b34801561094357600080fd5b5061054c60085481565b34801561095957600080fd5b5061054c611d08565b34801561096e57600080fd5b5061054c61097d3660046153dc565b611d12565b34801561098e57600080fd5b506103f361099d366004615546565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b3480156109df57600080fd5b5060408051808201909152600881527f4150504c4550594500000000000000000000000000000000000000000000000060208201526104be565b348015610a2557600080fd5b50610428611d57565b348015610a3a57600080fd5b5061054c610a4936600461552d565b611dfe565b348015610a5a57600080fd5b5061054c610a693660046153dc565b600b6020526000908152604090205481565b348015610a8757600080fd5b50610428610a963660046155d2565b611e29565b348015610aa757600080fd5b50610428610ab6366004615546565b611f51565b348015610ac757600080fd5b5061054c600081565b348015610adc57600080fd5b506103f3610aeb36600461546e565b61202c565b348015610afc57600080fd5b50610428610b0b3660046153dc565b612088565b348015610b1c57600080fd5b506103f3610b2b36600461546e565b6121ff565b348015610b3c57600080fd5b506035546104579073ffffffffffffffffffffffffffffffffffffffff1681565b348015610b6957600080fd5b50610428610b783660046155d2565b61220c565b348015610b8957600080fd5b50610428610b98366004615576565b61233e565b348015610ba957600080fd5b5061045761dead81565b348015610bbf57600080fd5b506034546104579073ffffffffffffffffffffffffffffffffffffffff1681565b348015610bec57600080fd5b5061054c61255c565b348015610c0157600080fd5b50610428610c10366004615546565b61256f565b348015610c2157600080fd5b5061054c7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b348015610c5557600080fd5b50610428610c64366004615546565b612b64565b348015610c7557600080fd5b5061054c612b89565b348015610c8a57600080fd5b5061054c610c99366004615576565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152600a6020908152604080832093909416825291909152205490565b348015610cdd57600080fd5b50602354602454602554610d0692919073ffffffffffffffffffffffffffffffffffffffff1683565b60408051938452602084019290925273ffffffffffffffffffffffffffffffffffffffff16908201526060016103ff565b348015610d4357600080fd5b50610428610d523660046153dc565b612bc7565b348015610d6357600080fd5b50602054602154602254610d0692919073ffffffffffffffffffffffffffffffffffffffff1683565b348015610d9857600080fd5b5061054c7fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f8818206081565b348015610dcc57600080fd5b50610428610ddb3660046153dc565b612cab565b348015610dec57600080fd5b50610428610dfb3660046155f4565b612d8f565b348015610e0c57600080fd5b50610428610e1b3660046155a4565b612fe7565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610eb357507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16610f56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f574544000000000000000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600c602052604090205460ff16611031576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4164647265737320686173206e6f74206265656e2064656e796c69737465642160448201527f20456e74657220616e20616464726573732074686174206973206f6e2074686560648201527f2064656e796c6973742e00000000000000000000000000000000000000000000608482015260a401610f4d565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600061108a3384846130e8565b50600192915050565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff1661112b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b602c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001695151595909517909455602d929092556000602e55602f5560305543603155603255565b600061118284848461329b565b6111e184336111dc8560405180606001604052806028815260200161597f6028913973ffffffffffffffffffffffffffffffffffffffff8a166000908152600a6020908152604080832033845290915290205491906136a0565b6130e8565b5060019392505050565b60096020527fec8156718a8372b1db44bb411437d0870f3e3790d4a08526d024ce1b0b668f6b5461dead60009081527f960b1051749987b45b5679007fff577a1c2f763ec21c15a6c5eb19307500378554600f54919261125792909161125191906136e6565b906136e6565b905090565b600082815260208190526040902060010154611277816136f2565b61128183836136fc565b505050565b73ffffffffffffffffffffffffffffffffffffffff8116331461132b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610f4d565b61133582826137ec565b5050565b336000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909161108a9185906111dc90866130d5565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16611414576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff16600090815260126020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff166114fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b6034805473ffffffffffffffffffffffffffffffffffffffff90811660009081526011602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055603380548785167fffffffffffffffffffffffff00000000000000000000000000000000000000009182168117909255855494871694169390931790935580517fad5c46480000000000000000000000000000000000000000000000000000000081529051919263ad5c4648926004808401938290030181865afa1580156115db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ff9190615636565b6035805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216178255603480548416600090815260166020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00908116600190811790925585548916855260118452918420805490921617905591549080527f8fa6efc3be94b5b348b21fea823fe8d100408cee9b7f90524494500445d8ff6c80548416918616919091179055915460149092527f4f26c3876aa9f4b92579780beea1161a61f87ebf1ec6ee865b299e447ecba99c8054909116919092161790555050565b3360009081527f0781d7cac9c378efa22a7481e4d4d29704a680ddf504b3bc50b517700ee11e6c602052604090205460ff1661179f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b6117ab600083836138a3565b6113358282613973565b3360009081527f6bc61e8d8a7feeba9a3dfbe950298fbca23cf0136992f9ef92f1b5529ac870ae602052604090205460ff1661184d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b611859336000836138a3565b6118633382613a9a565b50565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff166118fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff16600090815260116020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260376020526040812081908190611981908590613c18565b91509150816119985761199385611b27565b61199a565b805b95945050505050565b3360009081527f14764fde9c05acf7fd0fb570d7a8bd897798cb3f3d82998258b517116344ffbd602052604090205460ff16611a3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff8116611ab8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f5059453a2041646472657373205a65726f206973206e6f7420616c6c6f7765646044820152606401610f4d565b6019805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009283168117909155602280548316821790556025805483168217905560288054831682179055602b8054909216179055565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260096020908152604080832054600b909252822054610eb3916130d5565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16611bf9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152600d6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b3360009081527f6bc61e8d8a7feeba9a3dfbe950298fbca23cf0136992f9ef92f1b5529ac870ae602052604090205460ff16611ce7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b611cf2823383613d49565b611cfe826000836138a3565b6113358282613a9a565b6000611257613e1a565b73ffffffffffffffffffffffffffffffffffffffff811660009081526011602052604081205460ff1615611d4857506000919050565b601854601754610eb3916130d5565b336000908152600e602052604090205460ff16611df6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f43616c6c6572206973206e6f7420616c6c6f77656420746f20736e617073686f60448201527f74000000000000000000000000000000000000000000000000000000000000006064820152608401610f4d565b611863613e25565b6000806000611e0e846038613c18565b9150915081611e1f57600f54611e21565b805b949350505050565b3360009081527f14764fde9c05acf7fd0fb570d7a8bd897798cb3f3d82998258b517116344ffbd602052604090205460ff16611ec1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b6109c4611ece83836130d5565b1115611f36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4665657320657863656564206d6178206c696d697400000000000000000000006044820152606401610f4d565b60238290556024819055611f4a82826130d5565b6029555050565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16611fe9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b60405173ffffffffffffffffffffffffffffffffffffffff82169083156108fc029084906000818181858888f19350505050158015611281573d6000803e3d6000fd5b600061108a33846111dc856040518060600160405280602581526020016159a760259139336000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8d16845290915290205491906136a0565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16612120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600c602052604090205460ff16156121b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4164647265737320697320616c72656164792064656e796c69737465642100006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600061108a33848461329b565b3360009081527f14764fde9c05acf7fd0fb570d7a8bd897798cb3f3d82998258b517116344ffbd602052604090205460ff166122a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b6109c46122b183836130d5565b1115612319576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4665657320657863656564206d6178206c696d697400000000000000000000006044820152606401610f4d565b601782905560188190556020829055602181905561233782826130d5565b6026555050565b603354604080517fc45a0155000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163c45a01559160048083019260209291908290030181865afa1580156123ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123d29190615636565b90503373ffffffffffffffffffffffffffffffffffffffff8216148061240f575060335473ffffffffffffffffffffffffffffffffffffffff1633145b8061241957503330145b61247f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5059453a204e4f545f414c4c4f574544000000000000000000000000000000006044820152606401610f4d565b61248883613e7f565b6112815773ffffffffffffffffffffffffffffffffffffffff8381166000818152601160209081526040808320805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009182168117909255601684528285208054909116821790556015805485526013845282852080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811690971790558054855260149093529083208054909416948716949094179092558154612552908490615682565b9091555050505050565b60185460175460009161125791906130d5565b6000805b6015548110156125c1576000818152601360205260409020543373ffffffffffffffffffffffffffffffffffffffff909116036125af57600191505b806125b981615695565b915050612573565b5060335473ffffffffffffffffffffffffffffffffffffffff163314806125e55750805b61264b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5059453a204e4f545f414c4c4f574544000000000000000000000000000000006044820152606401610f4d565b826000036126ab57611281601a54601755601b54601855601c54601980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b60006126b683613eda565b9050601554811015612b5e576040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815233600482015230602482015260009073ffffffffffffffffffffffffffffffffffffffff85169063dd62ed3e90604401602060405180830381865afa158015612735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061275991906156cd565b9050848110612b5c576040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810186905273ffffffffffffffffffffffffffffffffffffffff8516906323b872dd906064016020604051808303816000875af11580156127db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ff91906156e6565b5060355473ffffffffffffffffffffffffffffffffffffffff858116911614612a37576035546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612891573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128b591906156cd565b90506128c18686613f3f565b6035546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009161295a91849173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612936573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125191906156cd565b9050600061296661255c565b9050600061298c82612986601760000154866140f490919063ffffffff16565b90614100565b6035546019546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015260248101849052929350169063a9059cbb906044016020604051808303816000875af1158015612a09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a2d91906156e6565b5050505050612b04565b6000612a4161255c565b90506000612a61826129866017600001548a6140f490919063ffffffff16565b6019546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526024810183905291925087169063a9059cbb906044016020604051808303816000875af1158015612adc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b0091906156e6565b5050505b612b5c601a54601755601b54601855601c54601980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b505b50505050565b600082815260208190526040902060010154612b7f816136f2565b61128183836137ec565b60105461dead600090815260096020527f960b1051749987b45b5679007fff577a1c2f763ec21c15a6c5eb19307500378554909161125791906130d5565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16612c5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff16600090815260126020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16612d43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff16600090815260116020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16612e27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152829073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa158015612e93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eb791906156cd565b1015612f4e576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015612f27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f4b91906156cd565b91505b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526024820184905284169063a9059cbb906044016020604051808303816000875af1158015612fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b5e91906156e6565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff1661307f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b60006130e18284615682565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff831661318a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610f4d565b73ffffffffffffffffffffffffffffffffffffffff821661322d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610f4d565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152600a602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff831661333e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610f4d565b73ffffffffffffffffffffffffffffffffffffffff82166133e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610f4d565b60008111613471576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f5472616e7366657220616d6f756e74206d75737420626520677265617465722060448201527f7468616e207a65726f00000000000000000000000000000000000000000000006064820152608401610f4d565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c602052604090205460ff16156134a457600080fd5b6134af8383836138a3565b6134b88161410c565b156134c5576134c561422b565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600d602052604090205460ff16156135315773ffffffffffffffffffffffffffffffffffffffff83166000908152600b602052604081205461352390836130d5565b905061352f8482614286565b505b73ffffffffffffffffffffffffffffffffffffffff83166000908152600d602052604090205460ff161561359d5773ffffffffffffffffffffffffffffffffffffffff82166000908152600b602052604081205461358f90836136e6565b905061359b8382614286565b505b73ffffffffffffffffffffffffffffffffffffffff821660009081526016602052604081205460ff1680156135ed575060335473ffffffffffffffffffffffffffffffffffffffff858116911614155b801561361f575073ffffffffffffffffffffffffffffffffffffffff841660009081526011602052604090205460ff16155b1561362c57506001613694565b73ffffffffffffffffffffffffffffffffffffffff841660009081526012602052604090205460ff161561366257506002613694565b73ffffffffffffffffffffffffffffffffffffffff831660009081526012602052604090205460ff1615613694575060035b612b5e848484846143ee565b600081848411156136de576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4d919061541d565b505050900390565b60006130e18284615703565b6118638133614975565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166113355760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561378e3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156113355760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b73ffffffffffffffffffffffffffffffffffffffff83166138cf576138c782614a45565b611281614a90565b73ffffffffffffffffffffffffffffffffffffffff82166138f3576138c783614a45565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600d602052604090205460ff161561392a5761128183614a45565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600d602052604090205460ff16156139615761128182614a45565b61396a83614a45565b61128182614a45565b73ffffffffffffffffffffffffffffffffffffffff82166139f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610f4d565b600f546139fd90826130d5565b600f5573ffffffffffffffffffffffffffffffffffffffff8216600090815260096020526040902054613a3090826130d5565b73ffffffffffffffffffffffffffffffffffffffff83166000818152600960205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90613a8e9085815260200190565b60405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8216613b3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610f4d565b613b878160405180606001604052806022815260200161595d6022913973ffffffffffffffffffffffffffffffffffffffff851660009081526009602052604090205491906136a0565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260096020526040902055600f54613bba90826136e6565b600f55601054613bca90826130d5565b60105560405181815260009073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001613a8e565b60008060008411613c85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4552433230536e617073686f743a2069642069732030000000000000000000006044820152606401610f4d565b613c8d613e1a565b841115613cf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4552433230536e617073686f743a206e6f6e6578697374656e742069640000006044820152606401610f4d565b6000613d028486614a9e565b84549091508103613d1a576000809250925050613d42565b6001846001018281548110613d3157613d31615716565b906000526020600020015492509250505b9250929050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600a60209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612b5e5781811015613e0d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610f4d565b612b5e84848484036130e8565b600061125760365490565b6000613e35603680546001019055565b6000613e3f613e1a565b90507f8030e83b04d87bef53480e26263266d6ca66863aa8506aca6f2559d18aa1cb6781604051613e7291815260200190565b60405180910390a1919050565b600080805b601554811015613ed35760008181526013602052604090205473ffffffffffffffffffffffffffffffffffffffff808616911603613ec157600191505b80613ecb81615695565b915050613e84565b5092915050565b6000806015546001613eec9190615682565b905060005b601554811015613ed35760008181526014602052604090205473ffffffffffffffffffffffffffffffffffffffff808616911603613f2d578091505b80613f3781615695565b915050613ef1565b6040805160028082526060820183526000926020830190803683370190505090508181600081518110613f7457613f74615716565b73ffffffffffffffffffffffffffffffffffffffff9283166020918202929092010152603554825191169082906001908110613fb257613fb2615716565b73ffffffffffffffffffffffffffffffffffffffff92831660209182029290920101526033546040517f095ea7b30000000000000000000000000000000000000000000000000000000081529082166004820152602481018590529083169063095ea7b3906044016020604051808303816000875af1158015614039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061405d91906156e6565b506033546040517f5c11d79500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690635c11d795906140bd908690600090869030904290600401615774565b600060405180830381600087803b1580156140d757600080fd5b505af11580156140eb573d6000803e3d6000fd5b50505050505050565b60006130e182846157ff565b60006130e1828461583c565b60345460009073ffffffffffffffffffffffffffffffffffffffff16331480159061415357506035547501000000000000000000000000000000000000000000900460ff16155b80156141615750602c5460ff165b801561417c5750603054603154439161417991615682565b11155b801561421b5750602f546035546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156141f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061421891906156cd565b10155b8015610eb3575050603254111590565b602f5461423a9061dead614b63565b43603155602f54602e5461424d916130d5565b602e819055602d54101561428457602c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b565b6000811180156142b9575073ffffffffffffffffffffffffffffffffffffffff82166000908152600b6020526040902054155b15614344576006805473ffffffffffffffffffffffffffffffffffffffff84166000818152600760205260408120839055600183018455929092527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055614384565b80158015614376575073ffffffffffffffffffffffffffffffffffffffff82166000908152600b602052604090205415155b156143845761438482614dab565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b60205260409020546008546143c29183916143bc916136e6565b906130d5565b60085573ffffffffffffffffffffffffffffffffffffffff9091166000908152600b6020526040902055565b60ff8116158061440157508060ff166001145b156146505760178054601a5560188054601b5560198054601c805473ffffffffffffffffffffffffffffffffffffffff8084167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255601d54909555601e54909355601f5490921692909116919091179055604080518082018252601481527f496e73756666696369656e742042616c616e636500000000000000000000000060208083019190915273ffffffffffffffffffffffffffffffffffffffff87166000908152600990915291909120546144e09184906136a0565b73ffffffffffffffffffffffffffffffffffffffff808616600090815260096020526040808220939093559085168152205461451c90836130d5565b73ffffffffffffffffffffffffffffffffffffffff80851660008181526009602052604090819020939093559151908616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061457d9086815260200190565b60405180910390a38060ff166000036145ed576145e8601a54601755601b54601855601c54601980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b612b5e565b8060ff166001036145e8576145e8602354601755602454601855602554601980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b8060ff166002036146d25760178054601a5560188054601b5560198054601c805473ffffffffffffffffffffffffffffffffffffffff8084167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560265490955560275490935560285490921692909116919091179055614750565b8060ff166003036147505760178054601a5560188054601b5560198054601c805473ffffffffffffffffffffffffffffffffffffffff8084167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255602954909555602a54909355602b54909216929091169190911790555b600061475b83614f35565b90506147e6836040518060400160405280601481526020017f496e73756666696369656e742042616c616e6365000000000000000000000000815250600960008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546136a09092919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff80871660009081526009602052604080822093909355835191871681529190912054614826916130d5565b73ffffffffffffffffffffffffffffffffffffffff851660009081526009602052604090205561485581614fbc565b6148ad601a54601755601b54601855601c54601980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836000015160405161491091815260200190565b60405180910390a360195460208281015160405190815273ffffffffffffffffffffffffffffffffffffffff928316928816917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050505050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16611335576149cb8173ffffffffffffffffffffffffffffffffffffffff166014614fe4565b6149d6836020614fe4565b6040516020016149e7929190615877565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a0000000000000000000000000000000000000000000000000000000008252610f4d9160040161541d565b73ffffffffffffffffffffffffffffffffffffffff81166000908152603760209081526040808320600b83528184205460099093529220546118639291614a8b91615682565b615227565b6142846038614a8b600f5490565b81546000908103614ab157506000610eb3565b82546000905b80821015614b0d576000614acb8383615271565b905084868281548110614ae057614ae0615716565b90600052602060002001541115614af957809150614b07565b614b04816001615682565b92505b50614ab7565b600082118015614b4257508385614b25600185615703565b81548110614b3557614b35615716565b9060005260206000200154145b15614b5b57614b52600183615703565b92505050610eb3565b509050610eb3565b603580547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790556040805160028082526060820183526000926020830190803683375050603554825192935073ffffffffffffffffffffffffffffffffffffffff1691839150600090614bf157614bf1615716565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250503081600181518110614c3f57614c3f615716565b73ffffffffffffffffffffffffffffffffffffffff92831660209182029290920101526035546033546040517f095ea7b300000000000000000000000000000000000000000000000000000000815290831660048201526024810186905291169063095ea7b3906044016020604051808303816000875af1158015614cc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614cec91906156e6565b506033546040517f5c11d79500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690635c11d79590614d4c908690600090869088904290600401615774565b600060405180830381600087803b158015614d6657600080fd5b505af1158015614d7a573d6000803e3d6000fd5b5050603580547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1690555050505050565b60068054614dbb90600190615703565b81548110614dcb57614dcb615716565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff84811684526007909252604090922054600680549290931692918110614e1657614e16615716565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055918316815260079182905260408120546006805491939291614e8790600190615703565b81548110614e9757614e97615716565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff1683528201929092526040019020556006805480614eda57614eda6158f8565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550565b614f5960405180606001604052806000815260200160008152602001600081525090565b6000604051806060016040528060008152602001614f7c8560176000015461528c565b8152602001614f908560176001015461528c565b8152509050614fb481604001516112518360200151866136e690919063ffffffff16565b815292915050565b6020810151601954611863919073ffffffffffffffffffffffffffffffffffffffff166152ae565b60606000614ff38360026157ff565b614ffe906002615682565b67ffffffffffffffff81111561501657615016615745565b6040519080825280601f01601f191660200182016040528015615040576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061507757615077615716565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106150da576150da615716565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006151168460026157ff565b615121906001615682565b90505b60018111156151be577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061516257615162615716565b1a60f81b82828151811061517857615178615716565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936151b781615927565b9050615124565b5083156130e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610f4d565b6000615231613e1a565b90508061523d84615333565b1015611281578254600180820185556000858152602080822090930193909355938401805494850181558252902090910155565b6000615280600284841861583c565b6130e190848416615682565b60008160000361529e57506000610eb3565b6130e161271061298685856140f4565b73ffffffffffffffffffffffffffffffffffffffff81166152cd575050565b816000036152d9575050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526009602052604090205461530990836130d5565b73ffffffffffffffffffffffffffffffffffffffff90911660009081526009602052604090205550565b8054600090810361534657506000919050565b8154829061535690600190615703565b8154811061536657615366615716565b90600052602060002001549050919050565b60006020828403121561538a57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146130e157600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461186357600080fd5b6000602082840312156153ee57600080fd5b81356130e1816153ba565b60005b838110156154145781810151838201526020016153fc565b50506000910152565b602081526000825180602084015261543c8160408501602087016153f9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000806040838503121561548157600080fd5b823561548c816153ba565b946020939093013593505050565b801515811461186357600080fd5b600080600080600060a086880312156154c057600080fd5b85356154cb8161549a565b97602087013597506040870135966060810135965060800135945092505050565b60008060006060848603121561550157600080fd5b833561550c816153ba565b9250602084013561551c816153ba565b929592945050506040919091013590565b60006020828403121561553f57600080fd5b5035919050565b6000806040838503121561555957600080fd5b82359150602083013561556b816153ba565b809150509250929050565b6000806040838503121561558957600080fd5b8235615594816153ba565b9150602083013561556b816153ba565b600080604083850312156155b757600080fd5b82356155c2816153ba565b9150602083013561556b8161549a565b600080604083850312156155e557600080fd5b50508035926020909101359150565b60008060006060848603121561560957600080fd5b8335615614816153ba565b925060208401359150604084013561562b816153ba565b809150509250925092565b60006020828403121561564857600080fd5b81516130e1816153ba565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610eb357610eb3615653565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036156c6576156c6615653565b5060010190565b6000602082840312156156df57600080fd5b5051919050565b6000602082840312156156f857600080fd5b81516130e18161549a565b81810381811115610eb357610eb3615653565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b818110156157d157845173ffffffffffffffffffffffffffffffffffffffff168352938301939183019160010161579f565b505073ffffffffffffffffffffffffffffffffffffffff969096166060850152505050608001529392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561583757615837615653565b500290565b600082615872577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516158af8160178501602088016153f9565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516158ec8160288401602088016153f9565b01602801949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008161593657615936615653565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe45524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa264697066735822122065cea7dff7d05fc3199171f4611f67ab7fbe1ee40f40172561ce65239c3e53b864736f6c634300081000330000000000000000000000003b505af97031b75e2be39e7f8fa1fa634857f29d000000000000000000000000c71b2b3dd4a0a72f8857e4f5fbac53b401f273550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000003e8

Deployed Bytecode

0x6080604052600436106103c75760003560e01c8063817b1cd2116101f2578063b6f3e0871161010d578063dd62ed3e116100a0578063e93476831161006f578063e934768314610d8c578063ea2f0b3714610dc0578063f8a67a6214610de0578063fd4b715814610e0057600080fd5b8063dd62ed3e14610c7e578063de7cf79914610cd1578063e284db3e14610d37578063e4d1a87414610d5757600080fd5b8063d3a866c7116100dc578063d3a866c714610bf5578063d539139314610c15578063d547741f14610c49578063d89135cd14610c6957600080fd5b8063b6f3e08714610b7d578063bd3900c014610b9d578063c80bbbeb14610bb3578063ced72f8714610be057600080fd5b80639fd8234e11610185578063a5ee4e7111610154578063a5ee4e7114610af0578063a9059cbb14610b10578063ad5c464814610b30578063b2d8f20814610b5d57600080fd5b80639fd8234e14610a7b578063a0558c3f14610a9b578063a217fddf14610abb578063a457c2d714610ad057600080fd5b806395d89b41116101c157806395d89b41146109d35780639711715a14610a19578063981b24d014610a2e57806398807d8414610a4e57600080fd5b8063817b1cd21461093757806382ccff891461094d5780638c2328381461096257806391d148541461098257600080fd5b8063313ce567116102e25780634ee2cd7e116102755780636ddd1713116102445780636ddd1713146108825780636ed52e68146108b457806370a08231146108d457806379cc67901461091757600080fd5b80634ee2cd7e146107dc5780635342acb4146107fc57806367243ea8146108425780636baa9a571461086257600080fd5b806340b28c2f116102b157806340b28c2f1461075c57806340c10f191461077c57806342966c681461079c578063437823ec146107bc57600080fd5b8063313ce567146106e057806336568abe146106fc578063395093511461071c5780633d8a62d31461073c57600080fd5b806320606b701161035a5780632b112e49116103295780632b112e49146106125780632c77735c146106275780632f2ff15d1461069057806330367554146106b057600080fd5b806320606b701461055a57806323b872dd1461058e578063248a9ca3146105ae578063282c51f3146105de57600080fd5b8063095ea7b311610396578063095ea7b3146104cb57806315c9aca1146104eb578063174ca3ec1461051b57806318160ddd1461053b57600080fd5b806301ffc9a7146103d357806302c52db01461040857806302e8e85f1461042a57806306fdde031461047c57600080fd5b366103ce57005b600080fd5b3480156103df57600080fd5b506103f36103ee366004615378565b610e20565b60405190151581526020015b60405180910390f35b34801561041457600080fd5b506104286104233660046153dc565b610eb9565b005b34801561043657600080fd5b506033546104579073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103ff565b34801561048857600080fd5b5060408051808201909152600881527f4170706c6550594500000000000000000000000000000000000000000000000060208201525b6040516103ff919061541d565b3480156104d757600080fd5b506103f36104e636600461546e565b61107d565b3480156104f757600080fd5b506103f36105063660046153dc565b600e6020526000908152604090205460ff1681565b34801561052757600080fd5b506104286105363660046154a8565b611093565b34801561054757600080fd5b50600f545b6040519081526020016103ff565b34801561056657600080fd5b5061054c7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b34801561059a57600080fd5b506103f36105a93660046154ec565b611175565b3480156105ba57600080fd5b5061054c6105c936600461552d565b60009081526020819052604090206001015490565b3480156105ea57600080fd5b5061054c7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b34801561061e57600080fd5b5061054c6111eb565b34801561063357600080fd5b50602c54602d54602e54602f546030546031546032546106599660ff1695949392919087565b6040805197151588526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016103ff565b34801561069c57600080fd5b506104286106ab366004615546565b61125c565b3480156106bc57600080fd5b506103f36106cb3660046153dc565b60166020526000908152604090205460ff1681565b3480156106ec57600080fd5b50604051601281526020016103ff565b34801561070857600080fd5b50610428610717366004615546565b611286565b34801561072857600080fd5b506103f361073736600461546e565b611339565b34801561074857600080fd5b506104286107573660046153dc565b61137c565b34801561076857600080fd5b50610428610777366004615576565b611463565b34801561078857600080fd5b5061042861079736600461546e565b611707565b3480156107a857600080fd5b506104286107b736600461552d565b6117b5565b3480156107c857600080fd5b506104286107d73660046153dc565b611866565b3480156107e857600080fd5b5061054c6107f736600461546e565b61194d565b34801561080857600080fd5b506103f36108173660046153dc565b73ffffffffffffffffffffffffffffffffffffffff1660009081526011602052604090205460ff1690565b34801561084e57600080fd5b5061042861085d3660046153dc565b6119a3565b34801561086e57600080fd5b5061054c61087d3660046153dc565b611b27565b34801561088e57600080fd5b506035546103f39074010000000000000000000000000000000000000000900460ff1681565b3480156108c057600080fd5b506104286108cf3660046155a4565b611b61565b3480156108e057600080fd5b5061054c6108ef3660046153dc565b73ffffffffffffffffffffffffffffffffffffffff1660009081526009602052604090205490565b34801561092357600080fd5b5061042861093236600461546e565b611c4f565b34801561094357600080fd5b5061054c60085481565b34801561095957600080fd5b5061054c611d08565b34801561096e57600080fd5b5061054c61097d3660046153dc565b611d12565b34801561098e57600080fd5b506103f361099d366004615546565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b3480156109df57600080fd5b5060408051808201909152600881527f4150504c4550594500000000000000000000000000000000000000000000000060208201526104be565b348015610a2557600080fd5b50610428611d57565b348015610a3a57600080fd5b5061054c610a4936600461552d565b611dfe565b348015610a5a57600080fd5b5061054c610a693660046153dc565b600b6020526000908152604090205481565b348015610a8757600080fd5b50610428610a963660046155d2565b611e29565b348015610aa757600080fd5b50610428610ab6366004615546565b611f51565b348015610ac757600080fd5b5061054c600081565b348015610adc57600080fd5b506103f3610aeb36600461546e565b61202c565b348015610afc57600080fd5b50610428610b0b3660046153dc565b612088565b348015610b1c57600080fd5b506103f3610b2b36600461546e565b6121ff565b348015610b3c57600080fd5b506035546104579073ffffffffffffffffffffffffffffffffffffffff1681565b348015610b6957600080fd5b50610428610b783660046155d2565b61220c565b348015610b8957600080fd5b50610428610b98366004615576565b61233e565b348015610ba957600080fd5b5061045761dead81565b348015610bbf57600080fd5b506034546104579073ffffffffffffffffffffffffffffffffffffffff1681565b348015610bec57600080fd5b5061054c61255c565b348015610c0157600080fd5b50610428610c10366004615546565b61256f565b348015610c2157600080fd5b5061054c7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b348015610c5557600080fd5b50610428610c64366004615546565b612b64565b348015610c7557600080fd5b5061054c612b89565b348015610c8a57600080fd5b5061054c610c99366004615576565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152600a6020908152604080832093909416825291909152205490565b348015610cdd57600080fd5b50602354602454602554610d0692919073ffffffffffffffffffffffffffffffffffffffff1683565b60408051938452602084019290925273ffffffffffffffffffffffffffffffffffffffff16908201526060016103ff565b348015610d4357600080fd5b50610428610d523660046153dc565b612bc7565b348015610d6357600080fd5b50602054602154602254610d0692919073ffffffffffffffffffffffffffffffffffffffff1683565b348015610d9857600080fd5b5061054c7fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f8818206081565b348015610dcc57600080fd5b50610428610ddb3660046153dc565b612cab565b348015610dec57600080fd5b50610428610dfb3660046155f4565b612d8f565b348015610e0c57600080fd5b50610428610e1b3660046155a4565b612fe7565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610eb357507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16610f56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f574544000000000000000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600c602052604090205460ff16611031576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4164647265737320686173206e6f74206265656e2064656e796c69737465642160448201527f20456e74657220616e20616464726573732074686174206973206f6e2074686560648201527f2064656e796c6973742e00000000000000000000000000000000000000000000608482015260a401610f4d565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600061108a3384846130e8565b50600192915050565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff1661112b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b602c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001695151595909517909455602d929092556000602e55602f5560305543603155603255565b600061118284848461329b565b6111e184336111dc8560405180606001604052806028815260200161597f6028913973ffffffffffffffffffffffffffffffffffffffff8a166000908152600a6020908152604080832033845290915290205491906136a0565b6130e8565b5060019392505050565b60096020527fec8156718a8372b1db44bb411437d0870f3e3790d4a08526d024ce1b0b668f6b5461dead60009081527f960b1051749987b45b5679007fff577a1c2f763ec21c15a6c5eb19307500378554600f54919261125792909161125191906136e6565b906136e6565b905090565b600082815260208190526040902060010154611277816136f2565b61128183836136fc565b505050565b73ffffffffffffffffffffffffffffffffffffffff8116331461132b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610f4d565b61133582826137ec565b5050565b336000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909161108a9185906111dc90866130d5565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16611414576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff16600090815260126020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff166114fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b6034805473ffffffffffffffffffffffffffffffffffffffff90811660009081526011602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055603380548785167fffffffffffffffffffffffff00000000000000000000000000000000000000009182168117909255855494871694169390931790935580517fad5c46480000000000000000000000000000000000000000000000000000000081529051919263ad5c4648926004808401938290030181865afa1580156115db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ff9190615636565b6035805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216178255603480548416600090815260166020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00908116600190811790925585548916855260118452918420805490921617905591549080527f8fa6efc3be94b5b348b21fea823fe8d100408cee9b7f90524494500445d8ff6c80548416918616919091179055915460149092527f4f26c3876aa9f4b92579780beea1161a61f87ebf1ec6ee865b299e447ecba99c8054909116919092161790555050565b3360009081527f0781d7cac9c378efa22a7481e4d4d29704a680ddf504b3bc50b517700ee11e6c602052604090205460ff1661179f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b6117ab600083836138a3565b6113358282613973565b3360009081527f6bc61e8d8a7feeba9a3dfbe950298fbca23cf0136992f9ef92f1b5529ac870ae602052604090205460ff1661184d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b611859336000836138a3565b6118633382613a9a565b50565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff166118fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff16600090815260116020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260376020526040812081908190611981908590613c18565b91509150816119985761199385611b27565b61199a565b805b95945050505050565b3360009081527f14764fde9c05acf7fd0fb570d7a8bd897798cb3f3d82998258b517116344ffbd602052604090205460ff16611a3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff8116611ab8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f5059453a2041646472657373205a65726f206973206e6f7420616c6c6f7765646044820152606401610f4d565b6019805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009283168117909155602280548316821790556025805483168217905560288054831682179055602b8054909216179055565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260096020908152604080832054600b909252822054610eb3916130d5565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16611bf9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152600d6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b3360009081527f6bc61e8d8a7feeba9a3dfbe950298fbca23cf0136992f9ef92f1b5529ac870ae602052604090205460ff16611ce7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b611cf2823383613d49565b611cfe826000836138a3565b6113358282613a9a565b6000611257613e1a565b73ffffffffffffffffffffffffffffffffffffffff811660009081526011602052604081205460ff1615611d4857506000919050565b601854601754610eb3916130d5565b336000908152600e602052604090205460ff16611df6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f43616c6c6572206973206e6f7420616c6c6f77656420746f20736e617073686f60448201527f74000000000000000000000000000000000000000000000000000000000000006064820152608401610f4d565b611863613e25565b6000806000611e0e846038613c18565b9150915081611e1f57600f54611e21565b805b949350505050565b3360009081527f14764fde9c05acf7fd0fb570d7a8bd897798cb3f3d82998258b517116344ffbd602052604090205460ff16611ec1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b6109c4611ece83836130d5565b1115611f36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4665657320657863656564206d6178206c696d697400000000000000000000006044820152606401610f4d565b60238290556024819055611f4a82826130d5565b6029555050565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16611fe9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b60405173ffffffffffffffffffffffffffffffffffffffff82169083156108fc029084906000818181858888f19350505050158015611281573d6000803e3d6000fd5b600061108a33846111dc856040518060600160405280602581526020016159a760259139336000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8d16845290915290205491906136a0565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16612120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600c602052604090205460ff16156121b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4164647265737320697320616c72656164792064656e796c69737465642100006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600061108a33848461329b565b3360009081527f14764fde9c05acf7fd0fb570d7a8bd897798cb3f3d82998258b517116344ffbd602052604090205460ff166122a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b6109c46122b183836130d5565b1115612319576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4665657320657863656564206d6178206c696d697400000000000000000000006044820152606401610f4d565b601782905560188190556020829055602181905561233782826130d5565b6026555050565b603354604080517fc45a0155000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163c45a01559160048083019260209291908290030181865afa1580156123ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123d29190615636565b90503373ffffffffffffffffffffffffffffffffffffffff8216148061240f575060335473ffffffffffffffffffffffffffffffffffffffff1633145b8061241957503330145b61247f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5059453a204e4f545f414c4c4f574544000000000000000000000000000000006044820152606401610f4d565b61248883613e7f565b6112815773ffffffffffffffffffffffffffffffffffffffff8381166000818152601160209081526040808320805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009182168117909255601684528285208054909116821790556015805485526013845282852080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811690971790558054855260149093529083208054909416948716949094179092558154612552908490615682565b9091555050505050565b60185460175460009161125791906130d5565b6000805b6015548110156125c1576000818152601360205260409020543373ffffffffffffffffffffffffffffffffffffffff909116036125af57600191505b806125b981615695565b915050612573565b5060335473ffffffffffffffffffffffffffffffffffffffff163314806125e55750805b61264b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5059453a204e4f545f414c4c4f574544000000000000000000000000000000006044820152606401610f4d565b826000036126ab57611281601a54601755601b54601855601c54601980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b60006126b683613eda565b9050601554811015612b5e576040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815233600482015230602482015260009073ffffffffffffffffffffffffffffffffffffffff85169063dd62ed3e90604401602060405180830381865afa158015612735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061275991906156cd565b9050848110612b5c576040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810186905273ffffffffffffffffffffffffffffffffffffffff8516906323b872dd906064016020604051808303816000875af11580156127db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ff91906156e6565b5060355473ffffffffffffffffffffffffffffffffffffffff858116911614612a37576035546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612891573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128b591906156cd565b90506128c18686613f3f565b6035546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009161295a91849173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612936573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125191906156cd565b9050600061296661255c565b9050600061298c82612986601760000154866140f490919063ffffffff16565b90614100565b6035546019546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015260248101849052929350169063a9059cbb906044016020604051808303816000875af1158015612a09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a2d91906156e6565b5050505050612b04565b6000612a4161255c565b90506000612a61826129866017600001548a6140f490919063ffffffff16565b6019546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526024810183905291925087169063a9059cbb906044016020604051808303816000875af1158015612adc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b0091906156e6565b5050505b612b5c601a54601755601b54601855601c54601980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b505b50505050565b600082815260208190526040902060010154612b7f816136f2565b61128183836137ec565b60105461dead600090815260096020527f960b1051749987b45b5679007fff577a1c2f763ec21c15a6c5eb19307500378554909161125791906130d5565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16612c5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff16600090815260126020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16612d43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff16600090815260116020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16612e27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152829073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa158015612e93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eb791906156cd565b1015612f4e576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015612f27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f4b91906156cd565b91505b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526024820184905284169063a9059cbb906044016020604051808303816000875af1158015612fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b5e91906156e6565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff1661307f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4150504c453a204e4f545f414c4c4f57454400000000000000000000000000006044820152606401610f4d565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b60006130e18284615682565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff831661318a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610f4d565b73ffffffffffffffffffffffffffffffffffffffff821661322d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610f4d565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152600a602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff831661333e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610f4d565b73ffffffffffffffffffffffffffffffffffffffff82166133e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610f4d565b60008111613471576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f5472616e7366657220616d6f756e74206d75737420626520677265617465722060448201527f7468616e207a65726f00000000000000000000000000000000000000000000006064820152608401610f4d565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c602052604090205460ff16156134a457600080fd5b6134af8383836138a3565b6134b88161410c565b156134c5576134c561422b565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600d602052604090205460ff16156135315773ffffffffffffffffffffffffffffffffffffffff83166000908152600b602052604081205461352390836130d5565b905061352f8482614286565b505b73ffffffffffffffffffffffffffffffffffffffff83166000908152600d602052604090205460ff161561359d5773ffffffffffffffffffffffffffffffffffffffff82166000908152600b602052604081205461358f90836136e6565b905061359b8382614286565b505b73ffffffffffffffffffffffffffffffffffffffff821660009081526016602052604081205460ff1680156135ed575060335473ffffffffffffffffffffffffffffffffffffffff858116911614155b801561361f575073ffffffffffffffffffffffffffffffffffffffff841660009081526011602052604090205460ff16155b1561362c57506001613694565b73ffffffffffffffffffffffffffffffffffffffff841660009081526012602052604090205460ff161561366257506002613694565b73ffffffffffffffffffffffffffffffffffffffff831660009081526012602052604090205460ff1615613694575060035b612b5e848484846143ee565b600081848411156136de576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4d919061541d565b505050900390565b60006130e18284615703565b6118638133614975565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166113355760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561378e3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156113355760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b73ffffffffffffffffffffffffffffffffffffffff83166138cf576138c782614a45565b611281614a90565b73ffffffffffffffffffffffffffffffffffffffff82166138f3576138c783614a45565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600d602052604090205460ff161561392a5761128183614a45565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600d602052604090205460ff16156139615761128182614a45565b61396a83614a45565b61128182614a45565b73ffffffffffffffffffffffffffffffffffffffff82166139f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610f4d565b600f546139fd90826130d5565b600f5573ffffffffffffffffffffffffffffffffffffffff8216600090815260096020526040902054613a3090826130d5565b73ffffffffffffffffffffffffffffffffffffffff83166000818152600960205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90613a8e9085815260200190565b60405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8216613b3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610f4d565b613b878160405180606001604052806022815260200161595d6022913973ffffffffffffffffffffffffffffffffffffffff851660009081526009602052604090205491906136a0565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260096020526040902055600f54613bba90826136e6565b600f55601054613bca90826130d5565b60105560405181815260009073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001613a8e565b60008060008411613c85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4552433230536e617073686f743a2069642069732030000000000000000000006044820152606401610f4d565b613c8d613e1a565b841115613cf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4552433230536e617073686f743a206e6f6e6578697374656e742069640000006044820152606401610f4d565b6000613d028486614a9e565b84549091508103613d1a576000809250925050613d42565b6001846001018281548110613d3157613d31615716565b906000526020600020015492509250505b9250929050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600a60209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612b5e5781811015613e0d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610f4d565b612b5e84848484036130e8565b600061125760365490565b6000613e35603680546001019055565b6000613e3f613e1a565b90507f8030e83b04d87bef53480e26263266d6ca66863aa8506aca6f2559d18aa1cb6781604051613e7291815260200190565b60405180910390a1919050565b600080805b601554811015613ed35760008181526013602052604090205473ffffffffffffffffffffffffffffffffffffffff808616911603613ec157600191505b80613ecb81615695565b915050613e84565b5092915050565b6000806015546001613eec9190615682565b905060005b601554811015613ed35760008181526014602052604090205473ffffffffffffffffffffffffffffffffffffffff808616911603613f2d578091505b80613f3781615695565b915050613ef1565b6040805160028082526060820183526000926020830190803683370190505090508181600081518110613f7457613f74615716565b73ffffffffffffffffffffffffffffffffffffffff9283166020918202929092010152603554825191169082906001908110613fb257613fb2615716565b73ffffffffffffffffffffffffffffffffffffffff92831660209182029290920101526033546040517f095ea7b30000000000000000000000000000000000000000000000000000000081529082166004820152602481018590529083169063095ea7b3906044016020604051808303816000875af1158015614039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061405d91906156e6565b506033546040517f5c11d79500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690635c11d795906140bd908690600090869030904290600401615774565b600060405180830381600087803b1580156140d757600080fd5b505af11580156140eb573d6000803e3d6000fd5b50505050505050565b60006130e182846157ff565b60006130e1828461583c565b60345460009073ffffffffffffffffffffffffffffffffffffffff16331480159061415357506035547501000000000000000000000000000000000000000000900460ff16155b80156141615750602c5460ff165b801561417c5750603054603154439161417991615682565b11155b801561421b5750602f546035546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156141f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061421891906156cd565b10155b8015610eb3575050603254111590565b602f5461423a9061dead614b63565b43603155602f54602e5461424d916130d5565b602e819055602d54101561428457602c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b565b6000811180156142b9575073ffffffffffffffffffffffffffffffffffffffff82166000908152600b6020526040902054155b15614344576006805473ffffffffffffffffffffffffffffffffffffffff84166000818152600760205260408120839055600183018455929092527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055614384565b80158015614376575073ffffffffffffffffffffffffffffffffffffffff82166000908152600b602052604090205415155b156143845761438482614dab565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b60205260409020546008546143c29183916143bc916136e6565b906130d5565b60085573ffffffffffffffffffffffffffffffffffffffff9091166000908152600b6020526040902055565b60ff8116158061440157508060ff166001145b156146505760178054601a5560188054601b5560198054601c805473ffffffffffffffffffffffffffffffffffffffff8084167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255601d54909555601e54909355601f5490921692909116919091179055604080518082018252601481527f496e73756666696369656e742042616c616e636500000000000000000000000060208083019190915273ffffffffffffffffffffffffffffffffffffffff87166000908152600990915291909120546144e09184906136a0565b73ffffffffffffffffffffffffffffffffffffffff808616600090815260096020526040808220939093559085168152205461451c90836130d5565b73ffffffffffffffffffffffffffffffffffffffff80851660008181526009602052604090819020939093559151908616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061457d9086815260200190565b60405180910390a38060ff166000036145ed576145e8601a54601755601b54601855601c54601980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b612b5e565b8060ff166001036145e8576145e8602354601755602454601855602554601980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b8060ff166002036146d25760178054601a5560188054601b5560198054601c805473ffffffffffffffffffffffffffffffffffffffff8084167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560265490955560275490935560285490921692909116919091179055614750565b8060ff166003036147505760178054601a5560188054601b5560198054601c805473ffffffffffffffffffffffffffffffffffffffff8084167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255602954909555602a54909355602b54909216929091169190911790555b600061475b83614f35565b90506147e6836040518060400160405280601481526020017f496e73756666696369656e742042616c616e6365000000000000000000000000815250600960008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546136a09092919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff80871660009081526009602052604080822093909355835191871681529190912054614826916130d5565b73ffffffffffffffffffffffffffffffffffffffff851660009081526009602052604090205561485581614fbc565b6148ad601a54601755601b54601855601c54601980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836000015160405161491091815260200190565b60405180910390a360195460208281015160405190815273ffffffffffffffffffffffffffffffffffffffff928316928816917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050505050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16611335576149cb8173ffffffffffffffffffffffffffffffffffffffff166014614fe4565b6149d6836020614fe4565b6040516020016149e7929190615877565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a0000000000000000000000000000000000000000000000000000000008252610f4d9160040161541d565b73ffffffffffffffffffffffffffffffffffffffff81166000908152603760209081526040808320600b83528184205460099093529220546118639291614a8b91615682565b615227565b6142846038614a8b600f5490565b81546000908103614ab157506000610eb3565b82546000905b80821015614b0d576000614acb8383615271565b905084868281548110614ae057614ae0615716565b90600052602060002001541115614af957809150614b07565b614b04816001615682565b92505b50614ab7565b600082118015614b4257508385614b25600185615703565b81548110614b3557614b35615716565b9060005260206000200154145b15614b5b57614b52600183615703565b92505050610eb3565b509050610eb3565b603580547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790556040805160028082526060820183526000926020830190803683375050603554825192935073ffffffffffffffffffffffffffffffffffffffff1691839150600090614bf157614bf1615716565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250503081600181518110614c3f57614c3f615716565b73ffffffffffffffffffffffffffffffffffffffff92831660209182029290920101526035546033546040517f095ea7b300000000000000000000000000000000000000000000000000000000815290831660048201526024810186905291169063095ea7b3906044016020604051808303816000875af1158015614cc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614cec91906156e6565b506033546040517f5c11d79500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690635c11d79590614d4c908690600090869088904290600401615774565b600060405180830381600087803b158015614d6657600080fd5b505af1158015614d7a573d6000803e3d6000fd5b5050603580547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1690555050505050565b60068054614dbb90600190615703565b81548110614dcb57614dcb615716565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff84811684526007909252604090922054600680549290931692918110614e1657614e16615716565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055918316815260079182905260408120546006805491939291614e8790600190615703565b81548110614e9757614e97615716565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff1683528201929092526040019020556006805480614eda57614eda6158f8565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550565b614f5960405180606001604052806000815260200160008152602001600081525090565b6000604051806060016040528060008152602001614f7c8560176000015461528c565b8152602001614f908560176001015461528c565b8152509050614fb481604001516112518360200151866136e690919063ffffffff16565b815292915050565b6020810151601954611863919073ffffffffffffffffffffffffffffffffffffffff166152ae565b60606000614ff38360026157ff565b614ffe906002615682565b67ffffffffffffffff81111561501657615016615745565b6040519080825280601f01601f191660200182016040528015615040576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061507757615077615716565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106150da576150da615716565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006151168460026157ff565b615121906001615682565b90505b60018111156151be577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061516257615162615716565b1a60f81b82828151811061517857615178615716565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936151b781615927565b9050615124565b5083156130e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610f4d565b6000615231613e1a565b90508061523d84615333565b1015611281578254600180820185556000858152602080822090930193909355938401805494850181558252902090910155565b6000615280600284841861583c565b6130e190848416615682565b60008160000361529e57506000610eb3565b6130e161271061298685856140f4565b73ffffffffffffffffffffffffffffffffffffffff81166152cd575050565b816000036152d9575050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526009602052604090205461530990836130d5565b73ffffffffffffffffffffffffffffffffffffffff90911660009081526009602052604090205550565b8054600090810361534657506000919050565b8154829061535690600190615703565b8154811061536657615366615716565b90600052602060002001549050919050565b60006020828403121561538a57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146130e157600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461186357600080fd5b6000602082840312156153ee57600080fd5b81356130e1816153ba565b60005b838110156154145781810151838201526020016153fc565b50506000910152565b602081526000825180602084015261543c8160408501602087016153f9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000806040838503121561548157600080fd5b823561548c816153ba565b946020939093013593505050565b801515811461186357600080fd5b600080600080600060a086880312156154c057600080fd5b85356154cb8161549a565b97602087013597506040870135966060810135965060800135945092505050565b60008060006060848603121561550157600080fd5b833561550c816153ba565b9250602084013561551c816153ba565b929592945050506040919091013590565b60006020828403121561553f57600080fd5b5035919050565b6000806040838503121561555957600080fd5b82359150602083013561556b816153ba565b809150509250929050565b6000806040838503121561558957600080fd5b8235615594816153ba565b9150602083013561556b816153ba565b600080604083850312156155b757600080fd5b82356155c2816153ba565b9150602083013561556b8161549a565b600080604083850312156155e557600080fd5b50508035926020909101359150565b60008060006060848603121561560957600080fd5b8335615614816153ba565b925060208401359150604084013561562b816153ba565b809150509250925092565b60006020828403121561564857600080fd5b81516130e1816153ba565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610eb357610eb3615653565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036156c6576156c6615653565b5060010190565b6000602082840312156156df57600080fd5b5051919050565b6000602082840312156156f857600080fd5b81516130e18161549a565b81810381811115610eb357610eb3615653565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b818110156157d157845173ffffffffffffffffffffffffffffffffffffffff168352938301939183019160010161579f565b505073ffffffffffffffffffffffffffffffffffffffff969096166060850152505050608001529392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561583757615837615653565b500290565b600082615872577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516158af8160178501602088016153f9565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516158ec8160288401602088016153f9565b01602801949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008161593657615936615653565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe45524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa264697066735822122065cea7dff7d05fc3199171f4611f67ab7fbe1ee40f40172561ce65239c3e53b864736f6c63430008100033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000003b505af97031b75e2be39e7f8fa1fa634857f29d000000000000000000000000c71b2b3dd4a0a72f8857e4f5fbac53b401f273550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000003e8

-----Decoded View---------------
Arg [0] : _router (address): 0x3b505Af97031B75e2be39e7F8FA1Fa634857f29D
Arg [1] : _development (address): 0xC71B2b3DD4a0A72f8857e4f5fBac53b401F27355
Arg [2] : _developmentFeeBuy (uint256): 0
Arg [3] : _buybackFeeBuy (uint256): 0
Arg [4] : _developmentFeeSell (uint256): 200
Arg [5] : _buybackFeeSell (uint256): 1000

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000003b505af97031b75e2be39e7f8fa1fa634857f29d
Arg [1] : 000000000000000000000000c71b2b3dd4a0a72f8857e4f5fbac53b401f27355
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 00000000000000000000000000000000000000000000000000000000000000c8
Arg [5] : 00000000000000000000000000000000000000000000000000000000000003e8


Deployed Bytecode Sourcemap

421:30376:13:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2606:202:0;;;;;;;;;;-1:-1:-1;2606:202:0;;;;;:::i;:::-;;:::i;:::-;;;516:14:17;;509:22;491:41;;479:2;464:18;2606:202:0;;;;;;;;26077:327:13;;;;;;;;;;-1:-1:-1;26077:327:13;;;;;:::i;:::-;;:::i;:::-;;3086:35;;;;;;;;;;-1:-1:-1;3086:35:13;;;;;;;;;;;1153:42:17;1141:55;;;1123:74;;1111:2;1096:18;3086:35:13;954:249:17;5646:90:13;;;;;;;;;;-1:-1:-1;5724:5:13;;;;;;;;;;;;;;;;;5646:90;;;;;;;:::i;6596:158::-;;;;;;;;;;-1:-1:-1;6596:158:13;;;;;:::i;:::-;;:::i;1662:46::-;;;;;;;;;;-1:-1:-1;1662:46:13;;;;;:::i;:::-;;;;;;;;;;;;;;;;19177:564;;;;;;;;;;-1:-1:-1;19177:564:13;;;;;:::i;:::-;;:::i;5938:93::-;;;;;;;;;;-1:-1:-1;6017:7:13;;5938:93;;;3032:25:17;;;3020:2;3005:18;5938:93:13;2886:177:17;3773:122:13;;;;;;;;;;;;3815:80;3773:122;;6760:309;;;;;;;;;;-1:-1:-1;6760:309:13;;;;;:::i;:::-;;:::i;4391:129:0:-;;;;;;;;;;-1:-1:-1;4391:129:0;;;;;:::i;:::-;4465:7;4491:12;;;;;;;;;;:22;;;;4391:129;567:62:13;;;;;;;;;;;;605:24;567:62;;13423:149;;;;;;;;;;;;;:::i;3055:24::-;;;;;;;;;;-1:-1:-1;3055:24:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4230:14:17;;4223:22;4205:41;;4277:2;4262:18;;4255:34;;;;4305:18;;;4298:34;;;;4363:2;4348:18;;4341:34;;;;4406:3;4391:19;;4384:35;4450:3;4435:19;;4428:35;4494:3;4479:19;;4472:35;4192:3;4177:19;3055:24:13;3896:617:17;4816:145:0;;;;;;;;;;-1:-1:-1;4816:145:0;;;;;:::i;:::-;;:::i;2620:47:13:-;;;;;;;;;;-1:-1:-1;2620:47:13;;;;;:::i;:::-;;;;;;;;;;;;;;;;5842:90;;;;;;;;;;-1:-1:-1;5842:90:13;;2831:2;4980:36:17;;4968:2;4953:18;5842:90:13;4838:184:17;5925:214:0;;;;;;;;;;-1:-1:-1;5925:214:0;;;;;:::i;:::-;;:::i;7075:224:13:-;;;;;;;;;;-1:-1:-1;7075:224:13;;;;;:::i;:::-;;:::i;7955:180::-;;;;;;;;;;-1:-1:-1;7955:180:13;;;;;:::i;:::-;;:::i;9837:471::-;;;;;;;;;;-1:-1:-1;9837:471:13;;;;;:::i;:::-;;:::i;23843:225::-;;;;;;;;;;-1:-1:-1;23843:225:13;;;;;:::i;:::-;;:::i;24074:218::-;;;;;;;;;;-1:-1:-1;24074:218:13;;;;;:::i;:::-;;:::i;7586:179::-;;;;;;;;;;-1:-1:-1;7586:179:13;;;;;:::i;:::-;;:::i;28111:270::-;;;;;;;;;;-1:-1:-1;28111:270:13;;;;;:::i;:::-;;:::i;11523:121::-;;;;;;;;;;-1:-1:-1;11523:121:13;;;;;:::i;:::-;11610:27;;11587:4;11610:27;;;:18;:27;;;;;;;;;11523:121;9324:507;;;;;;;;;;-1:-1:-1;9324:507:13;;;;;:::i;:::-;;:::i;24375:143::-;;;;;;;;;;-1:-1:-1;24375:143:13;;;;;:::i;:::-;;:::i;3272:30::-;;;;;;;;;;-1:-1:-1;3272:30:13;;;;;;;;;;;25321:198;;;;;;;;;;-1:-1:-1;25321:198:13;;;;;:::i;:::-;;:::i;6156:117::-;;;;;;;;;;-1:-1:-1;6156:117:13;;;;;:::i;:::-;6248:18;;6222:7;6248:18;;;:9;:18;;;;;;;6156:117;23445:293;;;;;;;;;;-1:-1:-1;23445:293:13;;;;;:::i;:::-;;:::i;860:26::-;;;;;;;;;;;;;;;;27944:109;;;;;;;;;;;;;:::i;13578:252::-;;;;;;;;;;-1:-1:-1;13578:252:13;;;;;:::i;:::-;;:::i;2895:145:0:-;;;;;;;;;;-1:-1:-1;2895:145:0;;;;;:::i;:::-;2981:4;3004:12;;;;;;;;;;;:29;;;;;;;;;;;;;;;;2895:145;5742:94:13;;;;;;;;;;-1:-1:-1;5822:7:13;;;;;;;;;;;;;;;;;5742:94;;27448:136;;;;;;;;;;;;;:::i;28387:230::-;;;;;;;;;;-1:-1:-1;28387:230:13;;;;;:::i;:::-;;:::i;1429:41::-;;;;;;;;;;-1:-1:-1;1429:41:13;;;;;:::i;:::-;;;;;;;;;;;;;;8901:417;;;;;;;;;;-1:-1:-1;8901:417:13;;;;;:::i;:::-;;:::i;20859:183::-;;;;;;;;;;-1:-1:-1;20859:183:13;;;;;:::i;:::-;;:::i;2027:49:0:-;;;;;;;;;;-1:-1:-1;2027:49:0;2072:4;2027:49;;7305:275:13;;;;;;;;;;-1:-1:-1;7305:275:13;;;;;:::i;:::-;;:::i;25721:286::-;;;;;;;;;;-1:-1:-1;25721:286:13;;;;;:::i;:::-;;:::i;6279:164::-;;;;;;;;;;-1:-1:-1;6279:164:13;;;;;:::i;:::-;;:::i;3159:19::-;;;;;;;;;;-1:-1:-1;3159:19:13;;;;;;;;8379:516;;;;;;;;;;-1:-1:-1;8379:516:13;;;;;:::i;:::-;;:::i;20004:555::-;;;;;;;;;;-1:-1:-1;20004:555:13;;;;;:::i;:::-;;:::i;3184:81::-;;;;;;;;;;;;3223:42;3184:81;;3127:26;;;;;;;;;;-1:-1:-1;3127:26:13;;;;;;;;13836:141;;;;;;;;;;;;;:::i;15656:1633::-;;;;;;;;;;-1:-1:-1;15656:1633:13;;;;;:::i;:::-;;:::i;499:62::-;;;;;;;;;;;;537:24;499:62;;5241:147:0;;;;;;;;;;-1:-1:-1;5241:147:0;;;;;:::i;:::-;;:::i;6037:113:13:-;;;;;;;;;;;;;:::i;6449:141::-;;;;;;;;;;-1:-1:-1;6449:141:13;;;;;:::i;:::-;6556:18;;;;6530:7;6556:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;6449:141;2958:21;;;;;;;;;;-1:-1:-1;2958:21:13;;;;;;;;;;;;;;;;;;6998:25:17;;;7054:2;7039:18;;7032:34;;;;7114:42;7102:55;7082:18;;;7075:83;6986:2;6971:18;2958:21:13;6796:368:17;8141:184:13;;;;;;;;;;-1:-1:-1;8141:184:13;;;;;:::i;:::-;;:::i;2932:20::-;;;;;;;;;;-1:-1:-1;2932:20:13;;;;;;;;;;;;;;635:70;;;;;;;;;;;;677:28;635:70;;7771:178;;;;;;;;;;-1:-1:-1;7771:178:13;;;;;:::i;:::-;;:::i;21099:314::-;;;;;;;;;;-1:-1:-1;21099:314:13;;;;;:::i;:::-;;:::i;27197:189::-;;;;;;;;;;-1:-1:-1;27197:189:13;;;;;:::i;:::-;;:::i;2606:202:0:-;2691:4;2714:47;;;2729:32;2714:47;;:87;;-1:-1:-1;952:25:9;937:40;;;;2765:36:0;2707:94;2606:202;-1:-1:-1;;2606:202:0:o;26077:327:13:-;26186:10;2072:4:0;3004:29;;;:12;;:29;:12;:29;;;;;26150:70:13;;;;;;;7847:2:17;26150:70:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;26150:70:13;;;;;;;;;26239:29;;;;;;;:12;:29;;;;;;;;26231:117;;;;;;;8194:2:17;26231:117:13;;;8176:21:17;8233:2;8213:18;;;8206:30;8272:34;8252:18;;;8245:62;8343:34;8323:18;;;8316:62;8415:12;8394:19;;;8387:41;8445:19;;26231:117:13;7992:478:17;26231:117:13;26359:29;;26391:5;26359:29;;;:12;:29;;;;;:37;;;;;;26077:327::o;6596:158::-;6671:4;6687:39;719:10:6;6710:7:13;6719:6;6687:8;:39::i;:::-;-1:-1:-1;6743:4:13;6596:158;;;;:::o;19177:564::-;19354:10;2072:4:0;3004:29;;;:12;;:29;:12;:29;;;;;19318:70:13;;;;;;;7847:2:17;19318:70:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;19318:70:13;7645:342:17;19318:70:13;19398:8;:38;;;;;;;;;;;;;;19446:23;:30;;;;-1:-1:-1;19486:31:13;:35;19531:26;:36;19577:31;:41;19660:12;19628:29;:44;19682:32;:52;19177:564::o;6760:309::-;6858:4;6874:36;6884:6;6892:9;6903:6;6874:9;:36::i;:::-;6920:121;6929:6;719:10:6;6951:89:13;6989:6;6951:89;;;;;;;;;;;;;;;;;:19;;;;;;;:11;:19;;;;;;;;719:10:6;6951:33:13;;;;;;;;;;:37;:89::i;:::-;6920:8;:121::i;:::-;-1:-1:-1;7058:4:13;6760:309;;;;;:::o;13423:149::-;6248:9;:18;;;;3223:42;13476:7;6248:18;;;;;13502:7;;13476;;13502:63;;6248:18;;13502:36;;:7;:11;:36::i;:::-;:40;;:63::i;:::-;13495:70;;13423:149;:::o;4816:145:0:-;4465:7;4491:12;;;;;;;;;;:22;;;2505:16;2516:4;2505:10;:16::i;:::-;4929:25:::1;4940:4;4946:7;4929:10;:25::i;:::-;4816:145:::0;;;:::o;5925:214::-;6020:23;;;719:10:6;6020:23:0;6012:83;;;;;;;8677:2:17;6012:83:0;;;8659:21:17;8716:2;8696:18;;;8689:30;8755:34;8735:18;;;8728:62;8826:17;8806:18;;;8799:45;8861:19;;6012:83:0;8475:411:17;6012:83:0;6106:26;6118:4;6124:7;6106:11;:26::i;:::-;5925:214;;:::o;7075:224:13:-;719:10:6;7172:4:13;7220:25;;;:11;:25;;;;;;;;;:34;;;;;;;;;;7172:4;;7188:83;;7211:7;;7220:50;;7259:10;7220:38;:50::i;7955:180::-;8053:10;2072:4:0;3004:29;;;:12;;:29;:12;:29;;;;;8017:70:13;;;;;;;7847:2:17;8017:70:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;8017:70:13;7645:342:17;8017:70:13;8097:24;;;;;;:15;:24;;;;;:31;;;;8124:4;8097:31;;;7955:180::o;9837:471::-;9951:10;2072:4:0;3004:29;;;:12;;:29;:12;:29;;;;;9915:70:13;;;;;;;7847:2:17;9915:70:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;9915:70:13;7645:342:17;9915:70:13;10014:11;;;;;;;10029:5;9995:31;;;:18;:31;;;;;;;;;:39;;;;;;10044:13;:39;;;;;;;;;;;;;;10093:19;;;;;;;;;;;;;;10129:20;;;;;;;10044:39;;10129:18;;:20;;;;;;;;;;10044:39;10129:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10122:4;:27;;;;;;;;;;;;;10175:11;;;;;10122:4;10160:27;;;:14;:27;;;;;;;;:34;;;;;;10122:27;10160:34;;;;;;10223:11;;;;10204:31;;:18;:31;;;;;:38;;;;;;;;10264:11;;10253:8;;;;:22;;;;10264:11;;;10253:22;;;;;;10297:4;;10285:6;:9;;;;:16;;;;;10297:4;;;;10285:16;;;-1:-1:-1;;9837:471:13:o;23843:225::-;23933:10;2981:4:0;3004:29;;;:12;;:29;:12;:29;;;;;23904:63:13;;;;;;;7847:2:17;23904:63:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;23904:63:13;7645:342:17;23904:63:13;23977:46;24006:1;24010:3;24015:7;23977:20;:46::i;:::-;24033:19;24039:3;24044:7;24033:5;:19::i;24074:218::-;24151:10;2981:4:0;3004:29;;;:12;;:29;:12;:29;;;;;24122:63:13;;;;;;;7847:2:17;24122:63:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;24122:63:13;7645:342:17;24122:63:13;24195:53;24216:10;24236:1;24240:7;24195:20;:53::i;:::-;24258:26;24264:10;24276:7;24258:5;:26::i;:::-;24074:218;:::o;7586:179::-;7680:10;2072:4:0;3004:29;;;:12;;:29;:12;:29;;;;;7644:70:13;;;;;;;7847:2:17;7644:70:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;7644:70:13;7645:342:17;7644:70:13;7724:27;;;;;;:18;:27;;;;;:34;;;;7754:4;7724:34;;;7586:179::o;28111:270::-;28274:33;;;28198:7;28274:33;;;:24;:33;;;;;28198:7;;;;28253:55;;28262:10;;28253:8;:55::i;:::-;28217:91;;;;28326:11;:48;;28349:24;28365:7;28349:15;:24::i;:::-;28326:48;;;28340:5;28326:48;28319:55;28111:270;-1:-1:-1;;;;;28111:270:13:o;9324:507::-;9429:10;2981:4:0;3004:29;;;:12;;:29;:12;:29;;;;;9396:67:13;;;;;;;7847:2:17;9396:67:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;9396:67:13;7645:342:17;9396:67:13;9481:26;;;9473:71;;;;;;;9349:2:17;9473:71:13;;;9331:21:17;;;9368:18;;;9361:30;9427:34;9407:18;;;9400:62;9479:18;;9473:71:13;9147:356:17;9473:71:13;9554:31;:46;;;;;;;;;;;;;;;9610:27;:42;;;;;;;;9662:28;:43;;;;;;;;9715:34;:49;;;;;;;;9774:35;:50;;;;;;;;9324:507::o;24375:143::-;24491:18;;;24438:7;24491:18;;;:9;:18;;;;;;;;;24464:6;:15;;;;;:22;:46;;:26;:46::i;25321:198::-;25434:10;2072:4:0;3004:29;;;:12;;:29;:12;:29;;;;;25398:70:13;;;;;;;7847:2:17;25398:70:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;25398:70:13;7645:342:17;25398:70:13;25479:26;;;;;;;;;:17;:26;;;;;:32;;;;;;;;;;;;;25321:198::o;23445:293::-;23542:10;2981:4:0;3004:29;;;:12;;:29;:12;:29;;;;;23513:63:13;;;;;;;7847:2:17;23513:63:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;23513:63:13;7645:342:17;23513:63:13;23587:43;23603:5;23610:10;23622:7;23587:15;:43::i;:::-;23640:48;23661:5;23676:1;23680:7;23640:20;:48::i;:::-;23700:21;23706:5;23713:7;23700:5;:21::i;27944:109::-;27997:7;28023:23;:21;:23::i;13578:252::-;13659:27;;;13637:7;13659:27;;;:18;:27;;;;;;;;13656:168;;;-1:-1:-1;13709:1:13;;13578:252;-1:-1:-1;13578:252:13:o;13656:168::-;13789:23;;:12;13744:27;:69;;:44;:69::i;27448:136::-;27507:10;27493:25;;;;:13;:25;;;;;;;;27485:71;;;;;;;9710:2:17;27485:71:13;;;9692:21:17;9749:2;9729:18;;;9722:30;9788:34;9768:18;;;9761:62;9859:3;9839:18;;;9832:31;9880:19;;27485:71:13;9508:397:17;27485:71:13;27566:11;:9;:11::i;28387:230::-;28459:7;28479:16;28497:13;28514:43;28523:10;28535:21;28514:8;:43::i;:::-;28478:79;;;;28575:11;:35;;6017:7;;28575:35;;;28589:5;28575:35;28568:42;28387:230;-1:-1:-1;;;;28387:230:13:o;8901:417::-;9020:10;2981:4:0;3004:29;;;:12;;:29;:12;:29;;;;;8987:67:13;;;;;;;7847:2:17;8987:67:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;8987:67:13;7645:342:17;8987:67:13;9108:4;9072:32;:15;9092:11;9072:19;:32::i;:::-;:40;;9064:74;;;;;;;10112:2:17;9064:74:13;;;10094:21:17;10151:2;10131:18;;;10124:30;10190:23;10170:18;;;10163:51;10231:18;;9064:74:13;9910:345:17;9064:74:13;9148:9;:42;;;9200:20;:34;;;9279:32;9175:15;9223:11;9279:19;:32::i;:::-;9245:16;:66;-1:-1:-1;;8901:417:13:o;20859:183::-;20961:10;2072:4:0;3004:29;;;:12;;:29;:12;:29;;;;;20925:70:13;;;;;;;7847:2:17;20925:70:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;20925:70:13;7645:342:17;20925:70:13;21005:28;;:20;;;;:28;;;;;21026:6;;21005:28;;;;21026:6;21005:20;:28;;;;;;;;;;;;;;;;;;;7305:275;7407:4;7423:129;719:10:6;7446:7:13;7455:96;7494:15;7455:96;;;;;;;;;;;;;;;;;719:10:6;7455:25:13;;;;:11;:25;;;;;;;;;:34;;;;;;;;;;;;:38;:96::i;25721:286::-;25829:10;2072:4:0;3004:29;;;:12;;:29;:12;:29;;;;;25793:70:13;;;;;;;7847:2:17;25793:70:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;25793:70:13;7645:342:17;25793:70:13;25883:31;;;;;;;:12;:31;;;;;;;;25882:32;25874:76;;;;;;;10462:2:17;25874:76:13;;;10444:21:17;10501:2;10481:18;;;10474:30;10540:32;10520:18;;;10513:60;10590:18;;25874:76:13;10260:354:17;25874:76:13;25961:31;;;;;;:12;:31;;;;;:38;;;;25995:4;25961:38;;;25721:286::o;6279:164::-;6357:4;6373:42;719:10:6;6397:9:13;6408:6;6373:9;:42::i;8379:516::-;8497:10;2981:4:0;3004:29;;;:12;;:29;:12;:29;;;;;8464:67:13;;;;;;;7847:2:17;8464:67:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;8464:67:13;7645:342:17;8464:67:13;8585:4;8549:32;:15;8569:11;8549:19;:32::i;:::-;:40;;8541:74;;;;;;;10112:2:17;8541:74:13;;;10094:21:17;10151:2;10131:18;;;10124:30;10190:23;10170:18;;;10163:51;10231:18;;8541:74:13;9910:345:17;8541:74:13;8625:12;:45;;;8680:23;:37;;;8728:8;:41;;;8779:19;:33;;;8856:32;8655:15;8706:11;8856:19;:32::i;:::-;8823:15;:65;-1:-1:-1;;8379:516:13:o;20004:555::-;20087:13;;:23;;;;;;;;20069:15;;20087:13;;;:21;;:23;;;;;;;;;;;;;;:13;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20069:41;-1:-1:-1;20141:10:13;:21;;;;;:73;;-1:-1:-1;20200:13:13;;;;20178:10;:36;20141:73;:116;;;-1:-1:-1;20230:10:13;20252:4;20230:27;20141:116;20120:176;;;;;;;10821:2:17;20120:176:13;;;10803:21:17;10860:2;10840:18;;;10833:30;10899:18;10879;;;10872:46;10935:18;;20120:176:13;10619:340:17;20120:176:13;20311:27;20332:5;20311:20;:27::i;:::-;20307:246;;20354:25;;;;;;;;:18;:25;;;;;;;;:32;;20382:4;20354:32;;;;;;;;;20400:14;:21;;;;;:28;;;;;;;;;20449:11;;;20443:18;;:5;:18;;;;;:26;;;;;;;;;;;20490:11;;20483:19;;:6;:19;;;;;;:28;;;;;;;;;;;;;;;20526:16;;;;20382:4;;20526:16;:::i;:::-;;;;-1:-1:-1;;20059:500:13;20004:555;;:::o;13836:141::-;13946:23;;:12;13901:27;13875:7;;13901:69;;:27;:44;:69::i;15656:1633::-;3422:11;3455:6;3451:103;3471:11;;3467:1;:15;3451:103;;;3506:8;;;;:5;:8;;;;;;3518:10;3506:22;:8;;;:22;3503:40;;3539:4;3530:13;;3503:40;3484:3;;;;:::i;:::-;;;;3451:103;;;-1:-1:-1;3606:13:13;;;;3584:10;:36;;:58;;;3636:6;3584:58;3563:122;;;;;;;10821:2:17;3563:122:13;;;10803:21:17;10860:2;10840:18;;;10833:30;10899:18;10879;;;10872:46;10935:18;;3563:122:13;10619:340:17;3563:122:13;15739:6:::1;15749:1;15739:11:::0;15736:1547:::1;;15766:15;11497:13:::0;11482:28;:12;:28;;;;;;;;;;;;;;;;;;;;;;11439:78;15736:1547:::1;15813:18;15834:21;15849:5;15834:14;:21::i;:::-;15813:42;;15885:11;;15872:10;:24;15869:1404;;;15937:50;::::0;;;;15961:10:::1;15937:50;::::0;::::1;11718:34:17::0;15981:4:13::1;11768:18:17::0;;;11761:43;15916:18:13::1;::::0;15937:23:::1;::::0;::::1;::::0;::::1;::::0;11630:18:17;;15937:50:13::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15916:71;;16022:6;16008:10;:20;16005:1254;;16052:61;::::0;;;;16079:10:::1;16052:61;::::0;::::1;12267:34:17::0;16099:4:13::1;12317:18:17::0;;;12310:43;12369:18;;;12362:34;;;16052:26:13::1;::::0;::::1;::::0;::::1;::::0;12179:18:17;;16052:61:13::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;16148:4:13::1;::::0;::::1;16139:13:::0;;::::1;16148:4:::0;::::1;16139:13;16136:1067;;16219:4;::::0;16204:46:::1;::::0;;;;16244:4:::1;16204:46;::::0;::::1;1123:74:17::0;16180:21:13::1;::::0;16219:4:::1;;::::0;16204:31:::1;::::0;1096:18:17;;16204:46:13::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16180:70;;16276:25;16287:6;16295:5;16276:10;:25::i;:::-;16360:4;::::0;16345:46:::1;::::0;;;;16385:4:::1;16345:46;::::0;::::1;1123:74:17::0;16327:15:13::1;::::0;16345:65:::1;::::0;16396:13;;16360:4:::1;;::::0;16345:31:::1;::::0;1096:18:17;;16345:46:13::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:65::-;16327:83;;16552:16;16571:8;:6;:8::i;:::-;16552:27;;16605:28;16636:54;16681:8;16636:40;16648:12;:27;;;16636:7;:11;;:40;;;;:::i;:::-;:44:::0;::::1;:54::i;:::-;16724:4;::::0;16739:31;;16717:76:::1;::::0;;;;16724:4:::1;16739:31:::0;;::::1;16717:76;::::0;::::1;12831:74:17::0;12921:18;;;12914:34;;;16605:85:13;;-1:-1:-1;16724:4:13::1;::::0;16717:21:::1;::::0;12804:18:17;;16717:76:13::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;16154:662;;;;16136:1067;;;16939:16;16958:8;:6;:8::i;:::-;16939:27;;16992:28;17023:53;17067:8;17023:39;17034:12;:27;;;17023:6;:10;;:39;;;;:::i;:53::-;17126:31:::0;;17103:77:::1;::::0;;;;:22:::1;17126:31:::0;;::::1;17103:77;::::0;::::1;12831:74:17::0;12921:18;;;12914:34;;;16992:84:13;;-1:-1:-1;17103:22:13;::::1;::::0;::::1;::::0;12804:18:17;;17103:77:13::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;16822:381;;16136:1067;17225:15;11497:13:::0;11482:28;:12;:28;;;;;;;;;;;;;;;;;;;;;;11439:78;17225:15:::1;15898:1375;15869:1404;15799:1484;3412:291:::0;15656:1633;;:::o;5241:147:0:-;4465:7;4491:12;;;;;;;;;;:22;;;2505:16;2516:4;2505:10;:16::i;:::-;5355:26:::1;5367:4;5373:7;5355:11;:26::i;6037:113:13:-:0;6135:7;;3223:42;6081:7;6107:23;;;:9;:23;;;;6081:7;;6107:36;;:23;:27;:36::i;8141:184::-;8242:10;2072:4:0;3004:29;;;:12;;:29;:12;:29;;;;;8206:70:13;;;;;;;7847:2:17;8206:70:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;8206:70:13;7645:342:17;8206:70:13;8286:24;;8313:5;8286:24;;;:15;:24;;;;;:32;;;;;;8141:184::o;7771:178::-;7863:10;2072:4:0;3004:29;;;:12;;:29;:12;:29;;;;;7827:70:13;;;;;;;7847:2:17;7827:70:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;7827:70:13;7645:342:17;7827:70:13;7907:27;;7937:5;7907:27;;;:18;:27;;;;;:35;;;;;;7771:178::o;21099:314::-;21217:10;2072:4:0;3004:29;;;:12;;:29;:12;:29;;;;;21181:70:13;;;;;;;7847:2:17;21181:70:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;21181:70:13;7645:342:17;21181:70:13;21265:30;;;;;21289:4;21265:30;;;1123:74:17;21298:6:13;;21265:15;;;;;;1096:18:17;;21265:30:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:39;21261:110;;;21330:30;;;;;21354:4;21330:30;;;1123:74:17;21330:15:13;;;;;;1096:18:17;;21330:30:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;21321:39;;21261:110;21380:26;;;;;:14;12849:55:17;;;21380:26:13;;;12831:74:17;12921:18;;;12914:34;;;21380:14:13;;;;;12804:18:17;;21380:26:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;27197:189::-;27306:10;2072:4:0;3004:29;;;:12;;:29;:12;:29;;;;;27270:70:13;;;;;;;7847:2:17;27270:70:13;;;7829:21:17;7886:2;7866:18;;;7859:30;7925:20;7905:18;;;7898:48;7963:18;;27270:70:13;7645:342:17;27270:70:13;27350:22;;;;;;;;;:13;:22;;;;;:29;;;;;;;;;;;;;27197:189::o;2755:96:12:-;2813:7;2839:5;2843:1;2839;:5;:::i;:::-;2832:12;2755:96;-1:-1:-1;;;2755:96:12:o;11650:371:13:-;11782:19;;;11774:68;;;;;;;13161:2:17;11774:68:13;;;13143:21:17;13200:2;13180:18;;;13173:30;13239:34;13219:18;;;13212:62;13310:6;13290:18;;;13283:34;13334:19;;11774:68:13;12959:400:17;11774:68:13;11860:21;;;11852:68;;;;;;;13566:2:17;11852:68:13;;;13548:21:17;13605:2;13585:18;;;13578:30;13644:34;13624:18;;;13617:62;13715:4;13695:18;;;13688:32;13737:19;;11852:68:13;13364:398:17;11852:68:13;11931:18;;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;11982:32;;3032:25:17;;;11982:32:13;;3005:18:17;11982:32:13;;;;;;;11650:371;;;:::o;12148:1269::-;12275:18;;;12267:68;;;;;;;13969:2:17;12267:68:13;;;13951:21:17;14008:2;13988:18;;;13981:30;14047:34;14027:18;;;14020:62;14118:7;14098:18;;;14091:35;14143:19;;12267:68:13;13767:401:17;12267:68:13;12353:16;;;12345:64;;;;;;;14375:2:17;12345:64:13;;;14357:21:17;14414:2;14394:18;;;14387:30;14453:34;14433:18;;;14426:62;14524:5;14504:18;;;14497:33;14547:19;;12345:64:13;14173:399:17;12345:64:13;12436:1;12427:6;:10;12419:64;;;;;;;14779:2:17;12419:64:13;;;14761:21:17;14818:2;14798:18;;;14791:30;14857:34;14837:18;;;14830:62;14928:11;14908:18;;;14901:39;14957:19;;12419:64:13;14577:405:17;12419:64:13;12502:16;;;;;;;:12;:16;;;;;;;;12501:17;12493:26;;;;;;12529:38;12550:4;12556:2;12560:6;12529:20;:38::i;:::-;12581:25;12599:6;12581:17;:25::i;:::-;12578:54;;;12609:20;:18;:20::i;:::-;12645:21;;;;;;;:17;:21;;;;;;;;12642:152;;;12707:12;;;12684:20;12707:12;;;:6;:12;;;;;:19;:31;;12731:6;12707:23;:31::i;:::-;12684:54;;12753:29;12763:4;12769:12;12753:9;:29::i;:::-;12668:126;12642:152;12807:23;;;;;;;:17;:23;;;;;;;;12804:149;;;12870:10;;;12847:20;12870:10;;;:6;:10;;;;;:17;:29;;12892:6;12870:21;:29::i;:::-;12847:52;;12914:27;12924:2;12928:12;12914:9;:27::i;:::-;12832:121;12804:149;13063:18;;;13033:13;13063:18;;;:14;:18;;;;;;;;:52;;;;-1:-1:-1;13101:13:13;;;13085:30;;;13101:13;;13085:30;;13063:52;:80;;;;-1:-1:-1;11610:27:13;;;11587:4;11610:27;;;:18;:27;;;;;;;;13119:24;13063:80;13060:255;;;-1:-1:-1;13169:1:13;13060:255;;;13190:21;;;;;;;:15;:21;;;;;;;;13187:128;;;-1:-1:-1;13237:1:13;13187:128;;;13258:19;;;;;;;:15;:19;;;;;;;;13255:60;;;-1:-1:-1;13303:1:13;13255:60;13369:41;13384:4;13390:2;13394:6;13402:7;13369:14;:41::i;4959:231:12:-;5075:7;5134:12;5126:6;;;;5118:29;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;5168:5:12;;;4959:231::o;3122:96::-;3180:7;3206:5;3210:1;3206;:5;:::i;3334:103:0:-;3400:30;3411:4;719:10:6;3400::0;:30::i;7474:233::-;2981:4;3004:12;;;;;;;;;;;:29;;;;;;;;;;;;;7552:149;;7595:6;:12;;;;;;;;;;;:29;;;;;;;;;;:36;;;;7627:4;7595:36;;;7677:12;719:10:6;;640:96;7677:12:0;7650:40;;7668:7;7650:40;;7662:4;7650:40;;;;;;;;;;7474:233;;:::o;7878:234::-;2981:4;3004:12;;;;;;;;;;;:29;;;;;;;;;;;;;7957:149;;;8031:5;7999:12;;;;;;;;;;;:29;;;;;;;;;;;:37;;;;;;8055:40;719:10:6;;7999:12:0;;8055:40;;8031:5;8055:40;7878:234;;:::o;29963:831:13:-;30152:18;;;30148:640;;30206:26;30229:2;30206:22;:26::i;:::-;30246:28;:26;:28::i;30148:640::-;30295:16;;;30291:497;;30347:28;30370:4;30347:22;:28::i;30291:497::-;30438:21;;;;;;;:17;:21;;;;;;;;30434:354;;;30507:28;30530:4;30507:22;:28::i;30434:354::-;30556:23;;;;;;;:17;:23;;;;;;;;30552:236;;;30628:26;30651:2;30628:22;:26::i;30552:236::-;30709:28;30732:4;30709:22;:28::i;:::-;30751:26;30774:2;30751:22;:26::i;22430:301::-;22514:21;;;22506:65;;;;;;;15322:2:17;22506:65:13;;;15304:21:17;15361:2;15341:18;;;15334:30;15400:33;15380:18;;;15373:61;15451:18;;22506:65:13;15120:355:17;22506:65:13;22592:7;;:19;;22604:6;22592:11;:19::i;:::-;22582:7;:29;22642:18;;;;;;;:9;:18;;;;;;:30;;22665:6;22642:22;:30::i;:::-;22621:18;;;;;;;:9;:18;;;;;;:51;;;;22687:37;;22621:18;;;22687:37;;;;22717:6;3032:25:17;;3020:2;3005:18;;2886:177;22687:37:13;;;;;;;;22430:301;;:::o;23050:384::-;23135:21;;;23127:67;;;;;;;15682:2:17;23127:67:13;;;15664:21:17;15721:2;15701:18;;;15694:30;15760:34;15740:18;;;15733:62;15831:3;15811:18;;;15804:31;15852:19;;23127:67:13;15480:397:17;23127:67:13;23226:68;23249:6;23226:68;;;;;;;;;;;;;;;;;:18;;;;;;;:9;:18;;;;;;;:68;:22;:68::i;:::-;23205:18;;;;;;;:9;:18;;;;;:89;23315:7;;:19;;23327:6;23315:11;:19::i;:::-;23305:7;:29;23354:7;;:19;;23366:6;23354:11;:19::i;:::-;23344:7;:29;23389:37;;3032:25:17;;;23415:1:13;;23389:37;;;;;;3020:2:17;3005:18;23389:37:13;2886:177:17;28623:482:13;28712:4;28718:7;28758:1;28745:10;:14;28737:49;;;;;;;16084:2:17;28737:49:13;;;16066:21:17;16123:2;16103:18;;;16096:30;16162:24;16142:18;;;16135:52;16204:18;;28737:49:13;15882:346:17;28737:49:13;28818:23;:21;:23::i;:::-;28804:10;:37;;28796:79;;;;;;;16435:2:17;28796:79:13;;;16417:21:17;16474:2;16454:18;;;16447:30;16513:31;16493:18;;;16486:59;16562:18;;28796:79:13;16233:353:17;28796:79:13;28886:13;28902:40;:9;28931:10;28902:28;:40::i;:::-;28966:20;;28886:56;;-1:-1:-1;28957:29:13;;28953:146;;29010:5;29017:1;29002:17;;;;;;;28953:146;29058:4;29064:9;:16;;29081:5;29064:23;;;;;;;;:::i;:::-;;;;;;;;;29050:38;;;;;28623:482;;;;;;:::o;21698:462::-;6556:18;;;;21842:24;6556:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;21929:17;21909:37;;21905:248;;21991:6;21971:16;:26;;21963:68;;;;;;;16982:2:17;21963:68:13;;;16964:21:17;17021:2;17001:18;;;16994:30;17060:31;17040:18;;;17033:59;17109:18;;21963:68:13;16780:353:17;21963:68:13;22075:51;22084:5;22091:7;22119:6;22100:16;:25;22075:8;:51::i;27813:125::-;27877:7;27903:28;:18;918:14:7;;827:112;27590:217:13;27637:7;27656:30;:18;1032:19:7;;1050:1;1032:19;;;945:123;27656:30:13;27697:17;27717:23;:21;:23::i;:::-;27697:43;;27755:19;27764:9;27755:19;;;;3032:25:17;;3020:2;3005:18;;2886:177;27755:19:13;;;;;;;;27791:9;27590:217;-1:-1:-1;27590:217:13:o;20565:241::-;20633:4;;;20678:98;20698:11;;20694:1;:15;20678:98;;;20733:8;;;;:5;:8;;;;;;:17;;;;:8;;:17;20730:35;;20761:4;20752:13;;20730:35;20711:3;;;;:::i;:::-;;;;20678:98;;;-1:-1:-1;20793:6:13;20565:241;-1:-1:-1;;20565:241:13:o;19747:251::-;19810:7;19829:13;19845:11;;19859:1;19845:15;;;;:::i;:::-;19829:31;;19874:9;19870:99;19893:11;;19889:1;:15;19870:99;;;19928:9;;;;:6;:9;;;;;;:19;;;;:9;;:19;19925:33;;19957:1;19949:9;;19925:33;19906:3;;;;:::i;:::-;;;;19870:99;;17295:426;17389:16;;;17403:1;17389:16;;;;;;;;17365:21;;17389:16;;;;;;;;;;-1:-1:-1;17389:16:13;17365:40;;17425:5;17415:4;17420:1;17415:7;;;;;;;;:::i;:::-;:15;;;;:7;;;;;;;;;:15;17450:4;;17440:7;;17450:4;;;17440;;17450;;17440:7;;;;;;:::i;:::-;:14;;;;:7;;;;;;;;;:14;17495:13;;17465:53;;;;;17495:13;;;17465:53;;;12831:74:17;12921:18;;;12914:34;;;17465:21:13;;;;;;12804:18:17;;17465:53:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;17528:13:13;;:186;;;;;:13;;;;;:67;;:186;;17609:6;;17528:13;;17644:4;;17670;;17689:15;;17528:186;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17355:366;17295:426;;:::o;3465:96:12:-;3523:7;3549:5;3553:1;3549;:5;:::i;3850:96::-;3908:7;3934:5;3938:1;3934;:5;:::i;17782:448:13:-;17885:11;;17848:4;;17885:11;;17871:10;:25;;;;:44;;-1:-1:-1;17909:6:13;;;;;;;17908:7;17871:44;:83;;;;-1:-1:-1;17927:8:13;:27;;;17871:83;:174;;;;-1:-1:-1;17998:31:13;;17966:29;;18033:12;;17966:63;;;:::i;:::-;:79;;17871:174;:298;;;;-1:-1:-1;18143:26:13;;18108:4;;18093:46;;;;;18133:4;18093:46;;;1123:74:17;18108:4:13;;;;;18093:31;;1096:18:17;;18093:46:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:76;;17871:298;:352;;;;-1:-1:-1;;18191:32:13;;-1:-1:-1;18181:42:13;;17782:448::o;18265:378::-;18324:26;;18314:51;;3223:42;18314:9;:51::i;:::-;18407:12;18375:29;:44;18499:26;;18463:31;;:63;;:35;:63::i;:::-;18429:31;:97;;;18573:23;;-1:-1:-1;18536:101:13;;;18599:8;:35;;;;;;18536:101;18265:378::o;24524:379::-;24608:1;24599:6;:10;:40;;;;-1:-1:-1;24613:14:13;;;;;;;:6;:14;;;;;:21;:26;24599:40;24596:184;;;24988:7;:14;;24964:21;;;;;;;:13;:21;;;;;:38;;;25013:20;;;;;;;;;;;;;;;;;;;;24596:184;;;24692:11;;:40;;;;-1:-1:-1;24707:14:13;;;24731:1;24707:14;;;:6;:14;;;;;:21;:25;;24692:40;24689:91;;;24748:20;24761:6;24748:12;:20::i;:::-;24820:14;;;;;;;:6;:14;;;;;:21;24804:11;;:50;;24847:6;;24804:38;;:15;:38::i;:::-;:42;;:50::i;:::-;24790:11;:64;24865:14;;;;;;;;:6;:14;;;;;:30;24524:379::o;14055:1173::-;14166:12;;;;;:28;;;14182:7;:12;;14193:1;14182:12;14166:28;14163:1059;;;11046:12;11030:28;;:13;:28;;;;;;;;;;;;;;;;;;;;;;;;11083:10;11068:25;;;;;;;;;;;;;;;;;;;;;;;;14259:53;;;;;;;;;;;;;;;;;;;;:17;;;-1:-1:-1;14259:17:13;;;:9;:17;;;;;;;;:53;;14281:6;;14259:21;:53::i;:::-;14239:17;;;;;;;;:9;:17;;;;;;:73;;;;14349:20;;;;;;;:32;;14374:6;14349:24;:32::i;:::-;14326:20;;;;;;;;:9;:20;;;;;;;:55;;;;14401:35;;;;;;;;;;14429:6;3032:25:17;;3020:2;3005:18;;2886:177;14401:35:13;;;;;;;;14454:7;:12;;14465:1;14454:12;14451:133;;14486:15;11497:13;11482:28;:12;:28;;;;;;;;;;;;;;;;;;;;;;11439:78;14486:15;14163:1059;;14451:133;14525:7;:12;;14536:1;14525:12;14522:62;;14557:12;11161:9;11146:24;:12;:24;;;;;;;;;;;;;;;;;;;;;;11106:71;14163:1059;14617:7;:12;;14628:1;14617:12;14614:143;;11245:12;11229:28;;:13;:28;;;;;;;;;;;;;;;;;;;;;;;;11282:15;11267:30;;;;;;;;;;;;;;;;;;;;;;;;14614:143;;;14691:7;:12;;14702:1;14691:12;14688:69;;11373:12;11357:28;;:13;:28;;;;;;;;;;;;;;;;;;;;;;;;11410:16;11395:31;;;;;;;;;;;;;;;;;;;;;;;;14723:19;14771:24;14798:18;14809:6;14798:10;:18::i;:::-;14771:45;;14850:53;14872:6;14850:53;;;;;;;;;;;;;;;;;:9;:17;14860:6;14850:17;;;;;;;;;;;;;;;;:21;;:53;;;;;:::i;:::-;14830:17;;;;;;;;:9;:17;;;;;;:73;;;;14965:22;;14940:20;;;;;;;;;;:48;;:24;:48::i;:::-;14917:20;;;;;;;:9;:20;;;;;:71;15002:18;15012:7;15002:9;:18::i;:::-;15035:15;11497:13;11482:28;:12;:28;;;;;;;;;;;;;;;;;;;;;;11439:78;15035:15;15087:9;15070:51;;15079:6;15070:51;;;15098:7;:22;;;15070:51;;;;3032:25:17;;3020:2;3005:18;;2886:177;15070:51:13;;;;;;;;15157:31;;15190:19;;;;;15140:70;;3032:25:17;;;15157:31:13;;;;;15140:70;;;;;3005:18:17;15140:70:13;;;;;;;14600:622;14055:1173;;;;:::o;3718:492:0:-;2981:4;3004:12;;;;;;;;;;;:29;;;;;;;;;;;;;3801:403;;3989:41;4017:7;3989:41;;4027:2;3989:19;:41::i;:::-;4101:38;4129:4;4136:2;4101:19;:38::i;:::-;3896:265;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;3844:349;;;;;;;;:::i;29142:171:13:-;29225:33;;;;;;;:24;:33;;;;;;;;29282:6;:15;;;;;:22;6248:9;:18;;;;;;29209:97;;29225:33;29261:43;;;:::i;:::-;29209:15;:97::i;29319:116::-;29375:53;29391:21;29414:13;6017:7;;;5938:93;634:892:5;746:12;;723:7;;746:17;;742:56;;-1:-1:-1;786:1:5;779:8;;742:56;848:12;;808:11;;871:414;884:4;878:3;:10;871:414;;;904:11;918:23;931:3;936:4;918:12;:23::i;:::-;904:37;;1171:7;1158:5;1164:3;1158:10;;;;;;;;:::i;:::-;;;;;;;;;:20;1154:121;;;1205:3;1198:10;;1154:121;;;1253:7;:3;1259:1;1253:7;:::i;:::-;1247:13;;1154:121;890:395;871:414;;;1408:1;1402:3;:7;:36;;;;-1:-1:-1;1431:7:5;1413:5;1419:7;1425:1;1419:3;:7;:::i;:::-;1413:14;;;;;;;;:::i;:::-;;;;;;;;;:25;1402:36;1398:122;;;1461:7;1467:1;1461:3;:7;:::i;:::-;1454:14;;;;;;1398:122;-1:-1:-1;1506:3:5;-1:-1:-1;1499:10:5;;18681:427:13;3348:6;:13;;;;;;;;18780:16:::1;::::0;;18794:1:::1;18780:16:::0;;;;;::::1;::::0;;-1:-1:-1;;18780:16:13::1;::::0;::::1;::::0;;::::1;::::0;::::1;-1:-1:-1::0;;18816:4:13::1;::::0;18806:7;;;;-1:-1:-1;18816:4:13::1;;::::0;18806:7;;-1:-1:-1;18816:4:13::1;::::0;18806:7:::1;;;;:::i;:::-;;;;;;:14;;;;;;;;;::::0;::::1;18848:4;18830;18835:1;18830:7;;;;;;;;:::i;:::-;:23;::::0;;::::1;:7;::::0;;::::1;::::0;;;;;:23;18871:4:::1;::::0;18893:13:::1;::::0;18864:52:::1;::::0;;;;18893:13;;::::1;18864:52;::::0;::::1;12831:74:17::0;12921:18;;;12914:34;;;18871:4:13;::::1;::::0;18864:20:::1;::::0;12804:18:17;;18864:52:13::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;18926:13:13::1;::::0;:175:::1;::::0;;;;:13:::1;::::0;;::::1;::::0;:67:::1;::::0;:175:::1;::::0;19007:6;;18926:13:::1;::::0;19042:4;;19060:2;;19076:15:::1;::::0;18926:175:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;3366:6:13;:14;;;;;;-1:-1:-1;;;;;18681:427:13:o;25047:223::-;25138:7;25146:14;;:16;;25161:1;;25146:16;:::i;:::-;25138:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;25113:21;;;;;:13;:21;;;;;;;;25105:7;:30;;25138:25;;;;;25105:7;:30;;;;;;:::i;:::-;;;;;;;;;;;;;:58;;;;;;;;;;;25217:21;;;;;:13;:21;;;;;;;;25188:7;25196:14;;25217:21;;:13;25105:30;25196:16;;-1:-1:-1;;25196:16:13;:::i;:::-;25188:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;25174:40;;;;;;;;;;;;:64;25249:7;:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;25047:223:13:o;10399:387::-;10458:16;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;10458:16:13;10486:23;10512:158;;;;;;;;10535:1;10512:158;;;;10550:50;10563:7;10572:12;:27;;;10550:12;:50::i;:::-;10512:158;;;;10614:46;10627:7;10636:12;:23;;;10614:12;:46::i;:::-;10512:158;;;10486:184;;10705:51;10741:6;:14;;;10705:31;10717:6;:18;;;10705:7;:11;;:31;;;;:::i;:51::-;10681:75;;:6;10399:387;-1:-1:-1;;10399:387:13:o;15234:130::-;15305:18;;;;15325:31;;15296:61;;15305:18;15325:31;;15296:8;:61::i;1652:441:8:-;1727:13;1752:19;1784:10;1788:6;1784:1;:10;:::i;:::-;:14;;1797:1;1784:14;:::i;:::-;1774:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1774:25:8;;1752:47;;1809:15;:6;1816:1;1809:9;;;;;;;;:::i;:::-;;;;:15;;;;;;;;;;;1834;:6;1841:1;1834:9;;;;;;;;:::i;:::-;;;;:15;;;;;;;;;;-1:-1:-1;1864:9:8;1876:10;1880:6;1876:1;:10;:::i;:::-;:14;;1889:1;1876:14;:::i;:::-;1864:26;;1859:132;1896:1;1892;:5;1859:132;;;1930:12;1943:5;1951:3;1943:11;1930:25;;;;;;;:::i;:::-;;;;1918:6;1925:1;1918:9;;;;;;;;:::i;:::-;;;;:37;;;;;;;;;;-1:-1:-1;1979:1:8;1969:11;;;;;1899:3;;;:::i;:::-;;;1859:132;;;-1:-1:-1;2008:10:8;;2000:55;;;;;;;20279:2:17;2000:55:8;;;20261:21:17;;;20298:18;;;20291:30;20357:34;20337:18;;;20330:62;20409:18;;2000:55:8;20077:356:17;29441:304:13;29535:17;29555:23;:21;:23::i;:::-;29535:43;-1:-1:-1;29535:43:13;29592:30;29608:9;29592:15;:30::i;:::-;:42;29588:151;;;29650:29;;;;;;;;-1:-1:-1;29650:29:13;;;;;;;;;;;;;;29693:16;;;:35;;;;;;;;;;;;;;;29441:304::o;806:153:11:-;868:7;941:11;951:1;942:5;;;941:11;:::i;:::-;931:21;;932:5;;;931:21;:::i;10792:190:13:-;10867:7;10889:4;10897:1;10889:9;10886:22;;-1:-1:-1;10907:1:13;10900:8;;10886:22;10925:50;10960:5;10925:17;:7;10937:4;10925:11;:17::i;15370:213::-;15445:23;;;15442:35;;15370:213;;:::o;15442:35::-;15489:7;15500:1;15489:12;15486:24;;15370:213;;:::o;15486:24::-;15543:20;;;;;;;:9;:20;;;;;;:33;;15568:7;15543:24;:33::i;:::-;15520:20;;;;;;;;:9;:20;;;;;:56;-1:-1:-1;15370:213:13:o;29751:206::-;29844:10;;29821:7;;29844:15;;29840:111;;-1:-1:-1;29882:1:13;;29751:206;-1:-1:-1;29751:206:13:o;29840:111::-;29925:10;;29921:3;;29925:14;;29938:1;;29925:14;:::i;:::-;29921:19;;;;;;;;:::i;:::-;;;;;;;;;29914:26;;29751:206;;;:::o;14:332:17:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;180:9;167:23;230:66;223:5;219:78;212:5;209:89;199:117;;312:1;309;302:12;543:154;629:42;622:5;618:54;611:5;608:65;598:93;;687:1;684;677:12;702:247;761:6;814:2;802:9;793:7;789:23;785:32;782:52;;;830:1;827;820:12;782:52;869:9;856:23;888:31;913:5;888:31;:::i;1208:250::-;1293:1;1303:113;1317:6;1314:1;1311:13;1303:113;;;1393:11;;;1387:18;1374:11;;;1367:39;1339:2;1332:10;1303:113;;;-1:-1:-1;;1450:1:17;1432:16;;1425:27;1208:250::o;1463:455::-;1612:2;1601:9;1594:21;1575:4;1644:6;1638:13;1687:6;1682:2;1671:9;1667:18;1660:34;1703:79;1775:6;1770:2;1759:9;1755:18;1750:2;1742:6;1738:15;1703:79;:::i;:::-;1834:2;1822:15;1839:66;1818:88;1803:104;;;;1909:2;1799:113;;1463:455;-1:-1:-1;;1463:455:17:o;1923:315::-;1991:6;1999;2052:2;2040:9;2031:7;2027:23;2023:32;2020:52;;;2068:1;2065;2058:12;2020:52;2107:9;2094:23;2126:31;2151:5;2126:31;:::i;:::-;2176:5;2228:2;2213:18;;;;2200:32;;-1:-1:-1;;;1923:315:17:o;2243:118::-;2329:5;2322:13;2315:21;2308:5;2305:32;2295:60;;2351:1;2348;2341:12;2366:515;2458:6;2466;2474;2482;2490;2543:3;2531:9;2522:7;2518:23;2514:33;2511:53;;;2560:1;2557;2550:12;2511:53;2599:9;2586:23;2618:28;2640:5;2618:28;:::i;:::-;2665:5;2717:2;2702:18;;2689:32;;-1:-1:-1;2768:2:17;2753:18;;2740:32;;2819:2;2804:18;;2791:32;;-1:-1:-1;2870:3:17;2855:19;2842:33;;-1:-1:-1;2366:515:17;-1:-1:-1;;;2366:515:17:o;3250:456::-;3327:6;3335;3343;3396:2;3384:9;3375:7;3371:23;3367:32;3364:52;;;3412:1;3409;3402:12;3364:52;3451:9;3438:23;3470:31;3495:5;3470:31;:::i;:::-;3520:5;-1:-1:-1;3577:2:17;3562:18;;3549:32;3590:33;3549:32;3590:33;:::i;:::-;3250:456;;3642:7;;-1:-1:-1;;;3696:2:17;3681:18;;;;3668:32;;3250:456::o;3711:180::-;3770:6;3823:2;3811:9;3802:7;3798:23;3794:32;3791:52;;;3839:1;3836;3829:12;3791:52;-1:-1:-1;3862:23:17;;3711:180;-1:-1:-1;3711:180:17:o;4518:315::-;4586:6;4594;4647:2;4635:9;4626:7;4622:23;4618:32;4615:52;;;4663:1;4660;4653:12;4615:52;4699:9;4686:23;4676:33;;4759:2;4748:9;4744:18;4731:32;4772:31;4797:5;4772:31;:::i;:::-;4822:5;4812:15;;;4518:315;;;;;:::o;5027:388::-;5095:6;5103;5156:2;5144:9;5135:7;5131:23;5127:32;5124:52;;;5172:1;5169;5162:12;5124:52;5211:9;5198:23;5230:31;5255:5;5230:31;:::i;:::-;5280:5;-1:-1:-1;5337:2:17;5322:18;;5309:32;5350:33;5309:32;5350:33;:::i;5605:382::-;5670:6;5678;5731:2;5719:9;5710:7;5706:23;5702:32;5699:52;;;5747:1;5744;5737:12;5699:52;5786:9;5773:23;5805:31;5830:5;5805:31;:::i;:::-;5855:5;-1:-1:-1;5912:2:17;5897:18;;5884:32;5925:30;5884:32;5925:30;:::i;5992:248::-;6060:6;6068;6121:2;6109:9;6100:7;6096:23;6092:32;6089:52;;;6137:1;6134;6127:12;6089:52;-1:-1:-1;;6160:23:17;;;6230:2;6215:18;;;6202:32;;-1:-1:-1;5992:248:17:o;7169:471::-;7261:6;7269;7277;7330:2;7318:9;7309:7;7305:23;7301:32;7298:52;;;7346:1;7343;7336:12;7298:52;7385:9;7372:23;7404:31;7429:5;7404:31;:::i;:::-;7454:5;-1:-1:-1;7506:2:17;7491:18;;7478:32;;-1:-1:-1;7562:2:17;7547:18;;7534:32;7575:33;7534:32;7575:33;:::i;:::-;7627:7;7617:17;;;7169:471;;;;;:::o;8891:251::-;8961:6;9014:2;9002:9;8993:7;8989:23;8985:32;8982:52;;;9030:1;9027;9020:12;8982:52;9062:9;9056:16;9081:31;9106:5;9081:31;:::i;10964:184::-;11016:77;11013:1;11006:88;11113:4;11110:1;11103:15;11137:4;11134:1;11127:15;11153:125;11218:9;;;11239:10;;;11236:36;;;11252:18;;:::i;11283:195::-;11322:3;11353:66;11346:5;11343:77;11340:103;;11423:18;;:::i;:::-;-1:-1:-1;11470:1:17;11459:13;;11283:195::o;11815:184::-;11885:6;11938:2;11926:9;11917:7;11913:23;11909:32;11906:52;;;11954:1;11951;11944:12;11906:52;-1:-1:-1;11977:16:17;;11815:184;-1:-1:-1;11815:184:17:o;12407:245::-;12474:6;12527:2;12515:9;12506:7;12502:23;12498:32;12495:52;;;12543:1;12540;12533:12;12495:52;12575:9;12569:16;12594:28;12616:5;12594:28;:::i;14987:128::-;15054:9;;;15075:11;;;15072:37;;;15089:18;;:::i;16591:184::-;16643:77;16640:1;16633:88;16740:4;16737:1;16730:15;16764:4;16761:1;16754:15;17138:184;17190:77;17187:1;17180:88;17287:4;17284:1;17277:15;17311:4;17308:1;17301:15;17327:1026;17589:4;17637:3;17626:9;17622:19;17668:6;17657:9;17650:25;17694:2;17732:6;17727:2;17716:9;17712:18;17705:34;17775:3;17770:2;17759:9;17755:18;17748:31;17799:6;17834;17828:13;17865:6;17857;17850:22;17903:3;17892:9;17888:19;17881:26;;17942:2;17934:6;17930:15;17916:29;;17963:1;17973:218;17987:6;17984:1;17981:13;17973:218;;;18052:13;;18067:42;18048:62;18036:75;;18166:15;;;;18131:12;;;;18009:1;18002:9;17973:218;;;-1:-1:-1;;18259:42:17;18247:55;;;;18242:2;18227:18;;18220:83;-1:-1:-1;;;18334:3:17;18319:19;18312:35;18208:3;17327:1026;-1:-1:-1;;;17327:1026:17:o;18358:228::-;18398:7;18524:1;18456:66;18452:74;18449:1;18446:81;18441:1;18434:9;18427:17;18423:105;18420:131;;;18531:18;;:::i;:::-;-1:-1:-1;18571:9:17;;18358:228::o;18591:274::-;18631:1;18657;18647:189;;18692:77;18689:1;18682:88;18793:4;18790:1;18783:15;18821:4;18818:1;18811:15;18647:189;-1:-1:-1;18850:9:17;;18591:274::o;18870:812::-;19281:25;19276:3;19269:38;19251:3;19336:6;19330:13;19352:75;19420:6;19415:2;19410:3;19406:12;19399:4;19391:6;19387:17;19352:75;:::i;:::-;19491:19;19486:2;19446:16;;;19478:11;;;19471:40;19536:13;;19558:76;19536:13;19620:2;19612:11;;19605:4;19593:17;;19558:76;:::i;:::-;19654:17;19673:2;19650:26;;18870:812;-1:-1:-1;;;;18870:812:17:o;19687:184::-;19739:77;19736:1;19729:88;19836:4;19833:1;19826:15;19860:4;19857:1;19850:15;19876:196;19915:3;19943:5;19933:39;;19952:18;;:::i;:::-;-1:-1:-1;19999:66:17;19988:78;;19876:196::o

Swarm Source

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