ETH Price: $2,673.34 (-5.03%)

Contract

0x055ccA50e0d4A7f406ac962e8336CAA2368535Ae
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
LoanTokenLogicV3

Compiler Version
v0.5.8+commit.23d335f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

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

/**
 * Copyright 2017-2019, bZeroX, LLC. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0.
 */
 
pragma solidity 0.5.8;
pragma experimental ABIEncoderV2;


/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 * See https://github.com/ethereum/EIPs/issues/179
 */
contract ERC20Basic {
  function totalSupply() public view returns (uint256);
  function balanceOf(address _who) public view returns (uint256);
  function transfer(address _to, uint256 _value) public returns (bool);
  event Transfer(address indexed from, address indexed to, uint256 value);
}

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract ERC20 is ERC20Basic {
  function allowance(address _owner, address _spender)
    public view returns (uint256);

  function transferFrom(address _from, address _to, uint256 _value)
    public returns (bool);

  function approve(address _spender, uint256 _value) public returns (bool);
  event Approval(
    address indexed owner,
    address indexed spender,
    uint256 value
  );
}

/**
 * @title EIP20/ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract EIP20 is ERC20 {
    string public name;
    uint8 public decimals;
    string public symbol;
}

contract WETHInterface is EIP20 {
    function deposit() external payable;
    function withdraw(uint256 wad) external;
}

/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
    // Gas optimization: this is cheaper than asserting 'a' not being zero, but the
    // benefit is lost if 'b' is also tested.
    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
    if (_a == 0) {
      return 0;
    }

    c = _a * _b;
    assert(c / _a == _b);
    return c;
  }

  /**
  * @dev Integer division of two numbers, truncating the quotient.
  */
  function div(uint256 _a, uint256 _b) internal pure returns (uint256) {
    // assert(_b > 0); // Solidity automatically throws when dividing by 0
    // uint256 c = _a / _b;
    // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold
    return _a / _b;
  }

  /**
  * @dev Integer division of two numbers, rounding up and truncating the quotient
  */
  function divCeil(uint256 _a, uint256 _b) internal pure returns (uint256) {
    if (_a == 0) {
      return 0;
    }

    return ((_a - 1) / _b) + 1;
  }

  /**
  * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {
    assert(_b <= _a);
    return _a - _b;
  }

  /**
  * @dev Adds two numbers, throws on overflow.
  */
  function add(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
    c = _a + _b;
    assert(c >= _a);
    return c;
  }
}

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address public owner;


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


  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  constructor() public {
    owner = msg.sender;
  }

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

  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param _newOwner The address to transfer ownership to.
   */
  function transferOwnership(address _newOwner) public onlyOwner {
    _transferOwnership(_newOwner);
  }

  /**
   * @dev Transfers control of the contract to a newOwner.
   * @param _newOwner The address to transfer ownership to.
   */
  function _transferOwnership(address _newOwner) internal {
    require(_newOwner != address(0));
    emit OwnershipTransferred(owner, _newOwner);
    owner = _newOwner;
  }
}

/**
 * @title Helps contracts guard against reentrancy attacks.
 * @author Remco Bloemen <remco@2π.com>, Eenae <[email protected]>
 * @dev If you mark a function `nonReentrant`, you should also
 * mark it `external`.
 */
contract ReentrancyGuard {

  /// @dev Constant for unlocked guard state - non-zero to prevent extra gas costs.
  /// See: https://github.com/OpenZeppelin/openzeppelin-solidity/issues/1056
  uint256 internal constant REENTRANCY_GUARD_FREE = 1;

  /// @dev Constant for locked guard state
  uint256 internal constant REENTRANCY_GUARD_LOCKED = 2;

  /**
   * @dev We use a single lock for the whole contract.
   */
  uint256 internal reentrancyLock = REENTRANCY_GUARD_FREE;

  /**
   * @dev Prevents a contract from calling itself, directly or indirectly.
   * If you mark a function `nonReentrant`, you should also
   * mark it `external`. Calling one `nonReentrant` function from
   * another is not supported. Instead, you can implement a
   * `private` function doing the actual work, and an `external`
   * wrapper marked as `nonReentrant`.
   */
  modifier nonReentrant() {
    require(reentrancyLock == REENTRANCY_GUARD_FREE, "nonReentrant");
    reentrancyLock = REENTRANCY_GUARD_LOCKED;
    _;
    reentrancyLock = REENTRANCY_GUARD_FREE;
  }

}

contract LoanTokenization is ReentrancyGuard, Ownable {

    uint256 internal constant MAX_UINT = 2**256 - 1;

    string public name;
    string public symbol;
    uint8 public decimals;

    address public bZxContract;
    address public bZxVault;
    address public bZxOracle;
    address public wethContract;

    address public loanTokenAddress;

    // price of token at last user checkpoint
    mapping (address => uint256) internal checkpointPrices_;
}

contract LoanTokenStorage is LoanTokenization {

    struct ListIndex {
        uint256 index;
        bool isSet;
    }

    struct LoanData {
        bytes32 loanOrderHash;
        uint256 leverageAmount;
        uint256 initialMarginAmount;
        uint256 maintenanceMarginAmount;
        uint256 maxDurationUnixTimestampSec;
        uint256 index;
    }

    struct TokenReserves {
        address lender;
        uint256 amount;
    }

    event Borrow(
        address indexed borrower,
        uint256 borrowAmount,
        uint256 interestRate,
        address collateralTokenAddress,
        address tradeTokenToFillAddress,
        bool withdrawOnOpen
    );

    event Repay(
        bytes32 indexed loanOrderHash,
        address indexed borrower,
        address closer,
        uint256 amount,
        bool isLiquidation
    );

    event Claim(
        address indexed claimant,
        uint256 tokenAmount,
        uint256 assetAmount,
        uint256 remainingTokenAmount,
        uint256 price
    );

    bool internal isInitialized_ = false;

    address public tokenizedRegistry;

    uint256 public baseRate = 1000000000000000000; // 1.0%
    uint256 public rateMultiplier = 18750000000000000000; // 18.75%

    // slot addition (non-sequential): lowUtilBaseRate = 8000000000000000000; // 8.0%
    // slot addition (non-sequential): lowUtilRateMultiplier = 4750000000000000000; // 4.75%

    // "fee percentage retained by the oracle" = SafeMath.sub(10**20, spreadMultiplier);
    uint256 public spreadMultiplier;

    mapping (uint256 => bytes32) public loanOrderHashes; // mapping of levergeAmount to loanOrderHash
    mapping (bytes32 => LoanData) public loanOrderData; // mapping of loanOrderHash to LoanOrder
    uint256[] public leverageList;

    TokenReserves[] public burntTokenReserveList; // array of TokenReserves
    mapping (address => ListIndex) public burntTokenReserveListIndex; // mapping of lender address to ListIndex objects
    uint256 public burntTokenReserved; // total outstanding burnt token amount
    address internal nextOwedLender_;

    uint256 public totalAssetBorrow; // current amount of loan token amount tied up in loans

    uint256 public checkpointSupply;

    uint256 internal lastSettleTime_;

    uint256 public initialPrice;
}

contract AdvancedTokenStorage is LoanTokenStorage {
    using SafeMath for uint256;

    event Transfer(
        address indexed from,
        address indexed to,
        uint256 value
    );
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
    event Mint(
        address indexed minter,
        uint256 tokenAmount,
        uint256 assetAmount,
        uint256 price
    );
    event Burn(
        address indexed burner,
        uint256 tokenAmount,
        uint256 assetAmount,
        uint256 price
    );

    mapping(address => uint256) internal balances;
    mapping (address => mapping (address => uint256)) internal allowed;
    uint256 internal totalSupply_;

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

    function balanceOf(
        address _owner)
        public
        view
        returns (uint256)
    {
        return balances[_owner];
    }

    function allowance(
        address _owner,
        address _spender)
        public
        view
        returns (uint256)
    {
        return allowed[_owner][_spender];
    }
}

contract AdvancedToken is AdvancedTokenStorage {
    using SafeMath for uint256;

    function approve(
        address _spender,
        uint256 _value)
        public
        returns (bool)
    {
        allowed[msg.sender][_spender] = _value;
        emit Approval(msg.sender, _spender, _value);
        return true;
    }

    function _mint(
        address _to,
        uint256 _tokenAmount,
        uint256 _assetAmount,
        uint256 _price)
        internal
    {
        require(_to != address(0), "invalid address");
        totalSupply_ = totalSupply_.add(_tokenAmount);
        balances[_to] = balances[_to].add(_tokenAmount);

        emit Mint(_to, _tokenAmount, _assetAmount, _price);
        emit Transfer(address(0), _to, _tokenAmount);
    }

    function _burn(
        address _who,
        uint256 _tokenAmount,
        uint256 _assetAmount,
        uint256 _price)
        internal
    {
        require(_tokenAmount <= balances[_who], "burn value exceeds balance");
        // no need to require value <= totalSupply, since that would imply the
        // sender's balance is greater than the totalSupply, which *should* be an assertion failure

        balances[_who] = balances[_who].sub(_tokenAmount);
        if (balances[_who] <= 10) { // we can't leave such small balance quantities
            _tokenAmount = _tokenAmount.add(balances[_who]);
            balances[_who] = 0;
        }

        totalSupply_ = totalSupply_.sub(_tokenAmount);

        emit Burn(_who, _tokenAmount, _assetAmount, _price);
        emit Transfer(_who, address(0), _tokenAmount);
    }
}

contract BZxObjects {

    struct LoanOrder {
        address loanTokenAddress;
        address interestTokenAddress;
        address collateralTokenAddress;
        address oracleAddress;
        uint256 loanTokenAmount;
        uint256 interestAmount;
        uint256 initialMarginAmount;
        uint256 maintenanceMarginAmount;
        uint256 maxDurationUnixTimestampSec;
        bytes32 loanOrderHash;
    }

    struct LoanPosition {
        address trader;
        address collateralTokenAddressFilled;
        address positionTokenAddressFilled;
        uint256 loanTokenAmountFilled;
        uint256 loanTokenAmountUsed;
        uint256 collateralTokenAmountFilled;
        uint256 positionTokenAmountFilled;
        uint256 loanStartUnixTimestampSec;
        uint256 loanEndUnixTimestampSec;
        bool active;
        uint256 positionId;
    }
}

contract OracleNotifierInterface {

    function closeLoanNotifier(
        BZxObjects.LoanOrder memory loanOrder,
        BZxObjects.LoanPosition memory loanPosition,
        address loanCloser,
        uint256 closeAmount,
        bool isLiquidation)
        public
        returns (bool);
}

interface IBZx {
    function takeOrderFromiToken(
        bytes32 loanOrderHash, // existing loan order hash
        address[3] calldata sentAddresses,
            // trader: borrower/trader
            // collateralTokenAddress: collateral token
            // tradeTokenAddress: trade token
        uint256[7] calldata sentAmounts,
            // newInterestRate: new loan interest rate
            // newLoanAmount: new loan size (principal from lender)
            // interestInitialAmount: interestAmount sent to determine initial loan length (this is included in one of the below)
            // loanTokenSent: loanTokenAmount + interestAmount + any extra
            // collateralTokenSent: collateralAmountRequired + any extra
            // tradeTokenSent: tradeTokenAmount (optional)
            // withdrawalAmount: Actual amount sent to borrower (can't exceed newLoanAmount)
        bytes calldata loanData)
        external
        returns (uint256);

    function getLenderInterestForOracle(
        address lender,
        address oracleAddress,
        address interestTokenAddress)
        external
        view
        returns (
            uint256,    // interestPaid
            uint256,    // interestPaidDate
            uint256,    // interestOwedPerDay
            uint256);   // interestUnPaid

    function oracleAddresses(
        address oracleAddress)
        external
        view
        returns (address);

    function getRequiredCollateral(
        address loanTokenAddress,
        address collateralTokenAddress,
        address oracleAddress,
        uint256 newLoanAmount,
        uint256 marginAmount)
        external
        view
        returns (uint256 collateralTokenAmount);

    function getBorrowAmount(
        address loanTokenAddress,
        address collateralTokenAddress,
        address oracleAddress,
        uint256 collateralTokenAmount,
        uint256 marginAmount)
        external
        view
        returns (uint256 borrowAmount);
}

interface IBZxOracle {
    function getTradeData(
        address sourceTokenAddress,
        address destTokenAddress,
        uint256 sourceTokenAmount)
        external
        view
        returns (uint256 sourceToDestRate, uint256 sourceToDestPrecision, uint256 destTokenAmount);
}

interface iTokenizedRegistry {
    function isTokenType(
        address _token,
        uint256 _tokenType)
        external
        view
        returns (bool valid);
}

contract LoanTokenLogicV3 is AdvancedToken, OracleNotifierInterface {
    using SafeMath for uint256;

    address internal target_;

    modifier onlyOracle() {
        require(msg.sender == IBZx(bZxContract).oracleAddresses(bZxOracle), "1");
        _;
    }


    function()
        external
        payable
    {
        require(
            msg.sender == wethContract,
            "fallback not allowed"
        );
    }


    /* Public functions */

    function mintWithEther(
        address receiver)
        external
        payable
        nonReentrant
        returns (uint256 mintAmount)
    {
        require(loanTokenAddress == wethContract, "2");
        return _mintToken(
            receiver,
            msg.value
        );
    }

    function mint(
        address receiver,
        uint256 depositAmount)
        external
        nonReentrant
        returns (uint256 mintAmount)
    {
        return _mintToken(
            receiver,
            depositAmount
        );
    }

    function burnToEther(
        address receiver,
        uint256 burnAmount)
        external
        nonReentrant
        returns (uint256 loanAmountPaid)
    {
        require(loanTokenAddress == wethContract, "3");
        loanAmountPaid = _burnToken(
            receiver,
            burnAmount
        );

        if (loanAmountPaid != 0) {
            WETHInterface(wethContract).withdraw(loanAmountPaid);
            (bool success, ) = receiver.call.value(loanAmountPaid)("");
            require(success, "4");
        }
    }

    function burn(
        address receiver,
        uint256 burnAmount)
        external
        nonReentrant
        returns (uint256 loanAmountPaid)
    {
        loanAmountPaid = _burnToken(
            receiver,
            burnAmount
        );

        if (loanAmountPaid != 0) {
            require(ERC20(loanTokenAddress).transfer(
                receiver,
                loanAmountPaid
            ), "5");
        }
    }

    function borrowTokenFromDeposit(
        uint256 borrowAmount,
        uint256 leverageAmount,
        uint256 initialLoanDuration,    // duration in seconds
        uint256 collateralTokenSent,    // set to 0 if sending ETH
        address borrower,
        address collateralTokenAddress, // address(0) means ETH and ETH must be sent with the call
        bytes memory loanData)          // arbitrary order data
        public
        payable
        nonReentrant
        returns (bytes32 loanOrderHash)
    {
        require(
            ((msg.value == 0 && collateralTokenAddress != address(0) && collateralTokenSent != 0) ||
            (msg.value != 0 && (collateralTokenAddress == address(0) || collateralTokenAddress == wethContract) && collateralTokenSent == 0)),
            "6"
        );

        loanOrderHash = loanOrderHashes[leverageAmount];
        require(loanOrderHash != 0, "7");

        _settleInterest();

        uint256[7] memory sentAmounts;

        bool useFixedInterestModel = loanOrderData[loanOrderHash].maxDurationUnixTimestampSec == 0;

        if (msg.value != 0) {
            collateralTokenAddress = wethContract;
            collateralTokenSent = msg.value;
        }

        if (borrowAmount == 0) {
            borrowAmount = _getBorrowAmountForDeposit(
                collateralTokenSent,
                leverageAmount,
                initialLoanDuration,
                collateralTokenAddress
            );
            require(borrowAmount != 0, "borrowAmount == 0");

            // withdrawalAmount
            sentAmounts[6] = borrowAmount;
        } else {
            // withdrawalAmount
            sentAmounts[6] = borrowAmount;
        }

        // interestRate, interestInitialAmount, borrowAmount (newBorrowAmount)
        (sentAmounts[0], sentAmounts[2], borrowAmount) = _getInterestRateAndAmount(
            borrowAmount,
            _totalAssetSupply(0), // interest is settled above
            initialLoanDuration,
            useFixedInterestModel
        );

        sentAmounts[6] = _borrowTokenAndUseFinal(
            loanOrderHash,
            [
                borrower,
                collateralTokenAddress,
                address(0) // tradeTokenAddress
            ],
            [
                sentAmounts[0],         // interestRate
                borrowAmount,
                sentAmounts[2],         // interestInitialAmount
                0,                      // loanTokenSent
                collateralTokenSent,
                0,                      // tradeTokenSent
                sentAmounts[6]          // withdrawalAmount
            ],
            loanData
        );
        require(sentAmounts[6] == borrowAmount, "8");
    }

    // Called to borrow token for withdrawal or trade
    // borrowAmount: loan amount to borrow
    // leverageAmount: signals the amount of initial margin we will collect
    //   Please reference the docs for supported values.
    //   Example: 2000000000000000000 -> 150% initial margin
    //            2000000000000000028 -> 150% initial margin, 28-day fixed-term
    // interestInitialAmount: This value will indicate the initial duration of the loan
    //   This is ignored if the loan order has a fixed-term
    // loanTokenSent: loan token sent (interestAmount + extra)
    // collateralTokenSent: collateral token sent
    // tradeTokenSent: trade token sent
    // borrower: the address the loan will be assigned to (this address can be different than msg.sender)
    //    Collateral and interest for loan will be withdrawn from msg.sender
    // collateralTokenAddress: The token to collateralize the loan in
    // tradeTokenAddress: The borrowed token will be swap for this token to start a leveraged trade
    //    If the borrower wished to instead withdraw the borrowed token to their wallet, set this to address(0)
    //    If set to address(0), initial collateral required will equal initial margin percent + 100%
    // returns loanOrderHash for the base protocol loan
    function borrowTokenAndUse(
        uint256 borrowAmount,
        uint256 leverageAmount,
        uint256 interestInitialAmount,
        uint256 loanTokenSent,
        uint256 collateralTokenSent,
        uint256 tradeTokenSent,
        address borrower,
        address collateralTokenAddress,
        address tradeTokenAddress,
        bytes memory loanData)
        public
        nonReentrant
        returns (bytes32 loanOrderHash)
    {
        require(collateralTokenAddress != address(0) &&
            (tradeTokenAddress == address(0) ||
                tradeTokenAddress != loanTokenAddress),
            "9"
        );

        loanOrderHash = _borrowTokenAndUse(
            leverageAmount,
            [
                borrower,
                collateralTokenAddress,
                tradeTokenAddress
            ],
            [
                0, // interestRate (found later)
                borrowAmount,
                interestInitialAmount,
                loanTokenSent,
                collateralTokenSent,
                tradeTokenSent,
                borrowAmount
            ],
            false, // amountIsADeposit
            loanData
        );
    }

    function marginTradeFromDeposit(
        uint256 depositAmount,
        uint256 leverageAmount,
        uint256 loanTokenSent,
        uint256 collateralTokenSent,
        uint256 tradeTokenSent,
        address trader,
        address depositTokenAddress,
        address collateralTokenAddress,
        address tradeTokenAddress)
        public
        returns (bytes32 loanOrderHash)
    {
        return _marginTradeFromDeposit(
            depositAmount,
            leverageAmount,
            loanTokenSent,
            collateralTokenSent,
            tradeTokenSent,
            trader,
            depositTokenAddress,
            collateralTokenAddress,
            tradeTokenAddress,
            "" // loanData
        );
    }

    function marginTradeFromDeposit(
        uint256 depositAmount,
        uint256 leverageAmount,
        uint256 loanTokenSent,
        uint256 collateralTokenSent,
        uint256 tradeTokenSent,
        address trader,
        address depositTokenAddress,
        address collateralTokenAddress,
        address tradeTokenAddress,
        bytes memory loanData)
        public
        returns (bytes32 loanOrderHash)
    {
        return _marginTradeFromDeposit(
            depositAmount,
            leverageAmount,
            loanTokenSent,
            collateralTokenSent,
            tradeTokenSent,
            trader,
            depositTokenAddress,
            collateralTokenAddress,
            tradeTokenAddress,
            loanData
        );
    }

    // Called by pTokens to borrow and immediately get into a positions
    // Other traders can call this, but it's recommended to instead use borrowTokenAndUse(...) instead
    // assumption: depositAmount is collateral + interest deposit and will be denominated in deposit token
    // assumption: loan token and interest token are the same
    // returns loanOrderHash for the base protocol loan
    function _marginTradeFromDeposit(
        uint256 depositAmount,
        uint256 leverageAmount,
        uint256 loanTokenSent,
        uint256 collateralTokenSent,
        uint256 tradeTokenSent,
        address trader,
        address depositTokenAddress,
        address collateralTokenAddress,
        address tradeTokenAddress,
        bytes memory loanData)
        internal
        nonReentrant
        returns (bytes32 loanOrderHash)
    {
        require(tradeTokenAddress != address(0) &&
            tradeTokenAddress != loanTokenAddress,
            "10"
        );

        uint256 amount = depositAmount;
        // To calculate borrow amount and interest owed to lender we need deposit amount to be represented as loan token
        if (depositTokenAddress == tradeTokenAddress) {
            (,,amount) = IBZxOracle(bZxOracle).getTradeData(
                tradeTokenAddress,
                loanTokenAddress,
                amount
            );
        } else if (depositTokenAddress != loanTokenAddress) {
            // depositTokenAddress can only be tradeTokenAddress or loanTokenAddress
            revert("11");
        }

        loanOrderHash = _borrowTokenAndUse(
            leverageAmount,
            [
                trader,
                collateralTokenAddress,     // collateralTokenAddress
                tradeTokenAddress          // tradeTokenAddress
            ],
            [
                0,                      // interestRate (found later)
                amount,                 // amount of deposit
                0,                      // interestInitialAmount (interest is calculated based on fixed-term loan)
                loanTokenSent,
                collateralTokenSent,
                tradeTokenSent,
                0
            ],
            true,                        // amountIsADeposit
            loanData
        );
    }


    // Claims owned loan token for the caller
    // Also claims for user with the longest reserves
    // returns amount claimed for the caller
    function claimLoanToken()
        external
        nonReentrant
        returns (uint256 claimedAmount)
    {
        claimedAmount = _claimLoanToken(msg.sender);

        if (burntTokenReserveList.length != 0) {
            _claimLoanToken(address(0));

            if (burntTokenReserveListIndex[msg.sender].isSet && nextOwedLender_ != msg.sender) {
                // ensure lender is paid next
                nextOwedLender_ = msg.sender;
            }
        }
    }

    function wrapEther()
        public
    {
        if (address(this).balance != 0) {
            WETHInterface(wethContract).deposit.value(address(this).balance)();
        }
    }

    // Sends non-LoanToken assets to the Oracle fund
    // These are assets that would otherwise be "stuck" due to a user accidently sending them to the contract
    function donateAsset(
        address tokenAddress)
        public
        returns (bool)
    {
        if (tokenAddress == loanTokenAddress)
            return false;

        uint256 balance = ERC20(tokenAddress).balanceOf(address(this));
        if (balance == 0)
            return false;

        require(ERC20(tokenAddress).transfer(
            IBZx(bZxContract).oracleAddresses(bZxOracle),
            balance
        ), "12");

        return true;
    }

    function transfer(
        address _to,
        uint256 _value)
        public
        returns (bool)
    {
        require(_value <= balances[msg.sender], "insufficient balance");
        require(_to != address(0), "13");

        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[_to] = balances[_to].add(_value);

        // handle checkpoint update
        uint256 currentPrice = tokenPrice();
        if (burntTokenReserveListIndex[msg.sender].isSet || balances[msg.sender] != 0) {
            checkpointPrices_[msg.sender] = currentPrice;
        } else {
            checkpointPrices_[msg.sender] = 0;
        }
        if (burntTokenReserveListIndex[_to].isSet || balances[_to] != 0) {
            checkpointPrices_[_to] = currentPrice;
        } else {
            checkpointPrices_[_to] = 0;
        }

        emit Transfer(msg.sender, _to, _value);
        return true;
    }

    function transferFrom(
        address _from,
        address _to,
        uint256 _value)
        public
        returns (bool)
    {
        uint256 allowanceAmount = allowed[_from][msg.sender];
        require(_value <= balances[_from], "14");
        require(_value <= allowanceAmount, "15");
        require(_to != address(0), "16");

        balances[_from] = balances[_from].sub(_value);
        balances[_to] = balances[_to].add(_value);
        if (allowanceAmount < MAX_UINT) {
            allowed[_from][msg.sender] = allowanceAmount.sub(_value);
        }

        // handle checkpoint update
        uint256 currentPrice = tokenPrice();
        if (burntTokenReserveListIndex[_from].isSet || balances[_from] != 0) {
            checkpointPrices_[_from] = currentPrice;
        } else {
            checkpointPrices_[_from] = 0;
        }
        if (burntTokenReserveListIndex[_to].isSet || balances[_to] != 0) {
            checkpointPrices_[_to] = currentPrice;
        } else {
            checkpointPrices_[_to] = 0;
        }

        emit Transfer(_from, _to, _value);
        return true;
    }


    /* Public View functions */

    function tokenPrice()
        public
        view
        returns (uint256 price)
    {
        uint256 interestUnPaid;
        if (lastSettleTime_ != block.timestamp) {
            (,,interestUnPaid) = _getAllInterest();

            interestUnPaid = interestUnPaid
                .mul(spreadMultiplier)
                .div(10**20);
        }

        return _tokenPrice(_totalAssetSupply(interestUnPaid));
    }

    function checkpointPrice(
        address _user)
        public
        view
        returns (uint256 price)
    {
        return checkpointPrices_[_user];
    }

    function totalReservedSupply()
        public
        view
        returns (uint256)
    {
        return burntTokenReserved.mul(tokenPrice()).div(10**18);
    }

    function marketLiquidity()
        public
        view
        returns (uint256)
    {
        uint256 totalSupply = totalAssetSupply();
        uint256 reservedSupply = totalReservedSupply();
        if (totalSupply > reservedSupply) {
            totalSupply = totalSupply.sub(reservedSupply);
        } else {
            return 0;
        }

        if (totalSupply > totalAssetBorrow) {
            return totalSupply.sub(totalAssetBorrow);
        } else {
            return 0;
        }
    }

    // interest that lenders are currently receiving for open loans, prior to any fees
    function supplyInterestRate()
        public
        view
        returns (uint256)
    {
        if (totalAssetBorrow != 0) {
            return _supplyInterestRate(totalAssetSupply());
        }
    }

    // the average interest that borrowers are currently paying for open loans, prior to any fees
    function avgBorrowInterestRate()
        public
        view
        returns (uint256)
    {
        if (totalAssetBorrow != 0) {
            return _protocolInterestRate(totalAssetSupply());
        } else {
            return _getLowUtilBaseRate();
        }
    }

    // the base rate the next base protocol borrower will receive for variable-rate loans
    function borrowInterestRate()
        public
        view
        returns (uint256)
    {
        return _nextBorrowInterestRate(
            0,              // borrowAmount
            false           // useFixedInterestModel
        );
    }

    // the rate the next base protocol borrower will receive based on the amount being borrowed for variable-rate loans
    function nextBorrowInterestRate(
        uint256 borrowAmount)
        public
        view
        returns (uint256)
    {
        return _nextBorrowInterestRate(
            borrowAmount,   // borrowAmount
            false           // useFixedInterestModel
        );
    }

    function nextBorrowInterestRateWithOption(
        uint256 borrowAmount,
        bool useFixedInterestModel)
        public
        view
        returns (uint256)
    {
        return _nextBorrowInterestRate(
            borrowAmount,   // borrowAmount
            useFixedInterestModel
        );
    }

    function nextSupplyInterestRate(
        uint256 supplyAmount)
        public
        view
        returns (uint256)
    {
        if (totalAssetBorrow != 0) {
            return _supplyInterestRate(totalAssetSupply().add(supplyAmount));
        }
    }

    function totalAssetSupply()
        public
        view
        returns (uint256)
    {
        uint256 interestUnPaid;
        if (lastSettleTime_ != block.timestamp) {
            (,,interestUnPaid) = _getAllInterest();

            interestUnPaid = interestUnPaid
                .mul(spreadMultiplier)
                .div(10**20);
        }

        return _totalAssetSupply(interestUnPaid);
    }

    function getMaxEscrowAmount(
        uint256 leverageAmount)
        public
        view
        returns (uint256)
    {
        LoanData memory loanData = loanOrderData[loanOrderHashes[leverageAmount]];
        if (loanData.initialMarginAmount == 0)
            return 0;

        return marketLiquidity()
            .mul(loanData.initialMarginAmount)
            .div(_adjustValue(
                10**20, // maximum possible interest (100%)
                loanData.maxDurationUnixTimestampSec,
                loanData.initialMarginAmount));
    }

    function getLeverageList()
        public
        view
        returns (uint256[] memory)
    {
        return leverageList;
    }

    // returns the user's balance of underlying token
    function assetBalanceOf(
        address _owner)
        public
        view
        returns (uint256)
    {
        return balanceOf(_owner)
            .mul(tokenPrice())
            .div(10**18);
    }

    function getDepositAmountForBorrow(
        uint256 borrowAmount,
        uint256 leverageAmount,             // use 2000000000000000000 for 150% initial margin
        uint256 initialLoanDuration,        // duration in seconds
        address collateralTokenAddress)     // address(0) means ETH
        public
        view
        returns (uint256 depositAmount)
    {
        if (borrowAmount != 0) {
            uint256 marginAmount = loanOrderData[loanOrderHashes[leverageAmount]].initialMarginAmount
                .add(10**20); // adjust for over-collateralized loan

            // adjust value since interest is also borrowed
            borrowAmount = borrowAmount
                .mul(_getTargetNextRateMultiplierValue(initialLoanDuration))
                .div(10**22);

            borrowAmount = _verifyBorrowAmount(borrowAmount);
            if (borrowAmount == 0) {
                return 0;
            }

            return IBZx(bZxContract).getRequiredCollateral(
                loanTokenAddress,
                collateralTokenAddress != address(0) ? collateralTokenAddress : wethContract,
                bZxOracle,
                borrowAmount,
                marginAmount
            ).add(10); // add some dust to ensure enough is borrowed later
        } else {
            return 0;
        }
    }

    function getBorrowAmountForDeposit(
        uint256 depositAmount,
        uint256 leverageAmount,             // use 2000000000000000000 for 150% initial margin
        uint256 initialLoanDuration,        // duration in seconds
        address collateralTokenAddress)     // address(0) means ETH
        public
        view
        returns (uint256 borrowAmount)
    {
        borrowAmount = _getBorrowAmountForDeposit(
            depositAmount,
            leverageAmount,
            initialLoanDuration,
            collateralTokenAddress
        );
    }

    /* Internal functions */

    function _mintToken(
        address receiver,
        uint256 depositAmount)
        internal
        returns (uint256 mintAmount)
    {
        require (depositAmount != 0, "17");

        if (burntTokenReserveList.length != 0) {
            _claimLoanToken(address(0));
            _claimLoanToken(receiver);
            if (msg.sender != receiver)
                _claimLoanToken(msg.sender);
        } else {
            _settleInterest();
        }

        uint256 currentPrice = _tokenPrice(_totalAssetSupply(0));
        mintAmount = depositAmount.mul(10**18).div(currentPrice);

        if (msg.value == 0) {
            require(ERC20(loanTokenAddress).transferFrom(
                msg.sender,
                address(this),
                depositAmount
            ), "18");
        } else {
            WETHInterface(wethContract).deposit.value(depositAmount)();
        }

        _mint(receiver, mintAmount, depositAmount, currentPrice);

        checkpointPrices_[receiver] = currentPrice;
    }

    function _burnToken(
        address receiver,
        uint256 burnAmount)
        internal
        returns (uint256 loanAmountPaid)
    {
        require(burnAmount != 0, "19");

        if (burnAmount > balanceOf(msg.sender)) {
            burnAmount = balanceOf(msg.sender);
        }

        if (burntTokenReserveList.length != 0) {
            _claimLoanToken(address(0));
            _claimLoanToken(receiver);
            if (msg.sender != receiver)
                _claimLoanToken(msg.sender);
        } else {
            _settleInterest();
        }

        uint256 currentPrice = _tokenPrice(_totalAssetSupply(0));

        uint256 loanAmountOwed = burnAmount.mul(currentPrice).div(10**18);
        uint256 loanAmountAvailableInContract = ERC20(loanTokenAddress).balanceOf(address(this));

        loanAmountPaid = loanAmountOwed;
        if (loanAmountPaid > loanAmountAvailableInContract) {
            uint256 reserveAmount = loanAmountPaid.sub(loanAmountAvailableInContract);
            uint256 reserveTokenAmount = reserveAmount.mul(10**18).div(currentPrice);

            burntTokenReserved = burntTokenReserved.add(reserveTokenAmount);
            if (burntTokenReserveListIndex[receiver].isSet) {
                uint256 index = burntTokenReserveListIndex[receiver].index;
                burntTokenReserveList[index].amount = burntTokenReserveList[index].amount.add(reserveTokenAmount);
            } else {
                burntTokenReserveList.push(TokenReserves({
                    lender: receiver,
                    amount: reserveTokenAmount
                }));
                burntTokenReserveListIndex[receiver] = ListIndex({
                    index: burntTokenReserveList.length-1,
                    isSet: true
                });
            }

            loanAmountPaid = loanAmountAvailableInContract;
        }

        _burn(msg.sender, burnAmount, loanAmountPaid, currentPrice);

        if (burntTokenReserveListIndex[msg.sender].isSet || balances[msg.sender] != 0) {
            checkpointPrices_[msg.sender] = currentPrice;
        } else {
            checkpointPrices_[msg.sender] = 0;
        }
    }

    function _settleInterest()
        internal
    {
        if (lastSettleTime_ != block.timestamp) {
            (bool success,) = bZxContract.call.gas(gasleft())(
                abi.encodeWithSignature(
                    "payInterestForOracle(address,address)",
                    bZxOracle, // (leave as original value)
                    loanTokenAddress // same as interestTokenAddress
                )
            );
            success;
            lastSettleTime_ = block.timestamp;
        }
    }

    function _getBorrowAmountForDeposit(
        uint256 depositAmount,
        uint256 leverageAmount,             // use 2000000000000000000 for 150% initial margin
        uint256 initialLoanDuration,        // duration in seconds
        address collateralTokenAddress)     // address(0) means ETH
        internal
        view
        returns (uint256 borrowAmount)
    {
        if (depositAmount != 0) {
            uint256 marginAmount = loanOrderData[loanOrderHashes[leverageAmount]].initialMarginAmount
                .add(10**20); // adjust for over-collateralized loan

            borrowAmount = IBZx(bZxContract).getBorrowAmount(
                loanTokenAddress,
                collateralTokenAddress != address(0) ? collateralTokenAddress : wethContract,
                bZxOracle,
                depositAmount,
                marginAmount
            );

            // adjust value since interest is also borrowed
            borrowAmount = borrowAmount
                .mul(10**22)
                .div(_getTargetNextRateMultiplierValue(initialLoanDuration));

            borrowAmount = _verifyBorrowAmount(borrowAmount);
        }
    }

    function _getTargetNextRateMultiplierValue(
        uint256 initialLoanDuration)
        internal
        view
        returns (uint256)
    {
        return rateMultiplier
            .mul(80 ether)
            .div(10**20)
            .add(baseRate)
            .mul(initialLoanDuration)
            .div(315360) // 365 * 86400 / 100
            .add(10**22);
    }

    function _getInterestRateAndAmount(
        uint256 borrowAmount,
        uint256 assetSupply,
        uint256 initialLoanDuration,        // duration in seconds
        bool useFixedInterestModel)         // False=variable interest, True=fixed interest
        internal
        view
        returns (uint256 interestRate, uint256 interestInitialAmount, uint256 newBorrowAmount)
    {
        (,interestInitialAmount) = _getInterestRateAndAmount2(
            borrowAmount,
            assetSupply,
            initialLoanDuration,
            useFixedInterestModel
        );

        (interestRate, interestInitialAmount) = _getInterestRateAndAmount2(
            borrowAmount
                .add(interestInitialAmount),
            assetSupply,
            initialLoanDuration,
            useFixedInterestModel
        );

        newBorrowAmount = borrowAmount
            .add(interestInitialAmount);
    }

    function _getInterestRateAndAmount2(
        uint256 borrowAmount,
        uint256 assetSupply,
        uint256 initialLoanDuration,
        bool useFixedInterestModel)
        internal
        view
        returns (uint256 interestRate, uint256 interestInitialAmount)
    {
        interestRate = _nextBorrowInterestRate2(
            borrowAmount,
            assetSupply,
            useFixedInterestModel
        );

        // initial interestInitialAmount
        interestInitialAmount = borrowAmount
            .mul(interestRate)
            .mul(initialLoanDuration)
            .div(31536000 * 10**20); // 365 * 86400 * 10**20
    }

    function _getNextOwed()
        internal
        view
        returns (address)
    {
        if (nextOwedLender_ != address(0))
            return nextOwedLender_;
        else if (burntTokenReserveList.length != 0)
            return burntTokenReserveList[0].lender;
        else
            return address(0);
    }

    function _claimLoanToken(
        address lender)
        internal
        returns (uint256)
    {
        _settleInterest();

        if (lender == address(0))
            lender = _getNextOwed();

        if (!burntTokenReserveListIndex[lender].isSet)
            return 0;

        uint256 index = burntTokenReserveListIndex[lender].index;
        uint256 currentPrice = _tokenPrice(_totalAssetSupply(0));

        uint256 claimAmount = burntTokenReserveList[index].amount.mul(currentPrice).div(10**18);
        if (claimAmount == 0)
            return 0;

        uint256 availableAmount = ERC20(loanTokenAddress).balanceOf(address(this));
        if (availableAmount == 0) {
            return 0;
        }

        uint256 claimTokenAmount;
        if (claimAmount <= availableAmount) {
            claimTokenAmount = burntTokenReserveList[index].amount;
            _removeFromList(lender, index);
        } else {
            claimAmount = availableAmount;
            claimTokenAmount = claimAmount.mul(10**18).div(currentPrice);

            // prevents less than 10 being left in burntTokenReserveList[index].amount
            if (claimTokenAmount.add(10) < burntTokenReserveList[index].amount) {
                burntTokenReserveList[index].amount = burntTokenReserveList[index].amount.sub(claimTokenAmount);
            } else {
                _removeFromList(lender, index);
            }
        }

        require(ERC20(loanTokenAddress).transfer(
            lender,
            claimAmount
        ), "20");

        if (burntTokenReserveListIndex[lender].isSet || balances[lender] != 0) {
            checkpointPrices_[lender] = currentPrice;
        } else {
            checkpointPrices_[lender] = 0;
        }

        burntTokenReserved = burntTokenReserved > claimTokenAmount ?
            burntTokenReserved.sub(claimTokenAmount) :
            0;

        emit Claim(
            lender,
            claimTokenAmount,
            claimAmount,
            burntTokenReserveListIndex[lender].isSet ?
                burntTokenReserveList[burntTokenReserveListIndex[lender].index].amount :
                0,
            currentPrice
        );

        return claimAmount;
    }

    function _borrowTokenAndUse(
        uint256 leverageAmount,
        address[3] memory sentAddresses,
        uint256[7] memory sentAmounts,
        bool amountIsADeposit,
        bytes memory loanData)
        internal
        returns (bytes32 loanOrderHash)
    {
        require(sentAmounts[1] != 0, "21"); // amount

        loanOrderHash = loanOrderHashes[leverageAmount];
        require(loanOrderHash != 0, "22");

        _settleInterest();

        bool useFixedInterestModel = loanOrderData[loanOrderHash].maxDurationUnixTimestampSec == 0;

        if (amountIsADeposit) {
            (sentAmounts[1], sentAmounts[0]) = _getBorrowAmountAndRate( // borrowAmount, interestRate
                loanOrderHash,
                sentAmounts[1], // amount
                useFixedInterestModel
            );

            // update for borrowAmount
            sentAmounts[6] = sentAmounts[1]; // borrowAmount
        } else {
            // amount is borrow amount
            sentAmounts[0] = _nextBorrowInterestRate2( // interestRate
                sentAmounts[1], // amount
                _totalAssetSupply(0),
                useFixedInterestModel
            );
        }

        if (sentAddresses[2] == address(0)) { // tradeTokenAddress
            // tradeTokenSent is ignored if trade token isn't specified
            sentAmounts[5] = 0;
        }

        uint256 borrowAmount = _borrowTokenAndUseFinal(
            loanOrderHash,
            sentAddresses,
            sentAmounts,
            loanData
        );
        require(borrowAmount == sentAmounts[1], "23");
    }

    // returns borrowAmount
    function _borrowTokenAndUseFinal(
        bytes32 loanOrderHash,
        address[3] memory sentAddresses,
        uint256[7] memory sentAmounts,
        bytes memory loanData)
        internal
        returns (uint256)
    {
        sentAmounts[1] = _verifyBorrowAmount(sentAmounts[1]); // borrowAmount
        require (sentAmounts[1] != 0, "24");

        // handle transfers prior to adding borrowAmount to loanTokenSent
        _verifyTransfers(
            sentAddresses,
            sentAmounts
        );

        // adding the loan token amount from the lender to loanTokenSent
        sentAmounts[3] = sentAmounts[3]
            .add(sentAmounts[1]); // borrowAmount

        sentAmounts[1] = IBZx(bZxContract).takeOrderFromiToken( // borrowAmount
            loanOrderHash,
            sentAddresses,
            sentAmounts,
            loanData
        );
        require (sentAmounts[1] != 0, "25");

        // update total borrowed amount outstanding in loans
        totalAssetBorrow = totalAssetBorrow
            .add(sentAmounts[1]); // borrowAmount

        // checkpoint supply since the base protocol borrow stats have changed
        checkpointSupply = _totalAssetSupply(0);

        if (burntTokenReserveList.length != 0) {
            _claimLoanToken(address(0));
            _claimLoanToken(sentAddresses[0]); // borrower
        }

        emit Borrow(
            sentAddresses[0],               // borrower
            sentAmounts[1],                 // borrowAmount
            sentAmounts[0],                 // interestRate
            sentAddresses[1],               // collateralTokenAddress
            sentAddresses[2],               // tradeTokenAddress
            sentAddresses[2] == address(0)  // withdrawOnOpen
        );

        return sentAmounts[1]; // borrowAmount;
    }

    function _verifyBorrowAmount(
        uint256 borrowAmount)
        internal
        view
        returns (uint256)
    {
        uint256 availableToBorrow = ERC20(loanTokenAddress).balanceOf(address(this));
        if (availableToBorrow == 0)
            return 0;

        uint256 reservedSupply = totalReservedSupply();
        if (availableToBorrow > reservedSupply) {
            availableToBorrow = availableToBorrow.sub(reservedSupply);
        } else {
            return 0;
        }

        if (borrowAmount > availableToBorrow) {
            //return availableToBorrow;
            return 0;
        }

        return borrowAmount;
    }

    // sentAddresses[0]: borrower
    // sentAddresses[1]: collateralTokenAddress
    // sentAddresses[2]: tradeTokenAddress
    // sentAmounts[0]: interestRate
    // sentAmounts[1]: borrowAmount
    // sentAmounts[2]: interestInitialAmount
    // sentAmounts[3]: loanTokenSent
    // sentAmounts[4]: collateralTokenSent
    // sentAmounts[5]: tradeTokenSent
    // sentAmounts[6]: withdrawalAmount
    function _verifyTransfers(
        address[3] memory sentAddresses,
        uint256[7] memory sentAmounts)
        internal
    {
        address borrower = sentAddresses[0];
        address collateralTokenAddress = sentAddresses[1];
        address tradeTokenAddress = sentAddresses[2];
        uint256 borrowAmount = sentAmounts[1];
        uint256 loanTokenSent = sentAmounts[3];
        uint256 collateralTokenSent = sentAmounts[4];
        uint256 tradeTokenSent = sentAmounts[5];
        uint256 withdrawalAmount = sentAmounts[6];

        if (tradeTokenAddress == address(0)) { // withdrawOnOpen == true
            require(ERC20(loanTokenAddress).transfer(
                borrower,
                withdrawalAmount
            ), "26");

            if (borrowAmount > withdrawalAmount) {
                require(ERC20(loanTokenAddress).transfer(
                    bZxVault,
                    borrowAmount - withdrawalAmount
                ), "34");
            }
        } else {
            require(ERC20(loanTokenAddress).transfer(
                bZxVault,
                borrowAmount
            ), "27");
        }

        if (collateralTokenSent != 0) {
            if (msg.value != 0) {
                require(collateralTokenAddress == wethContract &&
                    collateralTokenSent == msg.value, "28");

                WETHInterface(wethContract).deposit.value(collateralTokenSent)();

                require(ERC20(collateralTokenAddress).transfer(
                    bZxVault,
                    collateralTokenSent
                ), "29");
            } else {
                if (collateralTokenAddress == loanTokenAddress) {
                    loanTokenSent = loanTokenSent.add(collateralTokenSent);
                } else if (collateralTokenAddress == tradeTokenAddress) {
                    tradeTokenSent = tradeTokenSent.add(collateralTokenSent);
                } else {
                    require(ERC20(collateralTokenAddress).transferFrom(
                        msg.sender,
                        bZxVault,
                        collateralTokenSent
                    ), "30");
                }
            }
        }

        if (loanTokenSent != 0) {
            if (loanTokenAddress == tradeTokenAddress) {
                tradeTokenSent = tradeTokenSent.add(loanTokenSent);
            } else {
                require(ERC20(loanTokenAddress).transferFrom(
                    msg.sender,
                    bZxVault,
                    loanTokenSent
                ), "31");
            }
        }

        if (tradeTokenSent != 0) {
            require(ERC20(tradeTokenAddress).transferFrom(
                msg.sender,
                bZxVault,
                tradeTokenSent
            ), "32");
        }
    }

    function _removeFromList(
        address lender,
        uint256 index)
        internal
    {
        // remove lender from burntToken list
        if (burntTokenReserveList.length > 1) {
            // replace item in list with last item in array
            burntTokenReserveList[index] = burntTokenReserveList[burntTokenReserveList.length - 1];

            // update the position of this replacement
            burntTokenReserveListIndex[burntTokenReserveList[index].lender].index = index;
        }

        // trim array and clear storage
        burntTokenReserveList.length--;
        burntTokenReserveListIndex[lender].index = 0;
        burntTokenReserveListIndex[lender].isSet = false;

        if (lender == nextOwedLender_) {
            nextOwedLender_ = address(0);
        }
    }


    /* Internal View functions */

    function _tokenPrice(
        uint256 assetSupply)
        internal
        view
        returns (uint256)
    {
        uint256 totalTokenSupply = totalSupply_.add(burntTokenReserved);

        return totalTokenSupply != 0 ?
            assetSupply
                .mul(10**18)
                .div(totalTokenSupply) : initialPrice;
    }

    function _protocolInterestRate(
        uint256 assetSupply)
        internal
        view
        returns (uint256)
    {
        uint256 interestRate;
        if (totalAssetBorrow != 0) {
            (,uint256 interestOwedPerDay,) = _getAllInterest();
            interestRate = interestOwedPerDay
                .mul(10**20)
                .div(totalAssetBorrow)
                .mul(365)
                .mul(checkpointSupply)
                .div(assetSupply);
        } else {
            interestRate = _getLowUtilBaseRate();
        }

        return interestRate;
    }

    // next supply interest adjustment
    function _supplyInterestRate(
        uint256 assetSupply)
        public
        view
        returns (uint256)
    {
        if (totalAssetBorrow != 0) {
            return _protocolInterestRate(assetSupply)
                .mul(_utilizationRate(assetSupply))
                .div(10**20);
        } else {
            return 0;
        }
    }

    function _nextBorrowInterestRate(
        uint256 borrowAmount,
        bool useFixedInterestModel)
        internal
        view
        returns (uint256)
    {
        uint256 interestUnPaid;
        if (borrowAmount != 0) {
            if (lastSettleTime_ != block.timestamp) {
                (,,interestUnPaid) = _getAllInterest();

                interestUnPaid = interestUnPaid
                    .mul(spreadMultiplier)
                    .div(10**20);
            }

            uint256 balance = ERC20(loanTokenAddress).balanceOf(address(this)).add(interestUnPaid);
            if (borrowAmount > balance) {
                borrowAmount = balance;
            }
        }

        return _nextBorrowInterestRate2(
            borrowAmount,
            _totalAssetSupply(interestUnPaid),
            useFixedInterestModel
        );
    }

    function _nextBorrowInterestRate2(
        uint256 newBorrowAmount,
        uint256 assetSupply,
        bool useFixedInterestModel)
        internal
        view
        returns (uint256 nextRate)
    {
        uint256 utilRate = _utilizationRate(assetSupply)
            .add(newBorrowAmount != 0 ?
                newBorrowAmount
                .mul(10**20)
                .div(assetSupply) : 0);

        uint256 minRate;
        uint256 maxRate;

        if (utilRate > 90 ether) {
            // scale rate proportionally up to 100%

            utilRate = utilRate.sub(90 ether);
            if (utilRate > 10 ether)
                utilRate = 10 ether;

            maxRate = rateMultiplier
                .add(baseRate)
                .mul(90)
                .div(100);

            nextRate = utilRate
                .mul(SafeMath.sub(100 ether, maxRate))
                .div(10 ether)
                .add(maxRate);
        } else {
            if (useFixedInterestModel && utilRate < 80 ether) {
                // target 80% utilization when loan is fixed-rate and utilization is under 80%
                utilRate = 80 ether;
            }

            if (utilRate >= 50 ether) {
                nextRate = utilRate
                    .mul(rateMultiplier)
                    .div(10**20)
                    .add(baseRate);

                minRate = baseRate;
                maxRate = rateMultiplier
                    .add(baseRate);
            } else {
                uint256 lowUtilBaseRate = _getLowUtilBaseRate();
                uint256 lowUtilRateMultiplier = _getLowUtilRateMultiplier();
                nextRate = utilRate
                    .mul(lowUtilRateMultiplier)
                    .div(10**20)
                    .add(lowUtilBaseRate);

                minRate = lowUtilBaseRate;
                maxRate = lowUtilRateMultiplier
                    .add(lowUtilBaseRate);
            }

            if (nextRate < minRate)
                nextRate = minRate;
            else if (nextRate > maxRate)
                nextRate = maxRate;
        }

        return nextRate;
    }

    function _getAllInterest()
        internal
        view
        returns (
            uint256 interestPaidSoFar,
            uint256 interestOwedPerDay,
            uint256 interestUnPaid)
    {
        // these values don't account for any fees retained by the oracle, so we account for it elsewhere with spreadMultiplier
        (interestPaidSoFar,,interestOwedPerDay,interestUnPaid) = IBZx(bZxContract).getLenderInterestForOracle(
            address(this),
            bZxOracle, // (leave as original value)
            loanTokenAddress // same as interestTokenAddress
        );
    }

    function _getBorrowAmountAndRate(
        bytes32 loanOrderHash,
        uint256 depositAmount,
        bool useFixedInterestModel)
        internal
        view
        returns (uint256 borrowAmount, uint256 interestRate)
    {
        LoanData memory loanData = loanOrderData[loanOrderHash];
        require(loanData.initialMarginAmount != 0, "33");

        interestRate = _nextBorrowInterestRate2(
            depositAmount
                .mul(10**20)
                .div(loanData.initialMarginAmount),
            totalAssetSupply(),
            useFixedInterestModel
        );

        // assumes that loan, collateral, and interest token are the same
        borrowAmount = depositAmount
            .mul(10**40)
            .div(_adjustValue(
                interestRate,
                loanData.maxDurationUnixTimestampSec,
                loanData.initialMarginAmount))
            .div(loanData.initialMarginAmount);
    }

    function _adjustValue(
        uint256 interestRate,
        uint256 maxDuration,
        uint256 marginAmount)
        internal
        pure
        returns (uint256)
    {
        return maxDuration != 0 ?
            interestRate
                .mul(10**20)
                .div(31536000) // 86400 * 365
                .mul(maxDuration)
                .div(marginAmount)
                .add(10**20) :
            10**20;
    }

    function _utilizationRate(
        uint256 assetSupply)
        internal
        view
        returns (uint256)
    {
        if (totalAssetBorrow != 0 && assetSupply != 0) {
            // U = total_borrow / total_supply
            return totalAssetBorrow
                .mul(10**20)
                .div(assetSupply);
        } else {
            return 0;
        }
    }

    function _totalAssetSupply(
        uint256 interestUnPaid)
        internal
        view
        returns (uint256 assetSupply)
    {
        if (totalSupply_.add(burntTokenReserved) != 0) {
            return ERC20(loanTokenAddress).balanceOf(address(this))
                .add(totalAssetBorrow)
                .add(interestUnPaid);
        }
    }

    function _getLowUtilBaseRate()
        internal
        view
        returns (uint256 lowUtilBaseRate)
    {
        //keccak256("iToken_LowUtilBaseRate")
        assembly {
            lowUtilBaseRate := sload(0x3d82e958c891799f357c1316ae5543412952ae5c423336f8929ed7458039c995)
        }
    }
    function _getLowUtilRateMultiplier()
        internal
        view
        returns (uint256 lowUtilRateMultiplier)
    {
        //keccak256("iToken_LowUtilRateMultiplier")
        assembly {
            lowUtilRateMultiplier := sload(0x2b4858b1bc9e2d14afab03340ce5f6c81b703c86a0c570653ae586534e095fb1)
        }
    }

    /* Oracle-Only functions */

    // called only by BZxOracle when a loan is partially or fully closed
    function closeLoanNotifier(
        BZxObjects.LoanOrder memory loanOrder,
        BZxObjects.LoanPosition memory loanPosition,
        address loanCloser,
        uint256 closeAmount,
        bool isLiquidation)
        public
        onlyOracle
        returns (bool)
    {
        LoanData memory loanData = loanOrderData[loanOrder.loanOrderHash];
        if (loanData.loanOrderHash == loanOrder.loanOrderHash) {

            totalAssetBorrow = totalAssetBorrow > closeAmount ?
                totalAssetBorrow.sub(closeAmount) : 0;

            emit Repay(
                loanOrder.loanOrderHash,    // loanOrderHash
                loanPosition.trader,        // borrower
                loanCloser,                 // closer
                closeAmount,                // amount
                isLiquidation               // isLiquidation
            );

            if (burntTokenReserveList.length != 0) {
                _claimLoanToken(address(0));
            } else {
                _settleInterest();
            }

            if (closeAmount == 0)
                return true;

            // checkpoint supply since the base protocol borrow stats have changed
            checkpointSupply = _totalAssetSupply(0);

            if (loanCloser != loanPosition.trader) {
                if (iTokenizedRegistry(tokenizedRegistry).isTokenType(
                    loanPosition.trader,
                    2 // tokenType=pToken
                )) {
                    (bool success,) = loanPosition.trader.call(
                        abi.encodeWithSignature(
                            "triggerPosition(bool)",
                            true // openPosition
                        )
                    );
                    success;
                }
            }

            return true;
        } else {
            return false;
        }
    }


    /* Owner-Only functions */

    function updateSettings(
        address settingsTarget,
        bytes memory txnData)
        public
        onlyOwner
    {
        address currentTarget = target_;
        target_ = settingsTarget;

        (bool result,) = address(this).call(txnData);

        uint256 size;
        uint256 ptr;
        assembly {
            size := returndatasize
            ptr := mload(0x40)
            returndatacopy(ptr, 0, size)
            if eq(result, 0) { revert(ptr, size) }
        }

        target_ = currentTarget;

        assembly {
            return(ptr, size)
        }
    }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"assetBalanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"claimLoanToken","outputs":[{"name":"claimedAmount","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"supplyInterestRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"burntTokenReserved","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"depositAmount","type":"uint256"},{"name":"leverageAmount","type":"uint256"},{"name":"loanTokenSent","type":"uint256"},{"name":"collateralTokenSent","type":"uint256"},{"name":"tradeTokenSent","type":"uint256"},{"name":"trader","type":"address"},{"name":"depositTokenAddress","type":"address"},{"name":"collateralTokenAddress","type":"address"},{"name":"tradeTokenAddress","type":"address"},{"name":"loanData","type":"bytes"}],"name":"marginTradeFromDeposit","outputs":[{"name":"loanOrderHash","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"initialPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"baseRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalAssetBorrow","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"depositAmount","type":"uint256"},{"name":"leverageAmount","type":"uint256"},{"name":"initialLoanDuration","type":"uint256"},{"name":"collateralTokenAddress","type":"address"}],"name":"getBorrowAmountForDeposit","outputs":[{"name":"borrowAmount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"loanOrderData","outputs":[{"name":"loanOrderHash","type":"bytes32"},{"name":"leverageAmount","type":"uint256"},{"name":"initialMarginAmount","type":"uint256"},{"name":"maintenanceMarginAmount","type":"uint256"},{"name":"maxDurationUnixTimestampSec","type":"uint256"},{"name":"index","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"settingsTarget","type":"address"},{"name":"txnData","type":"bytes"}],"name":"updateSettings","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getLeverageList","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"rateMultiplier","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"receiver","type":"address"},{"name":"depositAmount","type":"uint256"}],"name":"mint","outputs":[{"name":"mintAmount","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"avgBorrowInterestRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"wethContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"borrowAmount","type":"uint256"},{"name":"leverageAmount","type":"uint256"},{"name":"initialLoanDuration","type":"uint256"},{"name":"collateralTokenSent","type":"uint256"},{"name":"borrower","type":"address"},{"name":"collateralTokenAddress","type":"address"},{"name":"loanData","type":"bytes"}],"name":"borrowTokenFromDeposit","outputs":[{"name":"loanOrderHash","type":"bytes32"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"tokenAddress","type":"address"}],"name":"donateAsset","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"marketLiquidity","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalReservedSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"wrapEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenizedRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"burntTokenReserveList","outputs":[{"name":"lender","type":"address"},{"name":"amount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"loanTokenAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"checkpointSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"borrowAmount","type":"uint256"},{"name":"useFixedInterestModel","type":"bool"}],"name":"nextBorrowInterestRateWithOption","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenPrice","outputs":[{"name":"price","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"receiver","type":"address"},{"name":"burnAmount","type":"uint256"}],"name":"burnToEther","outputs":[{"name":"loanAmountPaid","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"leverageAmount","type":"uint256"}],"name":"getMaxEscrowAmount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"borrowInterestRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"borrowAmount","type":"uint256"},{"name":"leverageAmount","type":"uint256"},{"name":"initialLoanDuration","type":"uint256"},{"name":"collateralTokenAddress","type":"address"}],"name":"getDepositAmountForBorrow","outputs":[{"name":"depositAmount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bZxVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"receiver","type":"address"}],"name":"mintWithEther","outputs":[{"name":"mintAmount","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"totalAssetSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bZxOracle","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bZxContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"leverageList","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"borrowAmount","type":"uint256"},{"name":"leverageAmount","type":"uint256"},{"name":"interestInitialAmount","type":"uint256"},{"name":"loanTokenSent","type":"uint256"},{"name":"collateralTokenSent","type":"uint256"},{"name":"tradeTokenSent","type":"uint256"},{"name":"borrower","type":"address"},{"name":"collateralTokenAddress","type":"address"},{"name":"tradeTokenAddress","type":"address"},{"name":"loanData","type":"bytes"}],"name":"borrowTokenAndUse","outputs":[{"name":"loanOrderHash","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"receiver","type":"address"},{"name":"burnAmount","type":"uint256"}],"name":"burn","outputs":[{"name":"loanAmountPaid","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"borrowAmount","type":"uint256"}],"name":"nextBorrowInterestRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"components":[{"name":"loanTokenAddress","type":"address"},{"name":"interestTokenAddress","type":"address"},{"name":"collateralTokenAddress","type":"address"},{"name":"oracleAddress","type":"address"},{"name":"loanTokenAmount","type":"uint256"},{"name":"interestAmount","type":"uint256"},{"name":"initialMarginAmount","type":"uint256"},{"name":"maintenanceMarginAmount","type":"uint256"},{"name":"maxDurationUnixTimestampSec","type":"uint256"},{"name":"loanOrderHash","type":"bytes32"}],"name":"loanOrder","type":"tuple"},{"components":[{"name":"trader","type":"address"},{"name":"collateralTokenAddressFilled","type":"address"},{"name":"positionTokenAddressFilled","type":"address"},{"name":"loanTokenAmountFilled","type":"uint256"},{"name":"loanTokenAmountUsed","type":"uint256"},{"name":"collateralTokenAmountFilled","type":"uint256"},{"name":"positionTokenAmountFilled","type":"uint256"},{"name":"loanStartUnixTimestampSec","type":"uint256"},{"name":"loanEndUnixTimestampSec","type":"uint256"},{"name":"active","type":"bool"},{"name":"positionId","type":"uint256"}],"name":"loanPosition","type":"tuple"},{"name":"loanCloser","type":"address"},{"name":"closeAmount","type":"uint256"},{"name":"isLiquidation","type":"bool"}],"name":"closeLoanNotifier","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"supplyAmount","type":"uint256"}],"name":"nextSupplyInterestRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"spreadMultiplier","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_user","type":"address"}],"name":"checkpointPrice","outputs":[{"name":"price","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"assetSupply","type":"uint256"}],"name":"_supplyInterestRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"burntTokenReserveListIndex","outputs":[{"name":"index","type":"uint256"},{"name":"isSet","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"loanOrderHashes","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"depositAmount","type":"uint256"},{"name":"leverageAmount","type":"uint256"},{"name":"loanTokenSent","type":"uint256"},{"name":"collateralTokenSent","type":"uint256"},{"name":"tradeTokenSent","type":"uint256"},{"name":"trader","type":"address"},{"name":"depositTokenAddress","type":"address"},{"name":"collateralTokenAddress","type":"address"},{"name":"tradeTokenAddress","type":"address"}],"name":"marginTradeFromDeposit","outputs":[{"name":"loanOrderHash","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"minter","type":"address"},{"indexed":false,"name":"tokenAmount","type":"uint256"},{"indexed":false,"name":"assetAmount","type":"uint256"},{"indexed":false,"name":"price","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"burner","type":"address"},{"indexed":false,"name":"tokenAmount","type":"uint256"},{"indexed":false,"name":"assetAmount","type":"uint256"},{"indexed":false,"name":"price","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"borrower","type":"address"},{"indexed":false,"name":"borrowAmount","type":"uint256"},{"indexed":false,"name":"interestRate","type":"uint256"},{"indexed":false,"name":"collateralTokenAddress","type":"address"},{"indexed":false,"name":"tradeTokenToFillAddress","type":"address"},{"indexed":false,"name":"withdrawOnOpen","type":"bool"}],"name":"Borrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"loanOrderHash","type":"bytes32"},{"indexed":true,"name":"borrower","type":"address"},{"indexed":false,"name":"closer","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"isLiquidation","type":"bool"}],"name":"Repay","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"claimant","type":"address"},{"indexed":false,"name":"tokenAmount","type":"uint256"},{"indexed":false,"name":"assetAmount","type":"uint256"},{"indexed":false,"name":"remainingTokenAmount","type":"uint256"},{"indexed":false,"name":"price","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]

608060405260016000819055600a805460ff19169055670de0b6b3a7640000600b556801043561a882930000600c5580546001600160a01b03191633179055615f048061004d6000396000f3fe60806040526004361061038c5760003560e01c8063797bf385116101dc5780639b3a54d111610102578063d84d2a47116100a0578063f468697e1161006f578063f468697e146109cd578063fbd9574d146109ed578063fe05634214610a1b578063fecb8da314610a3b5761038c565b8063d84d2a4714610958578063dd62ed3e1461096d578063eebc50811461098d578063f2fde38b146109ad5761038c565b8063a9059cbb116100dc578063a9059cbb146108d8578063b9fe1a8f146108f8578063cd4fa66d14610918578063d65a5021146109385761038c565b80639b3a54d1146108785780639d6bd0f2146108985780639dc29fac146108b85761038c565b80638423acd61161017a5780638fb807c5116101495780638fb807c51461082457806395d89b411461083957806396c7871b1461084e578063995363d3146108635761038c565b80638423acd6146107c7578063894ca308146107e75780638da5cb5b146107fc5780638f6ede1f146108115761038c565b80637ff9b596116101b65780637ff9b5961461075d57806381a6b25014610772578063829b38f4146107925780638325a1c0146107b25761038c565b8063797bf385146107135780637b7933b4146107285780637d90dcba1461073d5761038c565b8063284e2f56116102c157806347e917e71161025f5780636f1296d21161022e5780636f1296d21461069b57806370a08231146106b0578063736ee3d3146106d05780637866c6c1146106e55761038c565b806347e917e71461063e57806359e239af14610651578063612ef80b14610671578063674d13c8146106865761038c565b8063330691ac1161029b578063330691ac146105d257806340c10f19146105e757806344a4a003146106075780634780eac11461061c5761038c565b8063284e2f561461056e5780632ecae90a1461058e578063313ce567146105b05761038c565b80631c5d1da51161032e57806320f6d07c1161030857806320f6d07c146104e757806323b872dd146104fc57806324d25f4a1461051c5780632515aacd1461053c5761038c565b80631c5d1da51461049d5780631d0806ae146104bd5780631f68f20a146104d25761038c565b8063095ea7b31161036a578063095ea7b31461043157806309ec6b6b1461045e5780630c4925fd1461047357806318160ddd146104885761038c565b806306b3efd6146103c457806306fdde03146103fa578063087fc48b1461041c575b6007546001600160a01b031633146103c257604051600160e51b62461bcd0281526004016103b990615c02565b60405180910390fd5b005b3480156103d057600080fd5b506103e46103df366004614a7d565b610a5b565b6040516103f1919061599d565b60405180910390f35b34801561040657600080fd5b5061040f610a9d565b6040516103f19190615a41565b34801561042857600080fd5b506103e4610b28565b34801561043d57600080fd5b5061045161044c366004614b88565b610bc0565b6040516103f1919061598f565b34801561046a57600080fd5b506103e4610c2b565b34801561047f57600080fd5b506103e4610c48565b34801561049457600080fd5b506103e4610c4e565b3480156104a957600080fd5b506103e46104b8366004614f2d565b610c54565b3480156104c957600080fd5b506103e4610c77565b3480156104de57600080fd5b506103e4610c7d565b3480156104f357600080fd5b506103e4610c83565b34801561050857600080fd5b50610451610517366004614af3565b610c89565b34801561052857600080fd5b506103e4610537366004614cff565b610f33565b34801561054857600080fd5b5061055c610557366004614bd6565b610f4a565b6040516103f1969594939291906159e7565b34801561057a57600080fd5b506103c2610589366004614b40565b610f7f565b34801561059a57600080fd5b506105a3611043565b6040516103f1919061597e565b3480156105bc57600080fd5b506105c561109b565b6040516103f19190615d7f565b3480156105de57600080fd5b506103e46110a4565b3480156105f357600080fd5b506103e4610602366004614b88565b6110aa565b34801561061357600080fd5b506103e46110ee565b34801561062857600080fd5b50610631611112565b6040516103f1919061582e565b6103e461064c366004614db5565b611121565b34801561065d57600080fd5b5061045161066c366004614a7d565b611355565b34801561067d57600080fd5b506103e4611536565b34801561069257600080fd5b506103e46115a0565b3480156106a757600080fd5b506103c26115c8565b3480156106bc57600080fd5b506103e46106cb366004614a7d565b611636565b3480156106dc57600080fd5b50610631611651565b3480156106f157600080fd5b50610705610700366004614bd6565b611665565b6040516103f192919061593b565b34801561071f57600080fd5b5061063161169a565b34801561073457600080fd5b506103e46116a9565b34801561074957600080fd5b506103e4610758366004614c8c565b6116af565b34801561076957600080fd5b506103e46116bb565b34801561077e57600080fd5b506103e461078d366004614b88565b611711565b34801561079e57600080fd5b506103e46107ad366004614bd6565b611872565b3480156107be57600080fd5b506103e4611917565b3480156107d357600080fd5b506103e46107e2366004614cff565b611924565b3480156107f357600080fd5b50610631611a87565b34801561080857600080fd5b50610631611a96565b6103e461081f366004614a7d565b611aa5565b34801561083057600080fd5b506103e4611b0e565b34801561084557600080fd5b5061040f611b56565b34801561085a57600080fd5b50610631611bb1565b34801561086f57600080fd5b50610631611bc0565b34801561088457600080fd5b506103e4610893366004614bd6565b611bd4565b3480156108a457600080fd5b506103e46108b336600461501e565b611bf2565b3480156108c457600080fd5b506103e46108d3366004614b88565b611d19565b3480156108e457600080fd5b506104516108f3366004614b88565b611dfd565b34801561090457600080fd5b506103e4610913366004614bd6565b611ff0565b34801561092457600080fd5b50610451610933366004614bf4565b611ffd565b34801561094457600080fd5b506103e4610953366004614bd6565b612339565b34801561096457600080fd5b506103e461235b565b34801561097957600080fd5b506103e4610988366004614ab9565b612361565b34801561099957600080fd5b506103e46109a8366004614a7d565b61238c565b3480156109b957600080fd5b506103c26109c8366004614a7d565b6123a7565b3480156109d957600080fd5b506103e46109e8366004614bd6565b6123ca565b3480156109f957600080fd5b50610a0d610a08366004614a7d565b612400565b6040516103f1929190615cd2565b348015610a2757600080fd5b506103e4610a36366004614bd6565b61241c565b348015610a4757600080fd5b506103e4610a56366004614e69565b61242e565b6000610a95670de0b6b3a7640000610a89610a746116bb565b610a7d86611636565b9063ffffffff61245f16565b9063ffffffff61248416565b90505b919050565b6002805460408051602060018416156101000260001901909316849004601f81018490048402820184019092528181529291830182828015610b205780601f10610af557610100808354040283529160200191610b20565b820191906000526020600020905b815481529060010190602001808311610b0357829003601f168201915b505050505081565b6000600160005414610b4f57604051600160e51b62461bcd0281526004016103b990615c72565b6002600055610b5d33612497565b60115490915015610bb857610b726000612497565b503360009081526012602052604090206001015460ff168015610ba057506014546001600160a01b03163314155b15610bb857601480546001600160a01b031916331790555b600160005590565b336000818152601a602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610c1990869061599d565b60405180910390a35060015b92915050565b6000601554600014610c4557610c426109e8611b0e565b90505b90565b60135481565b601b5490565b6000610c688b8b8b8b8b8b8b8b8b8b6128e9565b9b9a5050505050505050505050565b60185481565b600b5481565b60155481565b6001600160a01b0383166000818152601a602090815260408083203384528252808320549383526019909152812054909190831115610cdd57604051600160e51b62461bcd0281526004016103b990615ad2565b80831115610d0057604051600160e51b62461bcd0281526004016103b990615a82565b6001600160a01b038416610d2957604051600160e51b62461bcd0281526004016103b990615a92565b6001600160a01b038516600090815260196020526040902054610d52908463ffffffff612adc16565b6001600160a01b038087166000908152601960205260408082209390935590861681522054610d87908463ffffffff612aee16565b6001600160a01b038516600090815260196020526040902055600019811015610ddf57610dba818463ffffffff612adc16565b6001600160a01b0386166000908152601a602090815260408083203384529091529020555b6000610de96116bb565b6001600160a01b03871660009081526012602052604090206001015490915060ff1680610e2d57506001600160a01b03861660009081526019602052604090205415155b15610e52576001600160a01b0386166000908152600960205260409020819055610e6c565b6001600160a01b0386166000908152600960205260408120555b6001600160a01b03851660009081526012602052604090206001015460ff1680610ead57506001600160a01b03851660009081526019602052604090205415155b15610ed2576001600160a01b0385166000908152600960205260409020819055610eec565b6001600160a01b0385166000908152600960205260408120555b846001600160a01b0316866001600160a01b0316600080516020615eab83398151915286604051610f1d919061599d565b60405180910390a36001925050505b9392505050565b6000610f4185858585612afb565b95945050505050565b600f60205260009081526040902080546001820154600283015460038401546004850154600590950154939492939192909186565b6001546001600160a01b03163314610f9657600080fd5b601c80546001600160a01b038481166001600160a01b03198316179092556040519116906000903090610fca908590615817565b6000604051808303816000865af19150503d8060008114611007576040519150601f19603f3d011682016040523d82523d6000602084013e61100c565b606091505b50506040519091503d90816000823e82611024578181fd5b601c80546001600160a01b0319166001600160a01b0386161790558181f35b6060601080548060200260200160405190810160405280929190818152602001828054801561109157602002820191906000526020600020905b81548152602001906001019080831161107d575b5050505050905090565b60045460ff1681565b600c5481565b60006001600054146110d157604051600160e51b62461bcd0281526004016103b990615c72565b60026000556110e08383612c33565b90505b600160005592915050565b600060155460001461110a57610c42611105611b0e565b612e12565b610c42612e6b565b6007546001600160a01b031681565b600060016000541461114857604051600160e51b62461bcd0281526004016103b990615c72565b60026000553415801561116357506001600160a01b03831615155b801561116e57508415155b806111ab575034158015906111a157506001600160a01b03831615806111a157506007546001600160a01b038481169116145b80156111ab575084155b6111ca57604051600160e51b62461bcd0281526004016103b990615c82565b506000868152600e6020526040902054806111fa57604051600160e51b62461bcd0281526004016103b990615ab2565b611202612e90565b61120a614749565b6000828152600f6020526040902060040154153415611235576007543497506001600160a01b031694505b8961127457611246878a8a88612afb565b99508961126857604051600160e51b62461bcd0281526004016103b990615cc2565b60c082018a905261127c565b60c082018a90525b6112918a61128a6000612f56565b8a84612fb4565b60408581019290925291845280516060810182526001600160a01b0389811682528816602080830191909152600082840152825160e08101845286518152908101849052929c5061131b928692810186600260200201518152602001600081526020018b8152602001600081526020018660066007811061130e57fe5b6020020151905287613005565b60c083018190528a1461134357604051600160e51b62461bcd0281526004016103b990615c92565b50506001600055979650505050505050565b6008546000906001600160a01b038381169116141561137657506000610a98565b604051600160e01b6370a082310281526000906001600160a01b038416906370a08231906113a890309060040161583c565b60206040518083038186803b1580156113c057600080fd5b505afa1580156113d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113f89190810190614c6e565b905080611409576000915050610a98565b60048054600654604051600160e11b6338f5892f0281526001600160a01b038781169463a9059cbb9461010090048216936371eb125e9361144e93909116910161582e565b60206040518083038186803b15801561146657600080fd5b505afa15801561147a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061149e9190810190614a9b565b836040518363ffffffff1660e01b81526004016114bc92919061593b565b602060405180830381600087803b1580156114d657600080fd5b505af11580156114ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061150e9190810190614bb8565b61152d57604051600160e51b62461bcd0281526004016103b990615b52565b50600192915050565b600080611541611b0e565b9050600061154d6115a0565b90508082111561156e57611567828263ffffffff612adc16565b9150611579565b600092505050610c45565b60155482111561156e5760155461159790839063ffffffff612adc16565b92505050610c45565b6000610c42670de0b6b3a7640000610a896115b96116bb565b6013549063ffffffff61245f16565b3031156116345760075460408051600160e41b630d0e30db02815290516001600160a01b039092169163d0e30db091303191600480830192600092919082900301818588803b15801561161a57600080fd5b505af115801561162e573d6000803e3d6000fd5b50505050505b565b6001600160a01b031660009081526019602052604090205490565b600a5461010090046001600160a01b031681565b6011818154811061167257fe5b6000918252602090912060029091020180546001909101546001600160a01b03909116915082565b6008546001600160a01b031681565b60165481565b6000610f2c83836131c3565b60008042601754146116fa576116cf613265565b600d549093506116f7925068056bc75e2d631000009150610a8990849063ffffffff61245f16565b90505b61170b61170682612f56565b61330f565b91505090565b600060016000541461173857604051600160e51b62461bcd0281526004016103b990615c72565b60026000556007546008546001600160a01b0390811691161461177057604051600160e51b62461bcd0281526004016103b990615aa2565b61177a8383613354565b905080156110e357600754604051600160e01b632e1a7d4d0281526001600160a01b0390911690632e1a7d4d906117b590849060040161599d565b600060405180830381600087803b1580156117cf57600080fd5b505af11580156117e3573d6000803e3d6000fd5b505050506000836001600160a01b03168260405161180090615823565b60006040518083038185875af1925050503d806000811461183d576040519150601f19603f3d011682016040523d82523d6000602084013e611842565b606091505b505090508061186657604051600160e51b62461bcd0281526004016103b990615a52565b50600160005592915050565b600061187c614767565b506000828152600e60209081526040808320548352600f825291829020825160c08101845281548152600182015492810192909252600281015492820183905260038101546060830152600481015460808301526005015460a0820152906118e8576000915050610a98565b610f2c61190768056bc75e2d63100000836080015184604001516136c8565b610a898360400151610a7d611536565b6000610c426000806131c3565b60008415611a7b576000848152600e60209081526040808320548352600f9091528120600201546119649068056bc75e2d6310000063ffffffff612aee16565b905061198d69021e19e0c9bab2400000610a8961198087613709565b899063ffffffff61245f16565b955061199886613755565b9550856119a9576000915050611a7f565b600454600854611a7391600a916001600160a01b0361010090920482169163bc6cb1d99181169088166119e7576007546001600160a01b03166119e9565b875b60065460405163ffffffff851660e01b8152611a179392916001600160a01b0316908e908a906004016158d0565b60206040518083038186803b158015611a2f57600080fd5b505afa158015611a43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611a679190810190614c6e565b9063ffffffff612aee16565b915050611a7f565b5060005b949350505050565b6005546001600160a01b031681565b6001546001600160a01b031681565b6000600160005414611acc57604051600160e51b62461bcd0281526004016103b990615c72565b60026000556007546008546001600160a01b03908116911614611b0457604051600160e51b62461bcd0281526004016103b990615c12565b6110e38234612c33565b6000804260175414611b4d57611b22613265565b600d54909350611b4a925068056bc75e2d631000009150610a8990849063ffffffff61245f16565b90505b61170b81612f56565b6003805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610b205780601f10610af557610100808354040283529160200191610b20565b6006546001600160a01b031681565b60045461010090046001600160a01b031681565b60108181548110611be157fe5b600091825260209091200154905081565b6000600160005414611c1957604051600160e51b62461bcd0281526004016103b990615c72565b60026000556001600160a01b03841615801590611c5557506001600160a01b0383161580611c5557506008546001600160a01b03848116911614155b611c7457604051600160e51b62461bcd0281526004016103b990615c52565b611d058a6040518060600160405280886001600160a01b03166001600160a01b03168152602001876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152506040518060e00160405280600081526020018f81526020018d81526020018c81526020018b81526020018a81526020018f81525060008661383f565b60016000559b9a5050505050505050505050565b6000600160005414611d4057604051600160e51b62461bcd0281526004016103b990615c72565b6002600055611d4f8383613354565b905080156110e357600854604051600160e01b63a9059cbb0281526001600160a01b039091169063a9059cbb90611d8c908690859060040161593b565b602060405180830381600087803b158015611da657600080fd5b505af1158015611dba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611dde9190810190614bb8565b6110e357604051600160e51b62461bcd0281526004016103b990615c42565b33600090815260196020526040812054821115611e2f57604051600160e51b62461bcd0281526004016103b990615bf2565b6001600160a01b038316611e5857604051600160e51b62461bcd0281526004016103b990615b42565b33600090815260196020526040902054611e78908363ffffffff612adc16565b33600090815260196020526040808220929092556001600160a01b03851681522054611eaa908363ffffffff612aee16565b6001600160a01b038416600090815260196020526040812091909155611ece6116bb565b3360009081526012602052604090206001015490915060ff1680611f0057503360009081526019602052604090205415155b15611f1c57336000908152600960205260409020819055611f2d565b336000908152600960205260408120555b6001600160a01b03841660009081526012602052604090206001015460ff1680611f6e57506001600160a01b03841660009081526019602052604090205415155b15611f93576001600160a01b0384166000908152600960205260409020819055611fad565b6001600160a01b0384166000908152600960205260408120555b836001600160a01b0316336001600160a01b0316600080516020615eab83398151915285604051611fde919061599d565b60405180910390a35060019392505050565b6000610a958260006131c3565b60048054600654604051600160e11b6338f5892f0281526000936001600160a01b036101009094048416936371eb125e9361203b939116910161582e565b60206040518083038186803b15801561205357600080fd5b505afa158015612067573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061208b9190810190614a9b565b6001600160a01b0316336001600160a01b0316146120be57604051600160e51b62461bcd0281526004016103b990615c32565b6120c6614767565b50610120860180516000908152600f6020908152604091829020825160c081018452815480825260018301549382019390935260028201549381019390935260038101546060840152600481015460808401526005015460a083015291519091141561232c57836015541161213c57600061214f565b60155461214f908563ffffffff612adc16565b60155585516101208801516040516001600160a01b03909216917f85dfc0033a3e5b3b9b3151bd779c1f9b855d66b83ff5bb79283b68d82e8e5b739061219a90899089908990615956565b60405180910390a3601154156121ba576121b46000612497565b506121c2565b6121c2612e90565b836121d1576001915050610f41565b6121db6000612f56565b60165585516001600160a01b0386811691161461232257600a548651604051600160e01b63f9b646db0281526101009092046001600160a01b03169163f9b646db9161222c91600290600401615920565b60206040518083038186803b15801561224457600080fd5b505afa158015612258573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061227c9190810190614bb8565b1561232257600086600001516001600160a01b031660016040516024016122a3919061598f565b60408051601f198184030181529181526020820180516001600160e01b0316600160e01b63dcd1cc2102179052516122db9190615817565b6000604051808303816000865af19150503d8060008114612318576040519150601f19603f3d011682016040523d82523d6000602084013e61231d565b606091505b505050505b6001915050610f41565b5060009695505050505050565b6000601554600014610a98576123546109e883611a67611b0e565b9050610a98565b600d5481565b6001600160a01b039182166000908152601a6020908152604080832093909416825291909152205490565b6001600160a01b031660009081526009602052604090205490565b6001546001600160a01b031633146123be57600080fd5b6123c781613954565b50565b60006015546000146123f85761235468056bc75e2d63100000610a896123ef856139c3565b610a7d86612e12565b506000610a98565b6012602052600090815260409020805460019091015460ff1682565b600e6020526000908152604090205481565b60006124518a8a8a8a8a8a8a8a8a604051806020016040528060008152506128e9565b9a9950505050505050505050565b60008261246e57506000610c25565b508181028183828161247c57fe5b0414610c2557fe5b600081838161248f57fe5b049392505050565b60006124a1612e90565b6001600160a01b0382166124ba576124b76139fe565b91505b6001600160a01b03821660009081526012602052604090206001015460ff166124e557506000610a98565b6001600160a01b0382166000908152601260205260408120549061250b61170682612f56565b9050600061254c670de0b6b3a7640000610a89846011878154811061252c57fe5b90600052602060002090600202016001015461245f90919063ffffffff16565b90508061255f5760009350505050610a98565b600854604051600160e01b6370a082310281526000916001600160a01b0316906370a082319061259390309060040161583c565b60206040518083038186803b1580156125ab57600080fd5b505afa1580156125bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506125e39190810190614c6e565b9050806125f7576000945050505050610a98565b6000818311612630576011858154811061260d57fe5b906000526020600020906002020160010154905061262b8786613a63565b6126ee565b909150819061265184610a8984670de0b6b3a764000063ffffffff61245f16565b90506011858154811061266057fe5b906000526020600020906002020160010154612686600a83612aee90919063ffffffff16565b10156126e4576126bd816011878154811061269d57fe5b906000526020600020906002020160010154612adc90919063ffffffff16565b601186815481106126ca57fe5b9060005260206000209060020201600101819055506126ee565b6126ee8786613a63565b600854604051600160e01b63a9059cbb0281526001600160a01b039091169063a9059cbb90612723908a90879060040161593b565b602060405180830381600087803b15801561273d57600080fd5b505af1158015612751573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506127759190810190614bb8565b61279457604051600160e51b62461bcd0281526004016103b990615af2565b6001600160a01b03871660009081526012602052604090206001015460ff16806127d557506001600160a01b03871660009081526019602052604090205415155b156127fa576001600160a01b0387166000908152600960205260409020849055612814565b6001600160a01b0387166000908152600960205260408120555b8060135411612824576000612837565b601354612837908263ffffffff612adc16565b6013556001600160a01b0387166000818152601260205260409020600101547f68e1caf97c4c29c1ac46024e9590f80b7a1f690d393703879cf66eea4e1e8421908390869060ff1661288a5760006128c5565b6001600160a01b038b166000908152601260205260409020546011805490919081106128b257fe5b9060005260206000209060020201600101545b886040516128d69493929190615d4a565b60405180910390a2509095945050505050565b600060016000541461291057604051600160e51b62461bcd0281526004016103b990615c72565b60026000556001600160a01b0383161580159061293b57506008546001600160a01b03848116911614155b61295a57604051600160e51b62461bcd0281526004016103b990615a72565b8a6001600160a01b038681169085161415612a0457600654600854604051600160e51b6232ccd50281526001600160a01b03928316926306599aa0926129aa928992909116908690600401615912565b60606040518083038186803b1580156129c257600080fd5b505afa1580156129d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506129fa9190810190614cbc565b9250612a34915050565b6008546001600160a01b03878116911614612a3457604051600160e51b62461bcd0281526004016103b990615b32565b612ac78b60405180606001604052808a6001600160a01b03166001600160a01b03168152602001886001600160a01b03166001600160a01b03168152602001876001600160a01b03166001600160a01b03168152506040518060e0016040528060008152602001858152602001600081526020018e81526020018d81526020018c8152602001600081525060018761383f565b60016000559c9b505050505050505050505050565b600082821115612ae857fe5b50900390565b81810182811015610c2557fe5b60008415611a7f576000848152600e60209081526040808320548352600f909152812060020154612b3b9068056bc75e2d6310000063ffffffff612aee16565b6004546008549192506001600160a01b0361010090910481169163f3d75a9c91908116908616612b76576007546001600160a01b0316612b78565b855b60065460405163ffffffff851660e01b8152612ba69392916001600160a01b0316908c9088906004016158d0565b60206040518083038186803b158015612bbe57600080fd5b505afa158015612bd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612bf69190810190614c6e565b9150612c1e612c0485613709565b610a898469021e19e0c9bab240000063ffffffff61245f16565b9150612c2982613755565b9695505050505050565b600081612c5557604051600160e51b62461bcd0281526004016103b990615b82565b60115415612c9257612c676000612497565b50612c7183612497565b50336001600160a01b03841614612c8d57612c8b33612497565b505b612c9a565b612c9a612e90565b6000612ca96117066000612f56565b9050612cc781610a8985670de0b6b3a764000063ffffffff61245f16565b915034612d7b57600854604051600160e01b6323b872dd0281526001600160a01b03909116906323b872dd90612d059033903090889060040161584a565b602060405180830381600087803b158015612d1f57600080fd5b505af1158015612d33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612d579190810190614bb8565b612d7657604051600160e51b62461bcd0281526004016103b990615b92565b612de5565b600760009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0846040518263ffffffff1660e01b81526004016000604051808303818588803b158015612dcb57600080fd5b505af1158015612ddf573d6000803e3d6000fd5b50505050505b612df184838584613b71565b6001600160a01b039093166000908152600960205260409020929092555090565b600080601554600014612e67576000612e29613265565b50915050612e5f84610a89601654610a7d61016d610a7d601554610a8968056bc75e2d631000008a61245f90919063ffffffff16565b915050610a95565b610f2c5b7f3d82e958c891799f357c1316ae5543412952ae5c423336f8929ed7458039c9955490565b42601754146116345760045460009061010090046001600160a01b03165a600654600854604051612ed1926001600160a01b039081169216906024016158b5565b60408051601f198184030181529181526020820180516001600160e01b0316600160e01b63327ab6390217905251612f099190615817565b60006040518083038160008787f1925050503d8060008114612f47576040519150601f19603f3d011682016040523d82523d6000602084013e612f4c565b606091505b5050426017555050565b6000612f6f601354601b54612aee90919063ffffffff16565b15610a9857601554600854604051600160e01b6370a08231028152612354928592611a67926001600160a01b03909116906370a0823190611a1790309060040161583c565b6000806000612fc587878787613c72565b9250612fe49050612fdc888463ffffffff612aee16565b878787613c72565b9093509150612ff9878363ffffffff612aee16565b90509450945094915050565b60006130178360016020020151613755565b6020840181905261303d57604051600160e51b62461bcd0281526004016103b990615ae2565b6130478484613cb1565b6020830151606084015161305a91612aee565b836003602002015260048054604051600160e01b633ad971670281526101009091046001600160a01b031691633ad971679161309e918991899189918991016159ab565b602060405180830381600087803b1580156130b857600080fd5b505af11580156130cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506130f09190810190614c6e565b6020840181905261311657604051600160e51b62461bcd0281526004016103b990615b62565b602083015160155461312791612aee565b6015556131346000612f56565b60165560115415613157576131496000612497565b50835161315590612497565b505b835160208481015185519187015160408089015190516001600160a01b03958616957f86e15dd78cd784ab7788bcf5b96b9395e86030e048e5faedcfe752c700f6157e956131af959490939092909182161590615ced565b60405180910390a250506020015192915050565b6000808315613252574260175414613208576131dd613265565b600d54909350613205925068056bc75e2d631000009150610a8990849063ffffffff61245f16565b90505b600854604051600160e01b6370a082310281526000916132429184916001600160a01b0316906370a0823190611a1790309060040161583c565b905080851115613250578094505b505b611a7f8461325f83612f56565b856142ed565b60048054600654600854604051600160e31b63015216af028152600094859485946101009091046001600160a01b0390811694630a90b578946132b19430948416939092169101615872565b60806040518083038186803b1580156132c957600080fd5b505afa1580156132dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506133019190810190614d60565b929690955091935090915050565b600080613329601354601b54612aee90919063ffffffff16565b90508061333857601854610f2c565b610f2c81610a8985670de0b6b3a764000063ffffffff61245f16565b60008161337657604051600160e51b62461bcd0281526004016103b990615bb2565b61337f33611636565b8211156133925761338f33611636565b91505b601154156133cf576133a46000612497565b506133ae83612497565b50336001600160a01b038416146133ca576133c833612497565b505b6133d7565b6133d7612e90565b60006133e66117066000612f56565b90506000613406670de0b6b3a7640000610a89868563ffffffff61245f16565b600854604051600160e01b6370a082310281529192506000916001600160a01b03909116906370a082319061343f90309060040161583c565b60206040518083038186803b15801561345757600080fd5b505afa15801561346b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061348f9190810190614c6e565b9050819350808411156136575760006134ae858363ffffffff612adc16565b905060006134ce85610a8984670de0b6b3a764000063ffffffff61245f16565b6013549091506134e4908263ffffffff612aee16565b6013556001600160a01b03881660009081526012602052604090206001015460ff1615613580576001600160a01b038816600090815260126020526040902054601180546135589184918490811061353857fe5b906000526020600020906002020160010154612aee90919063ffffffff16565b6011828154811061356557fe5b90600052602060002090600202016001018190555050613651565b6040805180820182526001600160a01b038a811680835260208084018681526011805460018082018355600083815297517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c68600290930292830180546001600160a01b031916919098161790965591517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c69909201919091558551808701875290546000190181528082018481529285526012909152939092209251835590519101805460ff19169115159190911790555b82955050505b613663338686866144cb565b3360009081526012602052604090206001015460ff168061369257503360009081526019602052604090205415155b156136ae573360009081526009602052604090208390556136bf565b336000908152600960205260408120555b50505092915050565b6000826136de5768056bc75e2d63100000611a7f565b611a7f68056bc75e2d63100000611a6784610a8987610a7d6301e13380838c8863ffffffff61245f16565b6000610a9569021e19e0c9bab2400000611a676204cfe0610a8986610a7d600b54611a6768056bc75e2d63100000610a896804563918244f400000600c5461245f90919063ffffffff16565b600854604051600160e01b6370a0823102815260009182916001600160a01b03909116906370a082319061378d90309060040161583c565b60206040518083038186803b1580156137a557600080fd5b505afa1580156137b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506137dd9190810190614c6e565b9050806137ee576000915050610a98565b60006137f86115a0565b90508082111561381957613812828263ffffffff612adc16565b9150613824565b600092505050610a98565b8184111561383757600092505050610a98565b509192915050565b602083015160009061386657604051600160e51b62461bcd0281526004016103b990615cb2565b506000858152600e60205260409020548061389657604051600160e51b62461bcd0281526004016103b990615c62565b61389e612e90565b6000818152600f60205260409020600401541583156138dc576138c982866001602002015183614626565b86526020860181905260c08601526138f8565b60208501516138f5906138ef6000612f56565b836142ed565b85525b60408601516001600160a01b031661391257600060a08601525b600061392083888887613005565b6020870151909150811461394957604051600160e51b62461bcd0281526004016103b990615a62565b505095945050505050565b6001600160a01b03811661396757600080fd5b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b60006015546000141580156139d757508115155b156123f85761235482610a8968056bc75e2d6310000060155461245f90919063ffffffff16565b6014546000906001600160a01b031615613a2457506014546001600160a01b0316610c45565b60115415613a5b576011600081548110613a3a57fe5b60009182526020909120600290910201546001600160a01b03169050610c45565b506000610c45565b60115460011015613b1557601180546000198101908110613a8057fe5b906000526020600020906002020160118281548110613a9b57fe5b600091825260208220835460029092020180546001600160a01b0319166001600160a01b03909216919091178155600192830154920191909155601180548392601292909184908110613aea57fe5b600091825260208083206002909202909101546001600160a01b031683528201929092526040019020555b6011805490613b289060001983016147a0565b506001600160a01b038083166000818152601260205260408120908155600101805460ff191690556014549091161415613b6d57601480546001600160a01b03191690555b5050565b6001600160a01b038416613b9a57604051600160e51b62461bcd0281526004016103b990615b02565b601b54613bad908463ffffffff612aee16565b601b556001600160a01b038416600090815260196020526040902054613bd9908463ffffffff612aee16565b6001600160a01b038516600081815260196020526040908190209290925590517fb4c03061fb5b7fed76389d5af8f2e0ddb09f8c70d1333abbb62582835e10accb90613c2a90869086908690615d2f565b60405180910390a2836001600160a01b031660006001600160a01b0316600080516020615eab83398151915285604051613c64919061599d565b60405180910390a350505050565b600080613c808686856142ed565b9150613ca66b0a3098c68eb9427db8000000610a8986610a7d8a8763ffffffff61245f16565b905094509492505050565b81516020808401516040850151918401516060850151608086015160a087015160c08801519495946001600160a01b038616613e4657600854604051600160e01b63a9059cbb0281526001600160a01b039091169063a9059cbb90613d1c908b90859060040161593b565b602060405180830381600087803b158015613d3657600080fd5b505af1158015613d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613d6e9190810190614bb8565b613d8d57604051600160e51b62461bcd0281526004016103b990615be2565b80851115613e4157600854600554604051600160e01b63a9059cbb0281526001600160a01b039283169263a9059cbb92613dd092911690858a039060040161593b565b602060405180830381600087803b158015613dea57600080fd5b505af1158015613dfe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613e229190810190614bb8565b613e4157604051600160e51b62461bcd0281526004016103b990615b22565b613ef0565b600854600554604051600160e01b63a9059cbb0281526001600160a01b039283169263a9059cbb92613e7f92911690899060040161593b565b602060405180830381600087803b158015613e9957600080fd5b505af1158015613ead573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613ed19190810190614bb8565b613ef057604051600160e51b62461bcd0281526004016103b990615ac2565b821561415357341561404d576007546001600160a01b038881169116148015613f1857503483145b613f3757604051600160e51b62461bcd0281526004016103b990615bc2565b600760009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0846040518263ffffffff1660e01b81526004016000604051808303818588803b158015613f8757600080fd5b505af1158015613f9b573d6000803e3d6000fd5b5050600554604051600160e01b63a9059cbb0281526001600160a01b038c8116955063a9059cbb9450613fd7935090911690879060040161593b565b602060405180830381600087803b158015613ff157600080fd5b505af1158015614005573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506140299190810190614bb8565b61404857604051600160e51b62461bcd0281526004016103b990615b12565b614153565b6008546001600160a01b038881169116141561407a57614073848463ffffffff612aee16565b9350614153565b856001600160a01b0316876001600160a01b031614156140ab576140a4828463ffffffff612aee16565b9150614153565b600554604051600160e01b6323b872dd0281526001600160a01b03808a16926323b872dd926140e29233921690889060040161589a565b602060405180830381600087803b1580156140fc57600080fd5b505af1158015614110573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506141349190810190614bb8565b61415357604051600160e51b62461bcd0281526004016103b990615c22565b8315614233576008546001600160a01b03878116911614156141865761417f828563ffffffff612aee16565b9150614233565b600854600554604051600160e01b6323b872dd0281526001600160a01b03928316926323b872dd926141c292339290911690899060040161589a565b602060405180830381600087803b1580156141dc57600080fd5b505af11580156141f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506142149190810190614bb8565b61423357604051600160e51b62461bcd0281526004016103b990615ba2565b81156142e157600554604051600160e01b6323b872dd0281526001600160a01b03808916926323b872dd926142709233921690879060040161589a565b602060405180830381600087803b15801561428a57600080fd5b505af115801561429e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506142c29190810190614bb8565b6142e157604051600160e51b62461bcd0281526004016103b990615b72565b50505050505050505050565b600080614325856142ff57600061431c565b61431c85610a898868056bc75e2d6310000063ffffffff61245f16565b611a67866139c3565b90506000806804e1003b28d92800008311156143cf57614354836804e1003b28d928000063ffffffff612adc16565b9250678ac7230489e8000083111561437257678ac7230489e8000092505b6143936064610a89605a610a7d600b54600c54612aee90919063ffffffff16565b90506143c881611a67678ac7230489e80000610a896143bb68056bc75e2d6310000087612adc565b889063ffffffff61245f16565b93506144c1565b8480156143e457506804563918244f40000083105b156143f6576804563918244f40000092505b6802b5e3af16b188000083106144505761442e600b54611a6768056bc75e2d63100000610a89600c548861245f90919063ffffffff16565b600b54600c549195509250614449908363ffffffff612aee16565b90506144a5565b600061445a612e6b565b90506000614466614724565b905061448982611a6768056bc75e2d63100000610a89898663ffffffff61245f16565b955090925082906144a0818363ffffffff612aee16565b925050505b818410156144b5578193506144c1565b808411156144c1578093505b5050509392505050565b6001600160a01b03841660009081526019602052604090205483111561450657604051600160e51b62461bcd0281526004016103b990615bd2565b6001600160a01b03841660009081526019602052604090205461452f908463ffffffff612adc16565b6001600160a01b0385166000908152601960205260409020819055600a10614597576001600160a01b03841660009081526019602052604090205461457b90849063ffffffff612aee16565b6001600160a01b03851660009081526019602052604081205592505b601b546145aa908463ffffffff612adc16565b601b556040516001600160a01b038516907f743033787f4738ff4d6a7225ce2bd0977ee5f86b91a902a58f5e4d0b297b4644906145ec90869086908690615d2f565b60405180910390a260006001600160a01b0316846001600160a01b0316600080516020615eab83398151915285604051613c64919061599d565b600080614631614767565b506000858152600f6020908152604091829020825160c08101845281548152600182015492810192909252600281015492820183905260038101546060830152600481015460808301526005015460a0820152906146a457604051600160e51b62461bcd0281526004016103b990615ca2565b60408101516146d8906146ca90610a898868056bc75e2d6310000063ffffffff61245f16565b6146d2611b0e565b866142ed565b91506147198160400151610a896146f885856080015186604001516136c8565b610a8989701d6329f1c35ca4bfabb9f561000000000063ffffffff61245f16565b925050935093915050565b7f2b4858b1bc9e2d14afab03340ce5f6c81b703c86a0c570653ae586534e095fb15490565b6040518060e001604052806007906020820280388339509192915050565b6040518060c001604052806000801916815260200160008152602001600081526020016000815260200160008152602001600081525090565b8154818355818111156147cc576002028160020283600052602060002091820191016147cc91906147d1565b505050565b610c4591905b808211156147fc5780546001600160a01b0319168155600060018201556002016147d7565b5090565b8035610c2581615e84565b8051610c2581615e84565b8035610c2581615e98565b8051610c2581615e98565b8035610c2581615ea1565b600082601f83011261484857600080fd5b813561485b61485682615db4565b615d8d565b9150808252602083016020830185838301111561487757600080fd5b6136bf838284615e3e565b6000610140828403121561489557600080fd5b6148a0610140615d8d565b905060006148ae8484614800565b82525060206148bf84848301614800565b60208301525060406148d384828501614800565b60408301525060606148e784828501614800565b60608301525060806148fb8482850161482c565b60808301525060a061490f8482850161482c565b60a08301525060c06149238482850161482c565b60c08301525060e06149378482850161482c565b60e08301525061010061494c8482850161482c565b610100830152506101206149628482850161482c565b6101208301525092915050565b6000610160828403121561498257600080fd5b61498d610160615d8d565b9050600061499b8484614800565b82525060206149ac84848301614800565b60208301525060406149c084828501614800565b60408301525060606149d48482850161482c565b60608301525060806149e88482850161482c565b60808301525060a06149fc8482850161482c565b60a08301525060c0614a108482850161482c565b60c08301525060e0614a248482850161482c565b60e083015250610100614a398482850161482c565b61010083015250610120614a4f84828501614816565b61012083015250610140614a658482850161482c565b6101408301525092915050565b8051610c2581615ea1565b600060208284031215614a8f57600080fd5b6000611a7f8484614800565b600060208284031215614aad57600080fd5b6000611a7f848461480b565b60008060408385031215614acc57600080fd5b6000614ad88585614800565b9250506020614ae985828601614800565b9150509250929050565b600080600060608486031215614b0857600080fd5b6000614b148686614800565b9350506020614b2586828701614800565b9250506040614b368682870161482c565b9150509250925092565b60008060408385031215614b5357600080fd5b6000614b5f8585614800565b925050602083013567ffffffffffffffff811115614b7c57600080fd5b614ae985828601614837565b60008060408385031215614b9b57600080fd5b6000614ba78585614800565b9250506020614ae98582860161482c565b600060208284031215614bca57600080fd5b6000611a7f8484614821565b600060208284031215614be857600080fd5b6000611a7f848461482c565b60008060008060006103008688031215614c0d57600080fd5b6000614c198888614882565b955050610140614c2b8882890161496f565b9450506102a0614c3d88828901614800565b9350506102c0614c4f8882890161482c565b9250506102e0614c6188828901614816565b9150509295509295909350565b600060208284031215614c8057600080fd5b6000611a7f8484614a72565b60008060408385031215614c9f57600080fd5b6000614cab858561482c565b9250506020614ae985828601614816565b600080600060608486031215614cd157600080fd5b6000614cdd8686614a72565b9350506020614cee86828701614a72565b9250506040614b3686828701614a72565b60008060008060808587031215614d1557600080fd5b6000614d21878761482c565b9450506020614d328782880161482c565b9350506040614d438782880161482c565b9250506060614d5487828801614800565b91505092959194509250565b60008060008060808587031215614d7657600080fd5b6000614d828787614a72565b9450506020614d9387828801614a72565b9350506040614da487828801614a72565b9250506060614d5487828801614a72565b600080600080600080600060e0888a031215614dd057600080fd5b6000614ddc8a8a61482c565b9750506020614ded8a828b0161482c565b9650506040614dfe8a828b0161482c565b9550506060614e0f8a828b0161482c565b9450506080614e208a828b01614800565b93505060a0614e318a828b01614800565b92505060c088013567ffffffffffffffff811115614e4e57600080fd5b614e5a8a828b01614837565b91505092959891949750929550565b60008060008060008060008060006101208a8c031215614e8857600080fd5b6000614e948c8c61482c565b9950506020614ea58c828d0161482c565b9850506040614eb68c828d0161482c565b9750506060614ec78c828d0161482c565b9650506080614ed88c828d0161482c565b95505060a0614ee98c828d01614800565b94505060c0614efa8c828d01614800565b93505060e0614f0b8c828d01614800565b925050610100614f1d8c828d01614800565b9150509295985092959850929598565b6000806000806000806000806000806101408b8d031215614f4d57600080fd5b6000614f598d8d61482c565b9a50506020614f6a8d828e0161482c565b9950506040614f7b8d828e0161482c565b9850506060614f8c8d828e0161482c565b9750506080614f9d8d828e0161482c565b96505060a0614fae8d828e01614800565b95505060c0614fbf8d828e01614800565b94505060e0614fd08d828e01614800565b935050610100614fe28d828e01614800565b9250506101208b013567ffffffffffffffff81111561500057600080fd5b61500c8d828e01614837565b9150509295989b9194979a5092959850565b6000806000806000806000806000806101408b8d03121561503e57600080fd5b600061504a8d8d61482c565b9a5050602061505b8d828e0161482c565b995050604061506c8d828e0161482c565b985050606061507d8d828e0161482c565b975050608061508e8d828e0161482c565b96505060a0614fae8d828e0161482c565b60006150ab83836150ce565b505060200190565b60006150ab83836151d9565b6150c881615e1d565b82525050565b6150c881615dfb565b6150e081615de2565b6150ea8184610a98565b92506150f582610c45565b8060005b8381101561512357815161510d878261509f565b965061511883615ddc565b9250506001016150f9565b505050505050565b61513481615de8565b61513e8184610a98565b925061514982610c45565b8060005b8381101561512357815161516187826150b3565b965061516c83615ddc565b92505060010161514d565b600061518282615dee565b61518c8185615df2565b935061519783615ddc565b8060005b838110156151c55781516151af88826150b3565b97506151ba83615ddc565b92505060010161519b565b509495945050505050565b6150c881615e06565b6150c881610c45565b60006151ed82615dee565b6151f78185615df2565b9350615207818560208601615e4a565b61521081615e7a565b9093019392505050565b600061522582615dee565b61522f8185610a98565b935061523f818560208601615e4a565b9290920192915050565b6150c881615e28565b600061525f600183615df2565b600160fa1b600d02815260200192915050565b600061527f600283615df2565b600160f01b61323302815260200192915050565b60006152a0600283615df2565b600160f41b61031302815260200192915050565b60006152c1600283615df2565b600160f01b61313502815260200192915050565b60006152e2600283615df2565b600160f11b61189b02815260200192915050565b6000615303600183615df2565b600160f81b603302815260200192915050565b6000615323600183615df2565b600160f81b603702815260200192915050565b6000615343600283615df2565b600160f01b61323702815260200192915050565b6000615364600283615df2565b600160f21b610c4d02815260200192915050565b6000615385600283615df2565b600160f21b610c8d02815260200192915050565b60006153a6600283615df2565b600160f41b61032302815260200192915050565b60006153c7600f83615df2565b7f696e76616c696420616464726573730000000000000000000000000000000000815260200192915050565b6000615400600283615df2565b600160f01b61323902815260200192915050565b6000615421600283615df2565b600160f21b610ccd02815260200192915050565b6000615442600283615df2565b600160f01b61313102815260200192915050565b6000615463600283615df2565b600160f01b61313302815260200192915050565b6000615484600283615df2565b600160f11b61189902815260200192915050565b60006154a5600283615df2565b600160f01b61323502815260200192915050565b60006154c6600283615df2565b600160f11b61199902815260200192915050565b60006154e7600283615df2565b600160f01b61313702815260200192915050565b6000615508600283615df2565b600160f31b61062702815260200192915050565b6000615529600283615df2565b600160f01b61333102815260200192915050565b600061554a600283615df2565b600160f01b61313902815260200192915050565b600061556b600283615df2565b600160f31b61064702815260200192915050565b600061558c601a83615df2565b7f6275726e2076616c756520657863656564732062616c616e6365000000000000815260200192915050565b60006155c5600283615df2565b600160f11b61191b02815260200192915050565b60006155e6601483615df2565b7f696e73756666696369656e742062616c616e6365000000000000000000000000815260200192915050565b600061561f601483615df2565b7f66616c6c6261636b206e6f7420616c6c6f776564000000000000000000000000815260200192915050565b6000615658600183615df2565b600160f91b601902815260200192915050565b6000615678600283615df2565b600160f41b61033302815260200192915050565b6000610c25600083610a98565b60006156a6600183615df2565b600160f81b603102815260200192915050565b60006156c6600183615df2565b600160f81b603502815260200192915050565b60006156e6600183615df2565b600160f81b603902815260200192915050565b6000615706600283615df2565b600160f11b61191902815260200192915050565b6000615727600c83615df2565b7f6e6f6e5265656e7472616e740000000000000000000000000000000000000000815260200192915050565b6000615760600183615df2565b600160f91b601b02815260200192915050565b6000615780600183615df2565b600160fb1b600702815260200192915050565b60006157a0600283615df2565b600160f01b61333302815260200192915050565b60006157c1600283615df2565b600160f01b61323102815260200192915050565b60006157e2601183615df2565b7f626f72726f77416d6f756e74203d3d2030000000000000000000000000000000815260200192915050565b6150c881615e17565b6000610f2c828461521a565b6000610c258261568c565b60208101610c2582846150ce565b60208101610c2582846150bf565b6060810161585882866150bf565b61586560208301856150bf565b611a7f60408301846151d9565b6060810161588082866150bf565b61588d60208301856150ce565b611a7f60408301846150ce565b606081016158a882866150bf565b61586560208301856150ce565b604081016158c382856150ce565b610f2c60208301846150ce565b60a081016158de82886150ce565b6158eb60208301876150ce565b6158f860408301866150ce565b61590560608301856151d9565b612c2960808301846151d9565b606081016158a882866150ce565b6040810161592e82856150ce565b610f2c6020830184615249565b6040810161594982856150ce565b610f2c60208301846151d9565b6060810161596482866150ce565b61597160208301856151d9565b611a7f60408301846151d0565b60208082528101610f2c8184615177565b60208101610c2582846151d0565b60208101610c2582846151d9565b61018081016159ba82876151d9565b6159c760208301866150d7565b6159d4608083018561512b565b818103610160830152612c2981846151e2565b60c081016159f582896151d9565b615a0260208301886151d9565b615a0f60408301876151d9565b615a1c60608301866151d9565b615a2960808301856151d9565b615a3660a08301846151d9565b979650505050505050565b60208082528101610f2c81846151e2565b60208082528101610a9581615252565b60208082528101610a9581615272565b60208082528101610a9581615293565b60208082528101610a95816152b4565b60208082528101610a95816152d5565b60208082528101610a95816152f6565b60208082528101610a9581615316565b60208082528101610a9581615336565b60208082528101610a9581615357565b60208082528101610a9581615378565b60208082528101610a9581615399565b60208082528101610a95816153ba565b60208082528101610a95816153f3565b60208082528101610a9581615414565b60208082528101610a9581615435565b60208082528101610a9581615456565b60208082528101610a9581615477565b60208082528101610a9581615498565b60208082528101610a95816154b9565b60208082528101610a95816154da565b60208082528101610a95816154fb565b60208082528101610a958161551c565b60208082528101610a958161553d565b60208082528101610a958161555e565b60208082528101610a958161557f565b60208082528101610a95816155b8565b60208082528101610a95816155d9565b60208082528101610a9581615612565b60208082528101610a958161564b565b60208082528101610a958161566b565b60208082528101610a9581615699565b60208082528101610a95816156b9565b60208082528101610a95816156d9565b60208082528101610a95816156f9565b60208082528101610a958161571a565b60208082528101610a9581615753565b60208082528101610a9581615773565b60208082528101610a9581615793565b60208082528101610a95816157b4565b60208082528101610a95816157d5565b60408101615ce082856151d9565b610f2c60208301846151d0565b60a08101615cfb82886151d9565b615d0860208301876151d9565b615d1560408301866150ce565b615d2260608301856150ce565b612c2960808301846151d0565b60608101615d3d82866151d9565b61586560208301856151d9565b60808101615d5882876151d9565b615d6560208301866151d9565b615d7260408301856151d9565b610f4160608301846151d9565b60208101610c25828461580e565b60405181810167ffffffffffffffff81118282101715615dac57600080fd5b604052919050565b600067ffffffffffffffff821115615dcb57600080fd5b506020601f91909101601f19160190565b60200190565b50600390565b50600790565b5190565b90815260200190565b6000610a9582615e0b565b151590565b6001600160a01b031690565b60ff1690565b6000610a9582615e33565b6000610a9582610c45565b6000610a9582615dfb565b82818337506000910152565b60005b83811015615e65578181015183820152602001615e4d565b83811115615e74576000848401525b50505050565b601f01601f191690565b615e8d81615dfb565b81146123c757600080fd5b615e8d81615e06565b615e8d81610c4556feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa265627a7a723058200725eca12df935cc7620fa4d6a3b0c229ad5188b26747029c507f11779ab374d6c6578706572696d656e74616cf50037

Deployed Bytecode

0x60806040526004361061038c5760003560e01c8063797bf385116101dc5780639b3a54d111610102578063d84d2a47116100a0578063f468697e1161006f578063f468697e146109cd578063fbd9574d146109ed578063fe05634214610a1b578063fecb8da314610a3b5761038c565b8063d84d2a4714610958578063dd62ed3e1461096d578063eebc50811461098d578063f2fde38b146109ad5761038c565b8063a9059cbb116100dc578063a9059cbb146108d8578063b9fe1a8f146108f8578063cd4fa66d14610918578063d65a5021146109385761038c565b80639b3a54d1146108785780639d6bd0f2146108985780639dc29fac146108b85761038c565b80638423acd61161017a5780638fb807c5116101495780638fb807c51461082457806395d89b411461083957806396c7871b1461084e578063995363d3146108635761038c565b80638423acd6146107c7578063894ca308146107e75780638da5cb5b146107fc5780638f6ede1f146108115761038c565b80637ff9b596116101b65780637ff9b5961461075d57806381a6b25014610772578063829b38f4146107925780638325a1c0146107b25761038c565b8063797bf385146107135780637b7933b4146107285780637d90dcba1461073d5761038c565b8063284e2f56116102c157806347e917e71161025f5780636f1296d21161022e5780636f1296d21461069b57806370a08231146106b0578063736ee3d3146106d05780637866c6c1146106e55761038c565b806347e917e71461063e57806359e239af14610651578063612ef80b14610671578063674d13c8146106865761038c565b8063330691ac1161029b578063330691ac146105d257806340c10f19146105e757806344a4a003146106075780634780eac11461061c5761038c565b8063284e2f561461056e5780632ecae90a1461058e578063313ce567146105b05761038c565b80631c5d1da51161032e57806320f6d07c1161030857806320f6d07c146104e757806323b872dd146104fc57806324d25f4a1461051c5780632515aacd1461053c5761038c565b80631c5d1da51461049d5780631d0806ae146104bd5780631f68f20a146104d25761038c565b8063095ea7b31161036a578063095ea7b31461043157806309ec6b6b1461045e5780630c4925fd1461047357806318160ddd146104885761038c565b806306b3efd6146103c457806306fdde03146103fa578063087fc48b1461041c575b6007546001600160a01b031633146103c257604051600160e51b62461bcd0281526004016103b990615c02565b60405180910390fd5b005b3480156103d057600080fd5b506103e46103df366004614a7d565b610a5b565b6040516103f1919061599d565b60405180910390f35b34801561040657600080fd5b5061040f610a9d565b6040516103f19190615a41565b34801561042857600080fd5b506103e4610b28565b34801561043d57600080fd5b5061045161044c366004614b88565b610bc0565b6040516103f1919061598f565b34801561046a57600080fd5b506103e4610c2b565b34801561047f57600080fd5b506103e4610c48565b34801561049457600080fd5b506103e4610c4e565b3480156104a957600080fd5b506103e46104b8366004614f2d565b610c54565b3480156104c957600080fd5b506103e4610c77565b3480156104de57600080fd5b506103e4610c7d565b3480156104f357600080fd5b506103e4610c83565b34801561050857600080fd5b50610451610517366004614af3565b610c89565b34801561052857600080fd5b506103e4610537366004614cff565b610f33565b34801561054857600080fd5b5061055c610557366004614bd6565b610f4a565b6040516103f1969594939291906159e7565b34801561057a57600080fd5b506103c2610589366004614b40565b610f7f565b34801561059a57600080fd5b506105a3611043565b6040516103f1919061597e565b3480156105bc57600080fd5b506105c561109b565b6040516103f19190615d7f565b3480156105de57600080fd5b506103e46110a4565b3480156105f357600080fd5b506103e4610602366004614b88565b6110aa565b34801561061357600080fd5b506103e46110ee565b34801561062857600080fd5b50610631611112565b6040516103f1919061582e565b6103e461064c366004614db5565b611121565b34801561065d57600080fd5b5061045161066c366004614a7d565b611355565b34801561067d57600080fd5b506103e4611536565b34801561069257600080fd5b506103e46115a0565b3480156106a757600080fd5b506103c26115c8565b3480156106bc57600080fd5b506103e46106cb366004614a7d565b611636565b3480156106dc57600080fd5b50610631611651565b3480156106f157600080fd5b50610705610700366004614bd6565b611665565b6040516103f192919061593b565b34801561071f57600080fd5b5061063161169a565b34801561073457600080fd5b506103e46116a9565b34801561074957600080fd5b506103e4610758366004614c8c565b6116af565b34801561076957600080fd5b506103e46116bb565b34801561077e57600080fd5b506103e461078d366004614b88565b611711565b34801561079e57600080fd5b506103e46107ad366004614bd6565b611872565b3480156107be57600080fd5b506103e4611917565b3480156107d357600080fd5b506103e46107e2366004614cff565b611924565b3480156107f357600080fd5b50610631611a87565b34801561080857600080fd5b50610631611a96565b6103e461081f366004614a7d565b611aa5565b34801561083057600080fd5b506103e4611b0e565b34801561084557600080fd5b5061040f611b56565b34801561085a57600080fd5b50610631611bb1565b34801561086f57600080fd5b50610631611bc0565b34801561088457600080fd5b506103e4610893366004614bd6565b611bd4565b3480156108a457600080fd5b506103e46108b336600461501e565b611bf2565b3480156108c457600080fd5b506103e46108d3366004614b88565b611d19565b3480156108e457600080fd5b506104516108f3366004614b88565b611dfd565b34801561090457600080fd5b506103e4610913366004614bd6565b611ff0565b34801561092457600080fd5b50610451610933366004614bf4565b611ffd565b34801561094457600080fd5b506103e4610953366004614bd6565b612339565b34801561096457600080fd5b506103e461235b565b34801561097957600080fd5b506103e4610988366004614ab9565b612361565b34801561099957600080fd5b506103e46109a8366004614a7d565b61238c565b3480156109b957600080fd5b506103c26109c8366004614a7d565b6123a7565b3480156109d957600080fd5b506103e46109e8366004614bd6565b6123ca565b3480156109f957600080fd5b50610a0d610a08366004614a7d565b612400565b6040516103f1929190615cd2565b348015610a2757600080fd5b506103e4610a36366004614bd6565b61241c565b348015610a4757600080fd5b506103e4610a56366004614e69565b61242e565b6000610a95670de0b6b3a7640000610a89610a746116bb565b610a7d86611636565b9063ffffffff61245f16565b9063ffffffff61248416565b90505b919050565b6002805460408051602060018416156101000260001901909316849004601f81018490048402820184019092528181529291830182828015610b205780601f10610af557610100808354040283529160200191610b20565b820191906000526020600020905b815481529060010190602001808311610b0357829003601f168201915b505050505081565b6000600160005414610b4f57604051600160e51b62461bcd0281526004016103b990615c72565b6002600055610b5d33612497565b60115490915015610bb857610b726000612497565b503360009081526012602052604090206001015460ff168015610ba057506014546001600160a01b03163314155b15610bb857601480546001600160a01b031916331790555b600160005590565b336000818152601a602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610c1990869061599d565b60405180910390a35060015b92915050565b6000601554600014610c4557610c426109e8611b0e565b90505b90565b60135481565b601b5490565b6000610c688b8b8b8b8b8b8b8b8b8b6128e9565b9b9a5050505050505050505050565b60185481565b600b5481565b60155481565b6001600160a01b0383166000818152601a602090815260408083203384528252808320549383526019909152812054909190831115610cdd57604051600160e51b62461bcd0281526004016103b990615ad2565b80831115610d0057604051600160e51b62461bcd0281526004016103b990615a82565b6001600160a01b038416610d2957604051600160e51b62461bcd0281526004016103b990615a92565b6001600160a01b038516600090815260196020526040902054610d52908463ffffffff612adc16565b6001600160a01b038087166000908152601960205260408082209390935590861681522054610d87908463ffffffff612aee16565b6001600160a01b038516600090815260196020526040902055600019811015610ddf57610dba818463ffffffff612adc16565b6001600160a01b0386166000908152601a602090815260408083203384529091529020555b6000610de96116bb565b6001600160a01b03871660009081526012602052604090206001015490915060ff1680610e2d57506001600160a01b03861660009081526019602052604090205415155b15610e52576001600160a01b0386166000908152600960205260409020819055610e6c565b6001600160a01b0386166000908152600960205260408120555b6001600160a01b03851660009081526012602052604090206001015460ff1680610ead57506001600160a01b03851660009081526019602052604090205415155b15610ed2576001600160a01b0385166000908152600960205260409020819055610eec565b6001600160a01b0385166000908152600960205260408120555b846001600160a01b0316866001600160a01b0316600080516020615eab83398151915286604051610f1d919061599d565b60405180910390a36001925050505b9392505050565b6000610f4185858585612afb565b95945050505050565b600f60205260009081526040902080546001820154600283015460038401546004850154600590950154939492939192909186565b6001546001600160a01b03163314610f9657600080fd5b601c80546001600160a01b038481166001600160a01b03198316179092556040519116906000903090610fca908590615817565b6000604051808303816000865af19150503d8060008114611007576040519150601f19603f3d011682016040523d82523d6000602084013e61100c565b606091505b50506040519091503d90816000823e82611024578181fd5b601c80546001600160a01b0319166001600160a01b0386161790558181f35b6060601080548060200260200160405190810160405280929190818152602001828054801561109157602002820191906000526020600020905b81548152602001906001019080831161107d575b5050505050905090565b60045460ff1681565b600c5481565b60006001600054146110d157604051600160e51b62461bcd0281526004016103b990615c72565b60026000556110e08383612c33565b90505b600160005592915050565b600060155460001461110a57610c42611105611b0e565b612e12565b610c42612e6b565b6007546001600160a01b031681565b600060016000541461114857604051600160e51b62461bcd0281526004016103b990615c72565b60026000553415801561116357506001600160a01b03831615155b801561116e57508415155b806111ab575034158015906111a157506001600160a01b03831615806111a157506007546001600160a01b038481169116145b80156111ab575084155b6111ca57604051600160e51b62461bcd0281526004016103b990615c82565b506000868152600e6020526040902054806111fa57604051600160e51b62461bcd0281526004016103b990615ab2565b611202612e90565b61120a614749565b6000828152600f6020526040902060040154153415611235576007543497506001600160a01b031694505b8961127457611246878a8a88612afb565b99508961126857604051600160e51b62461bcd0281526004016103b990615cc2565b60c082018a905261127c565b60c082018a90525b6112918a61128a6000612f56565b8a84612fb4565b60408581019290925291845280516060810182526001600160a01b0389811682528816602080830191909152600082840152825160e08101845286518152908101849052929c5061131b928692810186600260200201518152602001600081526020018b8152602001600081526020018660066007811061130e57fe5b6020020151905287613005565b60c083018190528a1461134357604051600160e51b62461bcd0281526004016103b990615c92565b50506001600055979650505050505050565b6008546000906001600160a01b038381169116141561137657506000610a98565b604051600160e01b6370a082310281526000906001600160a01b038416906370a08231906113a890309060040161583c565b60206040518083038186803b1580156113c057600080fd5b505afa1580156113d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113f89190810190614c6e565b905080611409576000915050610a98565b60048054600654604051600160e11b6338f5892f0281526001600160a01b038781169463a9059cbb9461010090048216936371eb125e9361144e93909116910161582e565b60206040518083038186803b15801561146657600080fd5b505afa15801561147a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061149e9190810190614a9b565b836040518363ffffffff1660e01b81526004016114bc92919061593b565b602060405180830381600087803b1580156114d657600080fd5b505af11580156114ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061150e9190810190614bb8565b61152d57604051600160e51b62461bcd0281526004016103b990615b52565b50600192915050565b600080611541611b0e565b9050600061154d6115a0565b90508082111561156e57611567828263ffffffff612adc16565b9150611579565b600092505050610c45565b60155482111561156e5760155461159790839063ffffffff612adc16565b92505050610c45565b6000610c42670de0b6b3a7640000610a896115b96116bb565b6013549063ffffffff61245f16565b3031156116345760075460408051600160e41b630d0e30db02815290516001600160a01b039092169163d0e30db091303191600480830192600092919082900301818588803b15801561161a57600080fd5b505af115801561162e573d6000803e3d6000fd5b50505050505b565b6001600160a01b031660009081526019602052604090205490565b600a5461010090046001600160a01b031681565b6011818154811061167257fe5b6000918252602090912060029091020180546001909101546001600160a01b03909116915082565b6008546001600160a01b031681565b60165481565b6000610f2c83836131c3565b60008042601754146116fa576116cf613265565b600d549093506116f7925068056bc75e2d631000009150610a8990849063ffffffff61245f16565b90505b61170b61170682612f56565b61330f565b91505090565b600060016000541461173857604051600160e51b62461bcd0281526004016103b990615c72565b60026000556007546008546001600160a01b0390811691161461177057604051600160e51b62461bcd0281526004016103b990615aa2565b61177a8383613354565b905080156110e357600754604051600160e01b632e1a7d4d0281526001600160a01b0390911690632e1a7d4d906117b590849060040161599d565b600060405180830381600087803b1580156117cf57600080fd5b505af11580156117e3573d6000803e3d6000fd5b505050506000836001600160a01b03168260405161180090615823565b60006040518083038185875af1925050503d806000811461183d576040519150601f19603f3d011682016040523d82523d6000602084013e611842565b606091505b505090508061186657604051600160e51b62461bcd0281526004016103b990615a52565b50600160005592915050565b600061187c614767565b506000828152600e60209081526040808320548352600f825291829020825160c08101845281548152600182015492810192909252600281015492820183905260038101546060830152600481015460808301526005015460a0820152906118e8576000915050610a98565b610f2c61190768056bc75e2d63100000836080015184604001516136c8565b610a898360400151610a7d611536565b6000610c426000806131c3565b60008415611a7b576000848152600e60209081526040808320548352600f9091528120600201546119649068056bc75e2d6310000063ffffffff612aee16565b905061198d69021e19e0c9bab2400000610a8961198087613709565b899063ffffffff61245f16565b955061199886613755565b9550856119a9576000915050611a7f565b600454600854611a7391600a916001600160a01b0361010090920482169163bc6cb1d99181169088166119e7576007546001600160a01b03166119e9565b875b60065460405163ffffffff851660e01b8152611a179392916001600160a01b0316908e908a906004016158d0565b60206040518083038186803b158015611a2f57600080fd5b505afa158015611a43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611a679190810190614c6e565b9063ffffffff612aee16565b915050611a7f565b5060005b949350505050565b6005546001600160a01b031681565b6001546001600160a01b031681565b6000600160005414611acc57604051600160e51b62461bcd0281526004016103b990615c72565b60026000556007546008546001600160a01b03908116911614611b0457604051600160e51b62461bcd0281526004016103b990615c12565b6110e38234612c33565b6000804260175414611b4d57611b22613265565b600d54909350611b4a925068056bc75e2d631000009150610a8990849063ffffffff61245f16565b90505b61170b81612f56565b6003805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610b205780601f10610af557610100808354040283529160200191610b20565b6006546001600160a01b031681565b60045461010090046001600160a01b031681565b60108181548110611be157fe5b600091825260209091200154905081565b6000600160005414611c1957604051600160e51b62461bcd0281526004016103b990615c72565b60026000556001600160a01b03841615801590611c5557506001600160a01b0383161580611c5557506008546001600160a01b03848116911614155b611c7457604051600160e51b62461bcd0281526004016103b990615c52565b611d058a6040518060600160405280886001600160a01b03166001600160a01b03168152602001876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152506040518060e00160405280600081526020018f81526020018d81526020018c81526020018b81526020018a81526020018f81525060008661383f565b60016000559b9a5050505050505050505050565b6000600160005414611d4057604051600160e51b62461bcd0281526004016103b990615c72565b6002600055611d4f8383613354565b905080156110e357600854604051600160e01b63a9059cbb0281526001600160a01b039091169063a9059cbb90611d8c908690859060040161593b565b602060405180830381600087803b158015611da657600080fd5b505af1158015611dba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611dde9190810190614bb8565b6110e357604051600160e51b62461bcd0281526004016103b990615c42565b33600090815260196020526040812054821115611e2f57604051600160e51b62461bcd0281526004016103b990615bf2565b6001600160a01b038316611e5857604051600160e51b62461bcd0281526004016103b990615b42565b33600090815260196020526040902054611e78908363ffffffff612adc16565b33600090815260196020526040808220929092556001600160a01b03851681522054611eaa908363ffffffff612aee16565b6001600160a01b038416600090815260196020526040812091909155611ece6116bb565b3360009081526012602052604090206001015490915060ff1680611f0057503360009081526019602052604090205415155b15611f1c57336000908152600960205260409020819055611f2d565b336000908152600960205260408120555b6001600160a01b03841660009081526012602052604090206001015460ff1680611f6e57506001600160a01b03841660009081526019602052604090205415155b15611f93576001600160a01b0384166000908152600960205260409020819055611fad565b6001600160a01b0384166000908152600960205260408120555b836001600160a01b0316336001600160a01b0316600080516020615eab83398151915285604051611fde919061599d565b60405180910390a35060019392505050565b6000610a958260006131c3565b60048054600654604051600160e11b6338f5892f0281526000936001600160a01b036101009094048416936371eb125e9361203b939116910161582e565b60206040518083038186803b15801561205357600080fd5b505afa158015612067573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061208b9190810190614a9b565b6001600160a01b0316336001600160a01b0316146120be57604051600160e51b62461bcd0281526004016103b990615c32565b6120c6614767565b50610120860180516000908152600f6020908152604091829020825160c081018452815480825260018301549382019390935260028201549381019390935260038101546060840152600481015460808401526005015460a083015291519091141561232c57836015541161213c57600061214f565b60155461214f908563ffffffff612adc16565b60155585516101208801516040516001600160a01b03909216917f85dfc0033a3e5b3b9b3151bd779c1f9b855d66b83ff5bb79283b68d82e8e5b739061219a90899089908990615956565b60405180910390a3601154156121ba576121b46000612497565b506121c2565b6121c2612e90565b836121d1576001915050610f41565b6121db6000612f56565b60165585516001600160a01b0386811691161461232257600a548651604051600160e01b63f9b646db0281526101009092046001600160a01b03169163f9b646db9161222c91600290600401615920565b60206040518083038186803b15801561224457600080fd5b505afa158015612258573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061227c9190810190614bb8565b1561232257600086600001516001600160a01b031660016040516024016122a3919061598f565b60408051601f198184030181529181526020820180516001600160e01b0316600160e01b63dcd1cc2102179052516122db9190615817565b6000604051808303816000865af19150503d8060008114612318576040519150601f19603f3d011682016040523d82523d6000602084013e61231d565b606091505b505050505b6001915050610f41565b5060009695505050505050565b6000601554600014610a98576123546109e883611a67611b0e565b9050610a98565b600d5481565b6001600160a01b039182166000908152601a6020908152604080832093909416825291909152205490565b6001600160a01b031660009081526009602052604090205490565b6001546001600160a01b031633146123be57600080fd5b6123c781613954565b50565b60006015546000146123f85761235468056bc75e2d63100000610a896123ef856139c3565b610a7d86612e12565b506000610a98565b6012602052600090815260409020805460019091015460ff1682565b600e6020526000908152604090205481565b60006124518a8a8a8a8a8a8a8a8a604051806020016040528060008152506128e9565b9a9950505050505050505050565b60008261246e57506000610c25565b508181028183828161247c57fe5b0414610c2557fe5b600081838161248f57fe5b049392505050565b60006124a1612e90565b6001600160a01b0382166124ba576124b76139fe565b91505b6001600160a01b03821660009081526012602052604090206001015460ff166124e557506000610a98565b6001600160a01b0382166000908152601260205260408120549061250b61170682612f56565b9050600061254c670de0b6b3a7640000610a89846011878154811061252c57fe5b90600052602060002090600202016001015461245f90919063ffffffff16565b90508061255f5760009350505050610a98565b600854604051600160e01b6370a082310281526000916001600160a01b0316906370a082319061259390309060040161583c565b60206040518083038186803b1580156125ab57600080fd5b505afa1580156125bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506125e39190810190614c6e565b9050806125f7576000945050505050610a98565b6000818311612630576011858154811061260d57fe5b906000526020600020906002020160010154905061262b8786613a63565b6126ee565b909150819061265184610a8984670de0b6b3a764000063ffffffff61245f16565b90506011858154811061266057fe5b906000526020600020906002020160010154612686600a83612aee90919063ffffffff16565b10156126e4576126bd816011878154811061269d57fe5b906000526020600020906002020160010154612adc90919063ffffffff16565b601186815481106126ca57fe5b9060005260206000209060020201600101819055506126ee565b6126ee8786613a63565b600854604051600160e01b63a9059cbb0281526001600160a01b039091169063a9059cbb90612723908a90879060040161593b565b602060405180830381600087803b15801561273d57600080fd5b505af1158015612751573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506127759190810190614bb8565b61279457604051600160e51b62461bcd0281526004016103b990615af2565b6001600160a01b03871660009081526012602052604090206001015460ff16806127d557506001600160a01b03871660009081526019602052604090205415155b156127fa576001600160a01b0387166000908152600960205260409020849055612814565b6001600160a01b0387166000908152600960205260408120555b8060135411612824576000612837565b601354612837908263ffffffff612adc16565b6013556001600160a01b0387166000818152601260205260409020600101547f68e1caf97c4c29c1ac46024e9590f80b7a1f690d393703879cf66eea4e1e8421908390869060ff1661288a5760006128c5565b6001600160a01b038b166000908152601260205260409020546011805490919081106128b257fe5b9060005260206000209060020201600101545b886040516128d69493929190615d4a565b60405180910390a2509095945050505050565b600060016000541461291057604051600160e51b62461bcd0281526004016103b990615c72565b60026000556001600160a01b0383161580159061293b57506008546001600160a01b03848116911614155b61295a57604051600160e51b62461bcd0281526004016103b990615a72565b8a6001600160a01b038681169085161415612a0457600654600854604051600160e51b6232ccd50281526001600160a01b03928316926306599aa0926129aa928992909116908690600401615912565b60606040518083038186803b1580156129c257600080fd5b505afa1580156129d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506129fa9190810190614cbc565b9250612a34915050565b6008546001600160a01b03878116911614612a3457604051600160e51b62461bcd0281526004016103b990615b32565b612ac78b60405180606001604052808a6001600160a01b03166001600160a01b03168152602001886001600160a01b03166001600160a01b03168152602001876001600160a01b03166001600160a01b03168152506040518060e0016040528060008152602001858152602001600081526020018e81526020018d81526020018c8152602001600081525060018761383f565b60016000559c9b505050505050505050505050565b600082821115612ae857fe5b50900390565b81810182811015610c2557fe5b60008415611a7f576000848152600e60209081526040808320548352600f909152812060020154612b3b9068056bc75e2d6310000063ffffffff612aee16565b6004546008549192506001600160a01b0361010090910481169163f3d75a9c91908116908616612b76576007546001600160a01b0316612b78565b855b60065460405163ffffffff851660e01b8152612ba69392916001600160a01b0316908c9088906004016158d0565b60206040518083038186803b158015612bbe57600080fd5b505afa158015612bd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612bf69190810190614c6e565b9150612c1e612c0485613709565b610a898469021e19e0c9bab240000063ffffffff61245f16565b9150612c2982613755565b9695505050505050565b600081612c5557604051600160e51b62461bcd0281526004016103b990615b82565b60115415612c9257612c676000612497565b50612c7183612497565b50336001600160a01b03841614612c8d57612c8b33612497565b505b612c9a565b612c9a612e90565b6000612ca96117066000612f56565b9050612cc781610a8985670de0b6b3a764000063ffffffff61245f16565b915034612d7b57600854604051600160e01b6323b872dd0281526001600160a01b03909116906323b872dd90612d059033903090889060040161584a565b602060405180830381600087803b158015612d1f57600080fd5b505af1158015612d33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612d579190810190614bb8565b612d7657604051600160e51b62461bcd0281526004016103b990615b92565b612de5565b600760009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0846040518263ffffffff1660e01b81526004016000604051808303818588803b158015612dcb57600080fd5b505af1158015612ddf573d6000803e3d6000fd5b50505050505b612df184838584613b71565b6001600160a01b039093166000908152600960205260409020929092555090565b600080601554600014612e67576000612e29613265565b50915050612e5f84610a89601654610a7d61016d610a7d601554610a8968056bc75e2d631000008a61245f90919063ffffffff16565b915050610a95565b610f2c5b7f3d82e958c891799f357c1316ae5543412952ae5c423336f8929ed7458039c9955490565b42601754146116345760045460009061010090046001600160a01b03165a600654600854604051612ed1926001600160a01b039081169216906024016158b5565b60408051601f198184030181529181526020820180516001600160e01b0316600160e01b63327ab6390217905251612f099190615817565b60006040518083038160008787f1925050503d8060008114612f47576040519150601f19603f3d011682016040523d82523d6000602084013e612f4c565b606091505b5050426017555050565b6000612f6f601354601b54612aee90919063ffffffff16565b15610a9857601554600854604051600160e01b6370a08231028152612354928592611a67926001600160a01b03909116906370a0823190611a1790309060040161583c565b6000806000612fc587878787613c72565b9250612fe49050612fdc888463ffffffff612aee16565b878787613c72565b9093509150612ff9878363ffffffff612aee16565b90509450945094915050565b60006130178360016020020151613755565b6020840181905261303d57604051600160e51b62461bcd0281526004016103b990615ae2565b6130478484613cb1565b6020830151606084015161305a91612aee565b836003602002015260048054604051600160e01b633ad971670281526101009091046001600160a01b031691633ad971679161309e918991899189918991016159ab565b602060405180830381600087803b1580156130b857600080fd5b505af11580156130cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506130f09190810190614c6e565b6020840181905261311657604051600160e51b62461bcd0281526004016103b990615b62565b602083015160155461312791612aee565b6015556131346000612f56565b60165560115415613157576131496000612497565b50835161315590612497565b505b835160208481015185519187015160408089015190516001600160a01b03958616957f86e15dd78cd784ab7788bcf5b96b9395e86030e048e5faedcfe752c700f6157e956131af959490939092909182161590615ced565b60405180910390a250506020015192915050565b6000808315613252574260175414613208576131dd613265565b600d54909350613205925068056bc75e2d631000009150610a8990849063ffffffff61245f16565b90505b600854604051600160e01b6370a082310281526000916132429184916001600160a01b0316906370a0823190611a1790309060040161583c565b905080851115613250578094505b505b611a7f8461325f83612f56565b856142ed565b60048054600654600854604051600160e31b63015216af028152600094859485946101009091046001600160a01b0390811694630a90b578946132b19430948416939092169101615872565b60806040518083038186803b1580156132c957600080fd5b505afa1580156132dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506133019190810190614d60565b929690955091935090915050565b600080613329601354601b54612aee90919063ffffffff16565b90508061333857601854610f2c565b610f2c81610a8985670de0b6b3a764000063ffffffff61245f16565b60008161337657604051600160e51b62461bcd0281526004016103b990615bb2565b61337f33611636565b8211156133925761338f33611636565b91505b601154156133cf576133a46000612497565b506133ae83612497565b50336001600160a01b038416146133ca576133c833612497565b505b6133d7565b6133d7612e90565b60006133e66117066000612f56565b90506000613406670de0b6b3a7640000610a89868563ffffffff61245f16565b600854604051600160e01b6370a082310281529192506000916001600160a01b03909116906370a082319061343f90309060040161583c565b60206040518083038186803b15801561345757600080fd5b505afa15801561346b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061348f9190810190614c6e565b9050819350808411156136575760006134ae858363ffffffff612adc16565b905060006134ce85610a8984670de0b6b3a764000063ffffffff61245f16565b6013549091506134e4908263ffffffff612aee16565b6013556001600160a01b03881660009081526012602052604090206001015460ff1615613580576001600160a01b038816600090815260126020526040902054601180546135589184918490811061353857fe5b906000526020600020906002020160010154612aee90919063ffffffff16565b6011828154811061356557fe5b90600052602060002090600202016001018190555050613651565b6040805180820182526001600160a01b038a811680835260208084018681526011805460018082018355600083815297517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c68600290930292830180546001600160a01b031916919098161790965591517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c69909201919091558551808701875290546000190181528082018481529285526012909152939092209251835590519101805460ff19169115159190911790555b82955050505b613663338686866144cb565b3360009081526012602052604090206001015460ff168061369257503360009081526019602052604090205415155b156136ae573360009081526009602052604090208390556136bf565b336000908152600960205260408120555b50505092915050565b6000826136de5768056bc75e2d63100000611a7f565b611a7f68056bc75e2d63100000611a6784610a8987610a7d6301e13380838c8863ffffffff61245f16565b6000610a9569021e19e0c9bab2400000611a676204cfe0610a8986610a7d600b54611a6768056bc75e2d63100000610a896804563918244f400000600c5461245f90919063ffffffff16565b600854604051600160e01b6370a0823102815260009182916001600160a01b03909116906370a082319061378d90309060040161583c565b60206040518083038186803b1580156137a557600080fd5b505afa1580156137b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506137dd9190810190614c6e565b9050806137ee576000915050610a98565b60006137f86115a0565b90508082111561381957613812828263ffffffff612adc16565b9150613824565b600092505050610a98565b8184111561383757600092505050610a98565b509192915050565b602083015160009061386657604051600160e51b62461bcd0281526004016103b990615cb2565b506000858152600e60205260409020548061389657604051600160e51b62461bcd0281526004016103b990615c62565b61389e612e90565b6000818152600f60205260409020600401541583156138dc576138c982866001602002015183614626565b86526020860181905260c08601526138f8565b60208501516138f5906138ef6000612f56565b836142ed565b85525b60408601516001600160a01b031661391257600060a08601525b600061392083888887613005565b6020870151909150811461394957604051600160e51b62461bcd0281526004016103b990615a62565b505095945050505050565b6001600160a01b03811661396757600080fd5b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b60006015546000141580156139d757508115155b156123f85761235482610a8968056bc75e2d6310000060155461245f90919063ffffffff16565b6014546000906001600160a01b031615613a2457506014546001600160a01b0316610c45565b60115415613a5b576011600081548110613a3a57fe5b60009182526020909120600290910201546001600160a01b03169050610c45565b506000610c45565b60115460011015613b1557601180546000198101908110613a8057fe5b906000526020600020906002020160118281548110613a9b57fe5b600091825260208220835460029092020180546001600160a01b0319166001600160a01b03909216919091178155600192830154920191909155601180548392601292909184908110613aea57fe5b600091825260208083206002909202909101546001600160a01b031683528201929092526040019020555b6011805490613b289060001983016147a0565b506001600160a01b038083166000818152601260205260408120908155600101805460ff191690556014549091161415613b6d57601480546001600160a01b03191690555b5050565b6001600160a01b038416613b9a57604051600160e51b62461bcd0281526004016103b990615b02565b601b54613bad908463ffffffff612aee16565b601b556001600160a01b038416600090815260196020526040902054613bd9908463ffffffff612aee16565b6001600160a01b038516600081815260196020526040908190209290925590517fb4c03061fb5b7fed76389d5af8f2e0ddb09f8c70d1333abbb62582835e10accb90613c2a90869086908690615d2f565b60405180910390a2836001600160a01b031660006001600160a01b0316600080516020615eab83398151915285604051613c64919061599d565b60405180910390a350505050565b600080613c808686856142ed565b9150613ca66b0a3098c68eb9427db8000000610a8986610a7d8a8763ffffffff61245f16565b905094509492505050565b81516020808401516040850151918401516060850151608086015160a087015160c08801519495946001600160a01b038616613e4657600854604051600160e01b63a9059cbb0281526001600160a01b039091169063a9059cbb90613d1c908b90859060040161593b565b602060405180830381600087803b158015613d3657600080fd5b505af1158015613d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613d6e9190810190614bb8565b613d8d57604051600160e51b62461bcd0281526004016103b990615be2565b80851115613e4157600854600554604051600160e01b63a9059cbb0281526001600160a01b039283169263a9059cbb92613dd092911690858a039060040161593b565b602060405180830381600087803b158015613dea57600080fd5b505af1158015613dfe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613e229190810190614bb8565b613e4157604051600160e51b62461bcd0281526004016103b990615b22565b613ef0565b600854600554604051600160e01b63a9059cbb0281526001600160a01b039283169263a9059cbb92613e7f92911690899060040161593b565b602060405180830381600087803b158015613e9957600080fd5b505af1158015613ead573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613ed19190810190614bb8565b613ef057604051600160e51b62461bcd0281526004016103b990615ac2565b821561415357341561404d576007546001600160a01b038881169116148015613f1857503483145b613f3757604051600160e51b62461bcd0281526004016103b990615bc2565b600760009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0846040518263ffffffff1660e01b81526004016000604051808303818588803b158015613f8757600080fd5b505af1158015613f9b573d6000803e3d6000fd5b5050600554604051600160e01b63a9059cbb0281526001600160a01b038c8116955063a9059cbb9450613fd7935090911690879060040161593b565b602060405180830381600087803b158015613ff157600080fd5b505af1158015614005573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506140299190810190614bb8565b61404857604051600160e51b62461bcd0281526004016103b990615b12565b614153565b6008546001600160a01b038881169116141561407a57614073848463ffffffff612aee16565b9350614153565b856001600160a01b0316876001600160a01b031614156140ab576140a4828463ffffffff612aee16565b9150614153565b600554604051600160e01b6323b872dd0281526001600160a01b03808a16926323b872dd926140e29233921690889060040161589a565b602060405180830381600087803b1580156140fc57600080fd5b505af1158015614110573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506141349190810190614bb8565b61415357604051600160e51b62461bcd0281526004016103b990615c22565b8315614233576008546001600160a01b03878116911614156141865761417f828563ffffffff612aee16565b9150614233565b600854600554604051600160e01b6323b872dd0281526001600160a01b03928316926323b872dd926141c292339290911690899060040161589a565b602060405180830381600087803b1580156141dc57600080fd5b505af11580156141f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506142149190810190614bb8565b61423357604051600160e51b62461bcd0281526004016103b990615ba2565b81156142e157600554604051600160e01b6323b872dd0281526001600160a01b03808916926323b872dd926142709233921690879060040161589a565b602060405180830381600087803b15801561428a57600080fd5b505af115801561429e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506142c29190810190614bb8565b6142e157604051600160e51b62461bcd0281526004016103b990615b72565b50505050505050505050565b600080614325856142ff57600061431c565b61431c85610a898868056bc75e2d6310000063ffffffff61245f16565b611a67866139c3565b90506000806804e1003b28d92800008311156143cf57614354836804e1003b28d928000063ffffffff612adc16565b9250678ac7230489e8000083111561437257678ac7230489e8000092505b6143936064610a89605a610a7d600b54600c54612aee90919063ffffffff16565b90506143c881611a67678ac7230489e80000610a896143bb68056bc75e2d6310000087612adc565b889063ffffffff61245f16565b93506144c1565b8480156143e457506804563918244f40000083105b156143f6576804563918244f40000092505b6802b5e3af16b188000083106144505761442e600b54611a6768056bc75e2d63100000610a89600c548861245f90919063ffffffff16565b600b54600c549195509250614449908363ffffffff612aee16565b90506144a5565b600061445a612e6b565b90506000614466614724565b905061448982611a6768056bc75e2d63100000610a89898663ffffffff61245f16565b955090925082906144a0818363ffffffff612aee16565b925050505b818410156144b5578193506144c1565b808411156144c1578093505b5050509392505050565b6001600160a01b03841660009081526019602052604090205483111561450657604051600160e51b62461bcd0281526004016103b990615bd2565b6001600160a01b03841660009081526019602052604090205461452f908463ffffffff612adc16565b6001600160a01b0385166000908152601960205260409020819055600a10614597576001600160a01b03841660009081526019602052604090205461457b90849063ffffffff612aee16565b6001600160a01b03851660009081526019602052604081205592505b601b546145aa908463ffffffff612adc16565b601b556040516001600160a01b038516907f743033787f4738ff4d6a7225ce2bd0977ee5f86b91a902a58f5e4d0b297b4644906145ec90869086908690615d2f565b60405180910390a260006001600160a01b0316846001600160a01b0316600080516020615eab83398151915285604051613c64919061599d565b600080614631614767565b506000858152600f6020908152604091829020825160c08101845281548152600182015492810192909252600281015492820183905260038101546060830152600481015460808301526005015460a0820152906146a457604051600160e51b62461bcd0281526004016103b990615ca2565b60408101516146d8906146ca90610a898868056bc75e2d6310000063ffffffff61245f16565b6146d2611b0e565b866142ed565b91506147198160400151610a896146f885856080015186604001516136c8565b610a8989701d6329f1c35ca4bfabb9f561000000000063ffffffff61245f16565b925050935093915050565b7f2b4858b1bc9e2d14afab03340ce5f6c81b703c86a0c570653ae586534e095fb15490565b6040518060e001604052806007906020820280388339509192915050565b6040518060c001604052806000801916815260200160008152602001600081526020016000815260200160008152602001600081525090565b8154818355818111156147cc576002028160020283600052602060002091820191016147cc91906147d1565b505050565b610c4591905b808211156147fc5780546001600160a01b0319168155600060018201556002016147d7565b5090565b8035610c2581615e84565b8051610c2581615e84565b8035610c2581615e98565b8051610c2581615e98565b8035610c2581615ea1565b600082601f83011261484857600080fd5b813561485b61485682615db4565b615d8d565b9150808252602083016020830185838301111561487757600080fd5b6136bf838284615e3e565b6000610140828403121561489557600080fd5b6148a0610140615d8d565b905060006148ae8484614800565b82525060206148bf84848301614800565b60208301525060406148d384828501614800565b60408301525060606148e784828501614800565b60608301525060806148fb8482850161482c565b60808301525060a061490f8482850161482c565b60a08301525060c06149238482850161482c565b60c08301525060e06149378482850161482c565b60e08301525061010061494c8482850161482c565b610100830152506101206149628482850161482c565b6101208301525092915050565b6000610160828403121561498257600080fd5b61498d610160615d8d565b9050600061499b8484614800565b82525060206149ac84848301614800565b60208301525060406149c084828501614800565b60408301525060606149d48482850161482c565b60608301525060806149e88482850161482c565b60808301525060a06149fc8482850161482c565b60a08301525060c0614a108482850161482c565b60c08301525060e0614a248482850161482c565b60e083015250610100614a398482850161482c565b61010083015250610120614a4f84828501614816565b61012083015250610140614a658482850161482c565b6101408301525092915050565b8051610c2581615ea1565b600060208284031215614a8f57600080fd5b6000611a7f8484614800565b600060208284031215614aad57600080fd5b6000611a7f848461480b565b60008060408385031215614acc57600080fd5b6000614ad88585614800565b9250506020614ae985828601614800565b9150509250929050565b600080600060608486031215614b0857600080fd5b6000614b148686614800565b9350506020614b2586828701614800565b9250506040614b368682870161482c565b9150509250925092565b60008060408385031215614b5357600080fd5b6000614b5f8585614800565b925050602083013567ffffffffffffffff811115614b7c57600080fd5b614ae985828601614837565b60008060408385031215614b9b57600080fd5b6000614ba78585614800565b9250506020614ae98582860161482c565b600060208284031215614bca57600080fd5b6000611a7f8484614821565b600060208284031215614be857600080fd5b6000611a7f848461482c565b60008060008060006103008688031215614c0d57600080fd5b6000614c198888614882565b955050610140614c2b8882890161496f565b9450506102a0614c3d88828901614800565b9350506102c0614c4f8882890161482c565b9250506102e0614c6188828901614816565b9150509295509295909350565b600060208284031215614c8057600080fd5b6000611a7f8484614a72565b60008060408385031215614c9f57600080fd5b6000614cab858561482c565b9250506020614ae985828601614816565b600080600060608486031215614cd157600080fd5b6000614cdd8686614a72565b9350506020614cee86828701614a72565b9250506040614b3686828701614a72565b60008060008060808587031215614d1557600080fd5b6000614d21878761482c565b9450506020614d328782880161482c565b9350506040614d438782880161482c565b9250506060614d5487828801614800565b91505092959194509250565b60008060008060808587031215614d7657600080fd5b6000614d828787614a72565b9450506020614d9387828801614a72565b9350506040614da487828801614a72565b9250506060614d5487828801614a72565b600080600080600080600060e0888a031215614dd057600080fd5b6000614ddc8a8a61482c565b9750506020614ded8a828b0161482c565b9650506040614dfe8a828b0161482c565b9550506060614e0f8a828b0161482c565b9450506080614e208a828b01614800565b93505060a0614e318a828b01614800565b92505060c088013567ffffffffffffffff811115614e4e57600080fd5b614e5a8a828b01614837565b91505092959891949750929550565b60008060008060008060008060006101208a8c031215614e8857600080fd5b6000614e948c8c61482c565b9950506020614ea58c828d0161482c565b9850506040614eb68c828d0161482c565b9750506060614ec78c828d0161482c565b9650506080614ed88c828d0161482c565b95505060a0614ee98c828d01614800565b94505060c0614efa8c828d01614800565b93505060e0614f0b8c828d01614800565b925050610100614f1d8c828d01614800565b9150509295985092959850929598565b6000806000806000806000806000806101408b8d031215614f4d57600080fd5b6000614f598d8d61482c565b9a50506020614f6a8d828e0161482c565b9950506040614f7b8d828e0161482c565b9850506060614f8c8d828e0161482c565b9750506080614f9d8d828e0161482c565b96505060a0614fae8d828e01614800565b95505060c0614fbf8d828e01614800565b94505060e0614fd08d828e01614800565b935050610100614fe28d828e01614800565b9250506101208b013567ffffffffffffffff81111561500057600080fd5b61500c8d828e01614837565b9150509295989b9194979a5092959850565b6000806000806000806000806000806101408b8d03121561503e57600080fd5b600061504a8d8d61482c565b9a5050602061505b8d828e0161482c565b995050604061506c8d828e0161482c565b985050606061507d8d828e0161482c565b975050608061508e8d828e0161482c565b96505060a0614fae8d828e0161482c565b60006150ab83836150ce565b505060200190565b60006150ab83836151d9565b6150c881615e1d565b82525050565b6150c881615dfb565b6150e081615de2565b6150ea8184610a98565b92506150f582610c45565b8060005b8381101561512357815161510d878261509f565b965061511883615ddc565b9250506001016150f9565b505050505050565b61513481615de8565b61513e8184610a98565b925061514982610c45565b8060005b8381101561512357815161516187826150b3565b965061516c83615ddc565b92505060010161514d565b600061518282615dee565b61518c8185615df2565b935061519783615ddc565b8060005b838110156151c55781516151af88826150b3565b97506151ba83615ddc565b92505060010161519b565b509495945050505050565b6150c881615e06565b6150c881610c45565b60006151ed82615dee565b6151f78185615df2565b9350615207818560208601615e4a565b61521081615e7a565b9093019392505050565b600061522582615dee565b61522f8185610a98565b935061523f818560208601615e4a565b9290920192915050565b6150c881615e28565b600061525f600183615df2565b600160fa1b600d02815260200192915050565b600061527f600283615df2565b600160f01b61323302815260200192915050565b60006152a0600283615df2565b600160f41b61031302815260200192915050565b60006152c1600283615df2565b600160f01b61313502815260200192915050565b60006152e2600283615df2565b600160f11b61189b02815260200192915050565b6000615303600183615df2565b600160f81b603302815260200192915050565b6000615323600183615df2565b600160f81b603702815260200192915050565b6000615343600283615df2565b600160f01b61323702815260200192915050565b6000615364600283615df2565b600160f21b610c4d02815260200192915050565b6000615385600283615df2565b600160f21b610c8d02815260200192915050565b60006153a6600283615df2565b600160f41b61032302815260200192915050565b60006153c7600f83615df2565b7f696e76616c696420616464726573730000000000000000000000000000000000815260200192915050565b6000615400600283615df2565b600160f01b61323902815260200192915050565b6000615421600283615df2565b600160f21b610ccd02815260200192915050565b6000615442600283615df2565b600160f01b61313102815260200192915050565b6000615463600283615df2565b600160f01b61313302815260200192915050565b6000615484600283615df2565b600160f11b61189902815260200192915050565b60006154a5600283615df2565b600160f01b61323502815260200192915050565b60006154c6600283615df2565b600160f11b61199902815260200192915050565b60006154e7600283615df2565b600160f01b61313702815260200192915050565b6000615508600283615df2565b600160f31b61062702815260200192915050565b6000615529600283615df2565b600160f01b61333102815260200192915050565b600061554a600283615df2565b600160f01b61313902815260200192915050565b600061556b600283615df2565b600160f31b61064702815260200192915050565b600061558c601a83615df2565b7f6275726e2076616c756520657863656564732062616c616e6365000000000000815260200192915050565b60006155c5600283615df2565b600160f11b61191b02815260200192915050565b60006155e6601483615df2565b7f696e73756666696369656e742062616c616e6365000000000000000000000000815260200192915050565b600061561f601483615df2565b7f66616c6c6261636b206e6f7420616c6c6f776564000000000000000000000000815260200192915050565b6000615658600183615df2565b600160f91b601902815260200192915050565b6000615678600283615df2565b600160f41b61033302815260200192915050565b6000610c25600083610a98565b60006156a6600183615df2565b600160f81b603102815260200192915050565b60006156c6600183615df2565b600160f81b603502815260200192915050565b60006156e6600183615df2565b600160f81b603902815260200192915050565b6000615706600283615df2565b600160f11b61191902815260200192915050565b6000615727600c83615df2565b7f6e6f6e5265656e7472616e740000000000000000000000000000000000000000815260200192915050565b6000615760600183615df2565b600160f91b601b02815260200192915050565b6000615780600183615df2565b600160fb1b600702815260200192915050565b60006157a0600283615df2565b600160f01b61333302815260200192915050565b60006157c1600283615df2565b600160f01b61323102815260200192915050565b60006157e2601183615df2565b7f626f72726f77416d6f756e74203d3d2030000000000000000000000000000000815260200192915050565b6150c881615e17565b6000610f2c828461521a565b6000610c258261568c565b60208101610c2582846150ce565b60208101610c2582846150bf565b6060810161585882866150bf565b61586560208301856150bf565b611a7f60408301846151d9565b6060810161588082866150bf565b61588d60208301856150ce565b611a7f60408301846150ce565b606081016158a882866150bf565b61586560208301856150ce565b604081016158c382856150ce565b610f2c60208301846150ce565b60a081016158de82886150ce565b6158eb60208301876150ce565b6158f860408301866150ce565b61590560608301856151d9565b612c2960808301846151d9565b606081016158a882866150ce565b6040810161592e82856150ce565b610f2c6020830184615249565b6040810161594982856150ce565b610f2c60208301846151d9565b6060810161596482866150ce565b61597160208301856151d9565b611a7f60408301846151d0565b60208082528101610f2c8184615177565b60208101610c2582846151d0565b60208101610c2582846151d9565b61018081016159ba82876151d9565b6159c760208301866150d7565b6159d4608083018561512b565b818103610160830152612c2981846151e2565b60c081016159f582896151d9565b615a0260208301886151d9565b615a0f60408301876151d9565b615a1c60608301866151d9565b615a2960808301856151d9565b615a3660a08301846151d9565b979650505050505050565b60208082528101610f2c81846151e2565b60208082528101610a9581615252565b60208082528101610a9581615272565b60208082528101610a9581615293565b60208082528101610a95816152b4565b60208082528101610a95816152d5565b60208082528101610a95816152f6565b60208082528101610a9581615316565b60208082528101610a9581615336565b60208082528101610a9581615357565b60208082528101610a9581615378565b60208082528101610a9581615399565b60208082528101610a95816153ba565b60208082528101610a95816153f3565b60208082528101610a9581615414565b60208082528101610a9581615435565b60208082528101610a9581615456565b60208082528101610a9581615477565b60208082528101610a9581615498565b60208082528101610a95816154b9565b60208082528101610a95816154da565b60208082528101610a95816154fb565b60208082528101610a958161551c565b60208082528101610a958161553d565b60208082528101610a958161555e565b60208082528101610a958161557f565b60208082528101610a95816155b8565b60208082528101610a95816155d9565b60208082528101610a9581615612565b60208082528101610a958161564b565b60208082528101610a958161566b565b60208082528101610a9581615699565b60208082528101610a95816156b9565b60208082528101610a95816156d9565b60208082528101610a95816156f9565b60208082528101610a958161571a565b60208082528101610a9581615753565b60208082528101610a9581615773565b60208082528101610a9581615793565b60208082528101610a95816157b4565b60208082528101610a95816157d5565b60408101615ce082856151d9565b610f2c60208301846151d0565b60a08101615cfb82886151d9565b615d0860208301876151d9565b615d1560408301866150ce565b615d2260608301856150ce565b612c2960808301846151d0565b60608101615d3d82866151d9565b61586560208301856151d9565b60808101615d5882876151d9565b615d6560208301866151d9565b615d7260408301856151d9565b610f4160608301846151d9565b60208101610c25828461580e565b60405181810167ffffffffffffffff81118282101715615dac57600080fd5b604052919050565b600067ffffffffffffffff821115615dcb57600080fd5b506020601f91909101601f19160190565b60200190565b50600390565b50600790565b5190565b90815260200190565b6000610a9582615e0b565b151590565b6001600160a01b031690565b60ff1690565b6000610a9582615e33565b6000610a9582610c45565b6000610a9582615dfb565b82818337506000910152565b60005b83811015615e65578181015183820152602001615e4d565b83811115615e74576000848401525b50505050565b601f01601f191690565b615e8d81615dfb565b81146123c757600080fd5b615e8d81615e06565b615e8d81610c4556feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa265627a7a723058200725eca12df935cc7620fa4d6a3b0c229ad5188b26747029c507f11779ab374d6c6578706572696d656e74616cf50037

Deployed Bytecode Sourcemap

15187:50367:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15563:12;;-1:-1:-1;;;;;15563:12:0;15549:10;:26;15527:96;;;;-1:-1:-1;;;;;15527:96:0;;;;;;;;;;;;;;;;;15187:50367;34743:213;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;34743:213:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;5818:18;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5818:18:0;;;:::i;:::-;;;;;;;;26700:488;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26700:488:0;;;:::i;9889:248::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;9889:248:0;;;;;;;;:::i;:::-;;;;;;;;31584:210;;8:9:-1;5:2;;;30:1;27;20:12;5:2;31584:210:0;;;:::i;8218:33::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8218:33:0;;;:::i;9320:123::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9320:123:0;;;:::i;23389:790::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;23389:790:0;;;;;;;;:::i;8516:27::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8516:27:0;;;:::i;7337:45::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7337:45:0;;;:::i;8339:31::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8339:31:0;;;:::i;28989:1147::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;28989:1147:0;;;;;;;;:::i;36331:575::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;36331:575:0;;;;;;;;:::i;7884:50::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;7884:50:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;64940:611;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;64940:611:0;;;;;;;;:::i;34544:136::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;34544:136:0;;;:::i;:::-;;;;;;;;5870:21;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5870:21:0;;;:::i;:::-;;;;;;;;7397:52;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7397:52:0;;;:::i;15981:255::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;15981:255:0;;;;;;;;:::i;31901:276::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;31901:276:0;;;:::i;5994:27::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5994:27:0;;;:::i;:::-;;;;;;;;17260:2805;;;;;;;;;:::i;27554:481::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;27554:481:0;;;;;;;;:::i;30970:518::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;30970:518:0;;;:::i;30795:167::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;30795:167:0;;;:::i;27196:185::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;27196:185:0;;;:::i;9451:149::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;9451:149:0;;;;;;;;:::i;7296:32::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7296:32:0;;;:::i;8020:44::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;8020:44:0;;;;;;;;:::i;:::-;;;;;;;;;6030:31;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6030:31:0;;;:::i;8435:::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8435:31:0;;;:::i;32951:314::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;32951:314:0;;;;;;;;:::i;30181:430::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;30181:430:0;;;:::i;16244:552::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;16244:552:0;;;;;;;;:::i;33968:568::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;33968:568:0;;;;;;;;:::i;32276:252::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32276:252:0;;;:::i;34964:1359::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;34964:1359:0;;;;;;;;:::i;5933:23::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5933:23:0;;;:::i;3327:20::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3327:20:0;;;:::i;15671:302::-;;;;;;;;;:::i;33543:417::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33543:417:0;;;:::i;5843:20::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5843:20:0;;;:::i;5963:24::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5963:24:0;;;:::i;5900:26::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;5900:26:0;;;:::i;7982:29::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;7982:29:0;;;;;;;;:::i;21385:1224::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;21385:1224:0;;;;;;;;:::i;16804:448::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;16804:448:0;;;;;;;;:::i;28043:938::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;28043:938:0;;;;;;;;:::i;32657:286::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;32657:286:0;;;;;;;;:::i;62971:1925::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;62971:1925:0;;;;;;;;:::i;33273:262::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;33273:262:0;;;;;;;;:::i;7741:31::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7741:31:0;;;:::i;9608:185::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;9608:185:0;;;;;;;;:::i;30619:168::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;30619:168:0;;;;;;;;:::i;3958:105::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3958:105:0;;;;;;;;:::i;55954:359::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;55954:359:0;;;;;;;;:::i;8097:64::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;8097:64:0;;;;;;;;:::i;:::-;;;;;;;;;7781:51;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;7781:51:0;;;;;;;;:::i;22617:764::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;22617:764:0;;;;;;;;:::i;34743:213::-;34841:7;34873:75;34941:6;34873:49;34909:12;:10;:12::i;:::-;34873:17;34883:6;34873:9;:17::i;:::-;:35;:49;:35;:49;:::i;:::-;:67;:75;:67;:75;:::i;:::-;34866:82;;34743:213;;;;:::o;5818:18::-;;;;;;;;;;;;;;-1:-1:-1;;5818:18:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;26700:488::-;26784:21;4860:1;5528:14;;:39;5520:64;;;;-1:-1:-1;;;;;5520:64:0;;;;;;;;;4964:1;5591:14;:40;26839:27;26855:10;26839:15;:27::i;:::-;26883:21;:28;26823:43;;-1:-1:-1;26883:33:0;26879:302;;26933:27;26957:1;26933:15;:27::i;:::-;-1:-1:-1;27008:10:0;26981:38;;;;:26;:38;;;;;:44;;;;;:77;;;;-1:-1:-1;27029:15:0;;-1:-1:-1;;;;;27029:15:0;27048:10;27029:29;;26981:77;26977:193;;;27126:15;:28;;-1:-1:-1;;;;;;27126:28:0;27144:10;27126:28;;;26977:193;4860:1;5646:14;:38;26700:488;:::o;9889:248::-;10023:10;9993:4;10015:19;;;:7;:19;;;;;;;;-1:-1:-1;;;;;10015:29:0;;;;;;;;;;:38;;;10069;9993:4;;10015:29;;10069:38;;;;10047:6;;10069:38;;;;;;;;;;-1:-1:-1;10125:4:0;9889:248;;;;;:::o;31584:210::-;31662:7;31691:16;;31711:1;31691:21;31687:100;;31736:39;31756:18;:16;:18::i;31736:39::-;31729:46;;31687:100;31584:210;:::o;8218:33::-;;;;:::o;9320:123::-;9423:12;;9320:123;:::o;23389:790::-;23796:21;23842:329;23880:13;23908:14;23937:13;23965:19;23999:14;24028:6;24049:19;24083:22;24120:17;24152:8;23842:23;:329::i;:::-;23835:336;23389:790;-1:-1:-1;;;;;;;;;;;23389:790:0:o;8516:27::-;;;;:::o;7337:45::-;;;;:::o;8339:31::-;;;;:::o;28989:1147::-;-1:-1:-1;;;;;29165:14:0;;29117:4;29165:14;;;:7;:14;;;;;;;;29180:10;29165:26;;;;;;;;29220:15;;;:8;:15;;;;;;29117:4;;29165:26;29210:25;;;29202:40;;;;-1:-1:-1;;;;;29202:40:0;;;;;;;;;29271:15;29261:6;:25;;29253:40;;;;-1:-1:-1;;;;;29253:40:0;;;;;;;;;-1:-1:-1;;;;;29312:17:0;;29304:32;;;;-1:-1:-1;;;;;29304:32:0;;;;;;;;;-1:-1:-1;;;;;29367:15:0;;;;;;:8;:15;;;;;;:27;;29387:6;29367:27;:19;:27;:::i;:::-;-1:-1:-1;;;;;29349:15:0;;;;;;;:8;:15;;;;;;:45;;;;29421:13;;;;;;;:25;;29439:6;29421:25;:17;:25;:::i;:::-;-1:-1:-1;;;;;29405:13:0;;;;;;:8;:13;;;;;:41;-1:-1:-1;;29461:26:0;;29457:115;;;29533:27;:15;29553:6;29533:27;:19;:27;:::i;:::-;-1:-1:-1;;;;;29504:14:0;;;;;;:7;:14;;;;;;;;29519:10;29504:26;;;;;;;:56;29457:115;29621:20;29644:12;:10;:12::i;:::-;-1:-1:-1;;;;;29671:33:0;;;;;;:26;:33;;;;;:39;;;29621:35;;-1:-1:-1;29671:39:0;;;:63;;-1:-1:-1;;;;;;29714:15:0;;;;;;:8;:15;;;;;;:20;;29671:63;29667:196;;;-1:-1:-1;;;;;29751:24:0;;;;;;:17;:24;;;;;:39;;;29667:196;;;-1:-1:-1;;;;;29823:24:0;;29850:1;29823:24;;;:17;:24;;;;;:28;29667:196;-1:-1:-1;;;;;29877:31:0;;;;;;:26;:31;;;;;:37;;;;;;:59;;-1:-1:-1;;;;;;29918:13:0;;;;;;:8;:13;;;;;;:18;;29877:59;29873:188;;;-1:-1:-1;;;;;29953:22:0;;;;;;:17;:22;;;;;:37;;;29873:188;;;-1:-1:-1;;;;;30023:22:0;;30048:1;30023:22;;;:17;:22;;;;;:26;29873:188;30094:3;-1:-1:-1;;;;;30078:28:0;30087:5;-1:-1:-1;;;;;30078:28:0;-1:-1:-1;;;;;;;;;;;30099:6:0;30078:28;;;;;;;;;;;;;;;30124:4;30117:11;;;;28989:1147;;;;;;:::o;36331:575::-;36680:20;36733:165;36774:13;36802:14;36831:19;36865:22;36733:26;:165::i;:::-;36718:180;36331:575;-1:-1:-1;;;;;36331:575:0:o;7884:50::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;64940:611::-;3770:5;;-1:-1:-1;;;;;3770:5:0;3756:10;:19;3748:28;;;;;;65104:7;;;-1:-1:-1;;;;;65122:24:0;;;-1:-1:-1;;;;;;65122:24:0;;;;;;65176:27;;65104:7;;;65080:21;;65184:4;;65176:27;;65195:7;;65176:27;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;-1:-1;;65334:4:0;65328:11;65159:44;;-1:-1:-1;65293:14:0;;;65216:12;65328:11;65353:28;65398:13;65395:2;;65426:4;65421:3;65414:17;65395:2;65456:7;:23;;-1:-1:-1;;;;;;65456:23:0;-1:-1:-1;;;;;65456:23:0;;;;;65528:4;65523:3;65516:17;34544:136;34619:16;34660:12;34653:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34544:136;:::o;5870:21::-;;;;;;:::o;7397:52::-;;;;:::o;15981:255::-;16113:18;4860:1;5528:14;;:39;5520:64;;;;-1:-1:-1;;;;;5520:64:0;;;;;;;;;4964:1;5591:14;:40;16156:72;16181:8;16204:13;16156:10;:72::i;:::-;16149:79;;5638:1;4860;5646:14;:38;15981:255;;-1:-1:-1;;15981:255:0:o;31901:276::-;31982:7;32011:16;;32031:1;32011:21;32007:163;;32056:41;32078:18;:16;:18::i;:::-;32056:21;:41::i;32007:163::-;32137:21;:19;:21::i;5994:27::-;;;-1:-1:-1;;;;;5994:27:0;;:::o;17260:2805::-;17754:21;4860:1;5528:14;;:39;5520:64;;;;-1:-1:-1;;;;;5520:64:0;;;;;;;;;4964:1;5591:14;:40;17817:9;:14;:54;;;;-1:-1:-1;;;;;;17835:36:0;;;;17817:54;:82;;;;-1:-1:-1;17875:24:0;;;17817:82;17816:229;;;-1:-1:-1;17918:9:0;:14;;;;:98;;-1:-1:-1;;;;;;17937:36:0;;;;:78;;-1:-1:-1;18003:12:0;;-1:-1:-1;;;;;17977:38:0;;;18003:12;;17977:38;17937:78;17918:126;;;;-1:-1:-1;18020:24:0;;17918:126;17793:282;;;;-1:-1:-1;;;;;17793:282:0;;;;;;;;;-1:-1:-1;18104:31:0;;;;:15;:31;;;;;;18154:18;18146:32;;;;-1:-1:-1;;;;;18146:32:0;;;;;;;;;18191:17;:15;:17::i;:::-;18221:29;;:::i;:::-;18263:26;18292:28;;;:13;:28;;;;;:56;;;:61;18370:9;:14;18366:130;;18426:12;;18475:9;;-1:-1:-1;;;;;;18426:12:0;;-1:-1:-1;18366:130:0;18512:17;18508:492;;18561:191;18606:19;18644:14;18677:19;18715:22;18561:26;:191::i;:::-;18546:206;-1:-1:-1;18775:17:0;18767:47;;;;-1:-1:-1;;;;;18767:47:0;;;;;;;;;18864:14;;;:29;;;18508:492;;;18959:14;;;:29;;;18508:492;19141:197;19181:12;19208:20;19226:1;19208:17;:20::i;:::-;19272:19;19306:21;19141:25;:197::i;:::-;19109:14;;;;19092:246;;;;;;;19368:634;;;;;;;-1:-1:-1;;;;;19368:634:0;;;;;;;19093:14;19368:634;;;;;;;-1:-1:-1;19368:634:0;;;;;;;;;;;19601:14;;19368:634;;;;;;;;19092:246;;-1:-1:-1;19368:634:0;;19406:13;;19368:634;;19109:14;19701:1;19689:14;;;;19368:634;;;;19755:1;19368:634;;;;19813:19;19368:634;;;;19851:1;19368:634;;;;19910:11;19922:1;19910:14;;;;;;;;;;;19368:634;;19983:8;19368:23;:634::i;:::-;19351:14;;;:651;;;20021:30;;20013:44;;;;-1:-1:-1;;;;;20013:44:0;;;;;;;;;-1:-1:-1;;4860:1:0;5646:14;:38;17260:2805;;-1:-1:-1;;;;;;;17260:2805:0:o;27554:481::-;27683:16;;27641:4;;-1:-1:-1;;;;;27667:32:0;;;27683:16;;27667:32;27663:63;;;-1:-1:-1;27721:5:0;27714:12;;27663:63;27757:44;;-1:-1:-1;;;;;27757:44:0;;27739:15;;-1:-1:-1;;;;;27757:29:0;;;;;:44;;27795:4;;27757:44;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;27757:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27757:44:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;27757:44:0;;;;;;;;;27739:62;-1:-1:-1;27816:12:0;27812:43;;27850:5;27843:12;;;;;27812:43;27924:11;;;27953:9;;27919:44;;-1:-1:-1;;;;;27919:44:0;;-1:-1:-1;;;;;27876:28:0;;;;;;27924:11;;;;;;27919:33;;:44;;27953:9;;;;27919:44;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;27919:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27919:44:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;27919:44:0;;;;;;;;;27978:7;27876:120;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;27876:120:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27876:120:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;27876:120:0;;;;;;;;;27868:135;;;;-1:-1:-1;;;;;27868:135:0;;;;;;;;;-1:-1:-1;28023:4:0;;27554:481;-1:-1:-1;;27554:481:0:o;30970:518::-;31045:7;31070:19;31092:18;:16;:18::i;:::-;31070:40;;31121:22;31146:21;:19;:21::i;:::-;31121:46;;31196:14;31182:11;:28;31178:147;;;31241:31;:11;31257:14;31241:31;:15;:31;:::i;:::-;31227:45;;31178:147;;;31312:1;31305:8;;;;;;31178:147;31355:16;;31341:11;:30;31337:144;;;31411:16;;31395:33;;:11;;:33;:15;:33;:::i;:::-;31388:40;;;;;;30795:167;30874:7;30906:48;30947:6;30906:36;30929:12;:10;:12::i;:::-;30906:18;;;:36;:22;:36;:::i;27196:185::-;27261:4;27253:21;:26;27249:125;;27310:12;;27296:66;;;-1:-1:-1;;;;;27296:66:0;;;;-1:-1:-1;;;;;27310:12:0;;;;27296:35;;27346:4;27338:21;;27296:66;;;;;27310:12;;27296:66;;;;;;;27338:21;27310:12;27296:66;;;5:2:-1;;;;30:1;27;20:12;5:2;27296:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27296:66:0;;;;;27249:125;27196:185::o;9451:149::-;-1:-1:-1;;;;;9576:16:0;9544:7;9576:16;;;:8;:16;;;;;;;9451:149::o;7296:32::-;;;;;;-1:-1:-1;;;;;7296:32:0;;:::o;8020:44::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;8020:44:0;;;;-1:-1:-1;8020:44:0;:::o;6030:31::-;;;-1:-1:-1;;;;;6030:31:0;;:::o;8435:::-;;;;:::o;32951:314::-;33110:7;33142:115;33180:12;33225:21;33142:23;:115::i;30181:430::-;30251:13;30282:22;30338:15;30319;;:34;30315:223;;30391:17;:15;:17::i;:::-;30479:16;;30370:38;;-1:-1:-1;30442:84:0;;-1:-1:-1;30519:6:0;;-1:-1:-1;30442:54:0;;30370:38;;30442:54;:36;:54;:::i;:84::-;30425:101;;30315:223;30557:46;30569:33;30587:14;30569:17;:33::i;:::-;30557:11;:46::i;:::-;30550:53;;;30181:430;:::o;16244:552::-;16380:22;4860:1;5528:14;;:39;5520:64;;;;-1:-1:-1;;;;;5520:64:0;;;;;;;;;4964:1;5591:14;:40;16448:12;;16428:16;;-1:-1:-1;;;;;16428:16:0;;;16448:12;;16428:32;16420:46;;;;-1:-1:-1;;;;;16420:46:0;;;;;;;;;16494:69;16519:8;16542:10;16494;:69::i;:::-;16477:86;-1:-1:-1;16580:19:0;;16576:213;;16630:12;;16616:52;;-1:-1:-1;;;;;16616:52:0;;-1:-1:-1;;;;;16630:12:0;;;;16616:36;;:52;;16653:14;;16616:52;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;16616:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;16616:52:0;;;;16684:12;16702:8;-1:-1:-1;;;;;16702:13:0;16722:14;16702:39;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;16683:58:0;;;16764:7;16756:21;;;;-1:-1:-1;;;;;16756:21:0;;;;;;;;;16576:213;4860:1;5646:14;:38;16244:552;;-1:-1:-1;;16244:552:0:o;33968:568::-;34078:7;34103:24;;:::i;:::-;-1:-1:-1;34130:46:0;34144:31;;;:15;:31;;;;;;;;;34130:46;;:13;:46;;;;;;34103:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34187:60;;34246:1;34239:8;;;;;34187:60;34267:261;34351:176;34382:6;34443:8;:36;;;34498:8;:28;;;34351:12;:176::i;:::-;34267:65;34303:8;:28;;;34267:17;:15;:17::i;32276:252::-;32354:7;32386:134;32424:1;32469:5;32386:23;:134::i;34964:1359::-;35312:21;35355:17;;35351:965;;35389:20;35426:31;;;:15;:31;;;;;;;;;35412:46;;:13;:46;;;;;:66;;;:96;;35501:6;35412:96;:88;:96;:::i;:::-;35389:119;;35640:120;35753:6;35640:90;35675:54;35709:19;35675:33;:54::i;:::-;35640:12;;:90;:34;:90;:::i;:120::-;35625:135;;35792:33;35812:12;35792:19;:33::i;:::-;35777:48;-1:-1:-1;35844:17:0;35840:66;;35889:1;35882:8;;;;;35840:66;35934:11;;35987:16;;35929:282;;36208:2;;-1:-1:-1;;;;;35934:11:0;;;;;;;35929:39;;35987:16;;;36022:36;;:76;;36086:12;;-1:-1:-1;;;;;36086:12:0;36022:76;;;36061:22;36022:76;36117:9;;35929:274;;;;;;;;;;;;;-1:-1:-1;;;;;36117:9:0;;36145:12;;36176;;35929:274;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;35929:274:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;35929:274:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;35929:274:0;;;;;;;;;:278;:282;:278;:282;:::i;:::-;35922:289;;;;;35351:965;-1:-1:-1;36303:1:0;35351:965;34964:1359;;;;;;:::o;5933:23::-;;;-1:-1:-1;;;;;5933:23:0;;:::o;3327:20::-;;;-1:-1:-1;;;;;3327:20:0;;:::o;15671:302::-;15797:18;4860:1;5528:14;;:39;5520:64;;;;-1:-1:-1;;;;;5520:64:0;;;;;;;;;4964:1;5591:14;:40;15861:12;;15841:16;;-1:-1:-1;;;;;15841:16:0;;;15861:12;;15841:32;15833:46;;;;-1:-1:-1;;;;;15833:46:0;;;;;;;;;15897:68;15922:8;15945:9;15897:10;:68::i;33543:417::-;33619:7;33644:22;33700:15;33681;;:34;33677:223;;33753:17;:15;:17::i;:::-;33841:16;;33732:38;;-1:-1:-1;33804:84:0;;-1:-1:-1;33881:6:0;;-1:-1:-1;33804:54:0;;33732:38;;33804:54;:36;:54;:::i;:84::-;33787:101;;33677:223;33919:33;33937:14;33919:17;:33::i;5843:20::-;;;;;;;;;;;;;;;-1:-1:-1;;5843:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5963:24;;;-1:-1:-1;;;;;5963:24:0;;:::o;5900:26::-;;;;;;-1:-1:-1;;;;;5900:26:0;;:::o;7982:29::-;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7982:29:0;:::o;21385:1224::-;21812:21;4860:1;5528:14;;:39;5520:64;;;;-1:-1:-1;;;;;5520:64:0;;;;;;;;;4964:1;5591:14;:40;-1:-1:-1;;;;;21859:36:0;;;;;;:144;;-1:-1:-1;;;;;;21913:31:0;;;;:89;;-1:-1:-1;21986:16:0;;-1:-1:-1;;;;;21965:37:0;;;21986:16;;21965:37;;21913:89;21851:181;;;;-1:-1:-1;;;;;21851:181:0;;;;;;;;;22061:540;22094:14;22061:540;;;;;;;;22142:8;-1:-1:-1;;;;;22061:540:0;-1:-1:-1;;;;;22061:540:0;;;;;22169:22;-1:-1:-1;;;;;22061:540:0;-1:-1:-1;;;;;22061:540:0;;;;;22210:17;-1:-1:-1;;;;;22061:540:0;-1:-1:-1;;;;;22061:540:0;;;;;;;;;;;;22276:1;22061:540;;;;22326:12;22061:540;;;;22357:21;22061:540;;;;22397:13;22061:540;;;;22429:19;22061:540;;;;22467:14;22061:540;;;;22500:12;22061:540;;;22542:5;22582:8;22061:18;:540::i;:::-;4860:1;5646:14;:38;22045:556;21385:1224;-1:-1:-1;;;;;;;;;;;21385:1224:0:o;16804:448::-;16933:22;4860:1;5528:14;;:39;5520:64;;;;-1:-1:-1;;;;;5520:64:0;;;;;;;;;4964:1;5591:14;:40;16990:69;17015:8;17038:10;16990;:69::i;:::-;16973:86;-1:-1:-1;17076:19:0;;17072:173;;17126:16;;17120:107;;-1:-1:-1;;;;;17120:107:0;;-1:-1:-1;;;;;17126:16:0;;;;17120:32;;:107;;17171:8;;17198:14;;17120:107;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;17120:107:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;17120:107:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;17120:107:0;;;;;;;;;17112:121;;;;-1:-1:-1;;;;;17112:121:0;;;;;;;;28043:938;28192:10;28143:4;28183:20;;;:8;:20;;;;;;28173:30;;;28165:63;;;;-1:-1:-1;;;;;28165:63:0;;;;;;;;;-1:-1:-1;;;;;28247:17:0;;28239:32;;;;-1:-1:-1;;;;;28239:32:0;;;;;;;;;28316:10;28307:20;;;;:8;:20;;;;;;:32;;28332:6;28307:32;:24;:32;:::i;:::-;28293:10;28284:20;;;;:8;:20;;;;;;:55;;;;-1:-1:-1;;;;;28366:13:0;;;;;;:25;;28384:6;28366:25;:17;:25;:::i;:::-;-1:-1:-1;;;;;28350:13:0;;;;;;:8;:13;;;;;:41;;;;28464:12;:10;:12::i;:::-;28518:10;28491:38;;;;:26;:38;;;;;:44;;;28441:35;;-1:-1:-1;28491:44:0;;;:73;;-1:-1:-1;28548:10:0;28539:20;;;;:8;:20;;;;;;:25;;28491:73;28487:216;;;28599:10;28581:29;;;;:17;:29;;;;;:44;;;28487:216;;;28676:10;28690:1;28658:29;;;:17;:29;;;;;:33;28487:216;-1:-1:-1;;;;;28717:31:0;;;;;;:26;:31;;;;;:37;;;;;;:59;;-1:-1:-1;;;;;;28758:13:0;;;;;;:8;:13;;;;;;:18;;28717:59;28713:188;;;-1:-1:-1;;;;;28793:22:0;;;;;;:17;:22;;;;;:37;;;28713:188;;;-1:-1:-1;;;;;28863:22:0;;28888:1;28863:22;;;:17;:22;;;;;:26;28713:188;28939:3;-1:-1:-1;;;;;28918:33:0;28927:10;-1:-1:-1;;;;;28918:33:0;-1:-1:-1;;;;;;;;;;;28944:6:0;28918:33;;;;;;;;;;;;;;;-1:-1:-1;28969:4:0;;28043:938;-1:-1:-1;;;28043:938:0:o;32657:286::-;32769:7;32801:134;32839:12;32884:5;32801:23;:134::i;62971:1925::-;15390:11;;;15419:9;;15385:44;;-1:-1:-1;;;;;15385:44:0;;63243:4;;-1:-1:-1;;;;;15390:11:0;;;;;;;15385:33;;:44;;15419:9;;;15385:44;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;15385:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;15385:44:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;15385:44:0;;;;;;;;;-1:-1:-1;;;;;15371:58:0;:10;-1:-1:-1;;;;;15371:58:0;;15363:72;;;;-1:-1:-1;;;;;15363:72:0;;;;;;;;;63265:24;;:::i;:::-;-1:-1:-1;63306:23:0;;;;;63292:38;;;;:13;:38;;;;;;;;;63265:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63371:23;;63265:65;;63345:49;63341:1548;;;63451:11;63432:16;;:30;:87;;63518:1;63432:87;;;63482:16;;:33;;63503:11;63482:33;:20;:33;:::i;:::-;63413:16;:106;63627:19;;63565:23;;;;63541:312;;-1:-1:-1;;;;;63541:312:0;;;;;;;;63684:10;;63739:11;;63794:13;;63541:312;;;;;;;;;;63874:21;:28;:33;63870:159;;63928:27;63952:1;63928:15;:27::i;:::-;;63870:159;;;63996:17;:15;:17::i;:::-;64049:16;64045:50;;64091:4;64084:11;;;;;64045:50;64215:20;64233:1;64215:17;:20::i;:::-;64196:16;:39;64270:19;;-1:-1:-1;;;;;64256:33:0;;;;;;64252:553;;64333:17;;64386:19;;64314:154;;-1:-1:-1;;;;;64314:154:0;;64333:17;;;;-1:-1:-1;;;;;64333:17:0;;64314:49;;:154;;64428:1;;64314:154;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64314:154:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64314:154:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;64314:154:0;;;;;;;;;64310:480;;;64494:12;64511;:19;;;-1:-1:-1;;;;;64511:24:0;64670:4;64562:155;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;64562:155:0;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;179:29;160:49;;64511:229:0;;;64562:155;64511:229;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;-1:-1;;;;64310:480:0;64828:4;64821:11;;;;;63341:1548;-1:-1:-1;64872:5:0;;62971:1925;-1:-1:-1;;;;;;62971:1925:0:o;33273:262::-;33385:7;33414:16;;33434:1;33414:21;33410:118;;33459:57;33479:36;33502:12;33479:18;:16;:18::i;33459:57::-;33452:64;;;;7741:31;;;;:::o;9608:185::-;-1:-1:-1;;;;;9760:15:0;;;9728:7;9760:15;;;:7;:15;;;;;;;;:25;;;;;;;;;;;;;9608:185::o;30619:168::-;-1:-1:-1;;;;;30755:24:0;30717:13;30755:24;;;:17;:24;;;;;;;30619:168::o;3958:105::-;3770:5;;-1:-1:-1;;;;;3770:5:0;3756:10;:19;3748:28;;;;;;4028:29;4047:9;4028:18;:29::i;:::-;3958:105;:::o;55954:359::-;56062:7;56091:16;;56111:1;56091:21;56087:219;;56136:117;56246:6;56136:87;56193:29;56210:11;56193:16;:29::i;:::-;56136:34;56158:11;56136:21;:34::i;56087:219::-;-1:-1:-1;56293:1:0;56286:8;;8097:64;;;;;;;;;;;;;;;;;;;;;:::o;7781:51::-;;;;;;;;;;;;;:::o;22617:764::-;22992:21;23038:335;23076:13;23104:14;23133:13;23161:19;23195:14;23224:6;23245:19;23279:22;23316:17;23038:335;;;;;;;;;;;;:23;:335::i;:::-;23031:342;22617:764;-1:-1:-1;;;;;;;;;;22617:764:0:o;1642:391::-;1702:9;1932:7;1928:38;;-1:-1:-1;1957:1:0;1950:8;;1928:38;-1:-1:-1;1978:7:0;;;1983:2;1978;:7;:2;1999:6;;;;;:12;1992:20;;;2120:288;2180:7;2400:2;2395;:7;;;;;;;2120:288;-1:-1:-1;;;2120:288:0:o;44286:2270::-;44373:7;44398:17;:15;:17::i;:::-;-1:-1:-1;;;;;44432:20:0;;44428:62;;44476:14;:12;:14::i;:::-;44467:23;;44428:62;-1:-1:-1;;;;;44508:34:0;;;;;;:26;:34;;;;;:40;;;;;44503:68;;-1:-1:-1;44570:1:0;44563:8;;44503:68;-1:-1:-1;;;;;44600:34:0;;44584:13;44600:34;;;:26;:34;;;;;:40;;44674:33;44686:20;44584:13;44686:17;:20::i;44674:33::-;44651:56;;44720:19;44742:65;44800:6;44742:53;44782:12;44742:21;44764:5;44742:28;;;;;;;;;;;;;;;;;;:35;;;:39;;:53;;;;:::i;:65::-;44720:87;-1:-1:-1;44822:16:0;44818:43;;44860:1;44853:8;;;;;;;44818:43;44906:16;;44900:48;;-1:-1:-1;;;;;44900:48:0;;44874:23;;-1:-1:-1;;;;;44906:16:0;;44900:33;;:48;;44942:4;;44900:48;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;44900:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;44900:48:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;44900:48:0;;;;;;;;;44874:74;-1:-1:-1;44963:20:0;44959:61;;45007:1;45000:8;;;;;;;;44959:61;45032:24;45086:15;45071:11;:30;45067:672;;45137:21;45159:5;45137:28;;;;;;;;;;;;;;;;;;:35;;;45118:54;;45187:30;45203:6;45211:5;45187:15;:30::i;:::-;45067:672;;;45264:15;;-1:-1:-1;45264:15:0;;45313:41;45341:12;45313:23;45264:15;45329:6;45313:23;:15;:23;:::i;:41::-;45294:60;;45490:21;45512:5;45490:28;;;;;;;;;;;;;;;;;;:35;;;45463:24;45484:2;45463:16;:20;;:24;;;;:::i;:::-;:62;45459:269;;;45584:57;45624:16;45584:21;45606:5;45584:28;;;;;;;;;;;;;;;;;;:35;;;:39;;:57;;;;:::i;:::-;45546:21;45568:5;45546:28;;;;;;;;;;;;;;;;;;:35;;:95;;;;45459:269;;;45682:30;45698:6;45706:5;45682:15;:30::i;:::-;45765:16;;45759:90;;-1:-1:-1;;;;;45759:90:0;;-1:-1:-1;;;;;45765:16:0;;;;45759:32;;:90;;45806:6;;45827:11;;45759:90;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;45759:90:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;45759:90:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;45759:90:0;;;;;;;;;45751:105;;;;-1:-1:-1;;;;;45751:105:0;;;;;;;;;-1:-1:-1;;;;;45873:34:0;;;;;;:26;:34;;;;;:40;;;;;;:65;;-1:-1:-1;;;;;;45917:16:0;;;;;;:8;:16;;;;;;:21;;45873:65;45869:200;;;-1:-1:-1;;;;;45955:25:0;;;;;;:17;:25;;;;;:40;;;45869:200;;;-1:-1:-1;;;;;46028:25:0;;46056:1;46028:25;;;:17;:25;;;;;:29;45869:200;46123:16;46102:18;;:37;:110;;46211:1;46102:110;;;46155:18;;:40;;46178:16;46155:40;:22;:40;:::i;:::-;46081:18;:131;-1:-1:-1;;;;;46230:287:0;;46328:34;;;;:26;:34;;;;;:40;;;46230:287;;46271:16;;46302:11;;46328:40;;:151;;46478:1;46328:151;;;-1:-1:-1;;;;;46410:34:0;;;;;;:26;:34;;;;;:40;46388:21;:63;;:21;;46410:40;46388:63;;;;;;;;;;;;;;;;:70;;;46328:151;46494:12;46230:287;;;;;;;;;;;;;;;;;;-1:-1:-1;46537:11:0;;44286:2270;-1:-1:-1;;;;;44286:2270:0:o;24592:1950::-;25024:21;4860:1;5528:14;;:39;5520:64;;;;-1:-1:-1;;;;;5520:64:0;;;;;;;;;4964:1;5591:14;:40;-1:-1:-1;;;;;25071:31:0;;;;;;:85;;-1:-1:-1;25140:16:0;;-1:-1:-1;;;;;25119:37:0;;;25140:16;;25119:37;;25071:85;25063:123;;;;-1:-1:-1;;;;;25063:123:0;;;;;;;;;25216:13;-1:-1:-1;;;;;25366:40:0;;;;;;;25362:407;;;25447:9;;25525:16;;25436:145;;-1:-1:-1;;;;;25436:145:0;;-1:-1:-1;;;;;25447:9:0;;;;25436:34;;:145;;25489:17;;25525:16;;;;25560:6;;25436:145;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25436:145:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;25436:145:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;25436:145:0;;;;;;;;;25423:158;-1:-1:-1;25362:407:0;;-1:-1:-1;;25362:407:0;;25626:16;;-1:-1:-1;;;;;25603:39:0;;;25626:16;;25603:39;25599:170;;25745:12;;-1:-1:-1;;;;;25745:12:0;;;;;;;;25599:170;25797:737;25830:14;25797:737;;;;;;;;25878:6;-1:-1:-1;;;;;25797:737:0;-1:-1:-1;;;;;25797:737:0;;;;;25903:22;-1:-1:-1;;;;;25797:737:0;-1:-1:-1;;;;;25797:737:0;;;;;25974:17;-1:-1:-1;;;;;25797:737:0;-1:-1:-1;;;;;25797:737:0;;;;;;;;;;;;26070:1;25797:737;;;;26141:6;25797:737;;;;26203:1;25797:737;;;;26319:13;25797:737;;;;26351:19;25797:737;;;;26389:14;25797:737;;;;26422:1;25797:737;;;26453:4;26515:8;25797:18;:737::i;:::-;4860:1;5646:14;:38;25781:753;24592:1950;-1:-1:-1;;;;;;;;;;;;24592:1950:0:o;2785:119::-;2845:7;2874:2;2868;:8;;2861:16;;;;-1:-1:-1;2891:7:0;;;2785:119::o;2971:132::-;3053:7;;;3074;;;;3067:15;;;40751:1185;41103:20;41145:18;;41141:788;;41180:20;41217:31;;;:15;:31;;;;;;;;;41203:46;;:13;:46;;;;;:66;;;:96;;41292:6;41203:96;:88;:96;:::i;:::-;41375:11;;41422:16;;41180:119;;-1:-1:-1;;;;;;41375:11:0;;;;;;;41370:33;;41422:16;;;;41457:36;;:76;;41521:12;;-1:-1:-1;;;;;41521:12:0;41457:76;;;41496:22;41457:76;41552:9;;41370:269;;;;;;;;;;;;;-1:-1:-1;;;;;41552:9:0;;41580:13;;41612:12;;41370:269;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41370:269:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;41370:269:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;41370:269:0;;;;;;;;;41355:284;;41732:120;41797:54;41831:19;41797:33;:54::i;:::-;41732:42;:12;41767:6;41732:42;:34;:42;:::i;:120::-;41717:135;;41884:33;41904:12;41884:19;:33::i;:::-;41869:48;40751:1185;-1:-1:-1;;;;;;40751:1185:0:o;36946:1045::-;37062:18;37107;37098:34;;;;-1:-1:-1;;;;;37098:34:0;;;;;;;;;37149:21;:28;:33;37145:270;;37199:27;37223:1;37199:15;:27::i;:::-;;37241:25;37257:8;37241:15;:25::i;:::-;-1:-1:-1;37285:10:0;-1:-1:-1;;;;;37285:22:0;;;37281:72;;37326:27;37342:10;37326:15;:27::i;:::-;;37281:72;37145:270;;;37386:17;:15;:17::i;:::-;37427:20;37450:33;37462:20;37480:1;37462:17;:20::i;37450:33::-;37427:56;-1:-1:-1;37507:43:0;37427:56;37507:25;:13;37525:6;37507:25;:17;:25;:::i;:43::-;37494:56;-1:-1:-1;37567:9:0;37563:297;;37612:16;;37606:144;;-1:-1:-1;;;;;37606:144:0;;-1:-1:-1;;;;;37612:16:0;;;;37606:36;;:144;;37661:10;;37698:4;;37722:13;;37606:144;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37606:144:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;37606:144:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;37606:144:0;;;;;;;;;37598:159;;;;-1:-1:-1;;;;;37598:159:0;;;;;;;;;37563:297;;;37804:12;;;;;;;;;-1:-1:-1;;;;;37804:12:0;-1:-1:-1;;;;;37790:35:0;;37832:13;37790:58;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37790:58:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;37790:58:0;;;;;37563:297;37872:56;37878:8;37888:10;37900:13;37915:12;37872:5;:56::i;:::-;-1:-1:-1;;;;;37941:27:0;;;;;;;:17;:27;;;;;:42;;;;-1:-1:-1;36946:1045:0;:::o;55306:600::-;55418:7;55443:20;55478:16;;55498:1;55478:21;55474:393;;55518:26;55549:17;:15;:17::i;:::-;55516:50;;;;55596:190;55774:11;55596:155;55734:16;;55596:115;55707:3;55596:88;55667:16;;55596:48;55637:6;55596:18;:40;;:48;;;;:::i;:190::-;55581:205;;55474:393;;;;55834:21;62218:303;62436:66;62430:73;;62396:118::o;40219:524::-;40303:15;40284;;:34;40280:456;;40353:11;;40336:12;;40353:11;;;-1:-1:-1;;;;;40353:11:0;40374:9;40511;;40572:16;;40403:236;;;;-1:-1:-1;;;;;40511:9:0;;;;40572:16;;40403:236;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;40403:236:0;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;179:29;160:49;;40353:301:0;;;40403:236;40353:301;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;-1:-1;;40709:15:0;40691;:33;-1:-1:-1;;40219:524:0:o;61848:362::-;61959:19;62000:36;62017:18;;62000:12;;:16;;:36;;;;:::i;:::-;:41;61996:207;;62136:16;;62071;;62065:48;;-1:-1:-1;;;;;62065:48:0;;:126;;62176:14;;62065:88;;-1:-1:-1;;;;;62071:16:0;;;;62065:33;;:48;;62107:4;;62065:48;;;;42332:939;42640:20;42662:29;42693:23;42761:160;42802:12;42829:11;42855:19;42889:21;42761:26;:160::i;:::-;42734:187;-1:-1:-1;42974:205:0;;-1:-1:-1;43015:57:0;:12;42734:187;43015:57;:34;:57;:::i;:::-;43087:11;43113:19;43147:21;42974:26;:205::i;:::-;42934:245;;-1:-1:-1;42934:245:0;-1:-1:-1;43210:53:0;:12;42934:245;43210:53;:30;:53;:::i;:::-;43192:71;;42332:939;;;;;;;;:::o;48241:1868::-;48457:7;48499:35;48519:11;48531:1;48519:14;;;;48499:19;:35::i;:::-;48482:14;;;:52;;;48561:35;;;;-1:-1:-1;;;;;48561:35:0;;;;;;;;;48684:81;48715:13;48743:11;48684:16;:81::i;:::-;48902:14;;;;48869;;;;:48;;:32;:48::i;:::-;48852:11;48864:1;48852:14;;;:65;48968:11;;;48963:169;;-1:-1:-1;;;;;48963:169:0;;48968:11;;;;-1:-1:-1;;;;;48968:11:0;;48963:37;;:169;;49031:13;;49059;;49087:11;;49113:8;;48963:169;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48963:169:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;48963:169:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;48963:169:0;;;;;;;;;48946:14;;;:186;;;49143:35;;;;-1:-1:-1;;;;;49143:35:0;;;;;;;;;49307:14;;;;49272:16;;:50;;:34;:50::i;:::-;49253:16;:69;49450:20;49468:1;49450:17;:20::i;:::-;49431:16;:39;49487:21;:28;:33;49483:153;;49537:27;49561:1;49537:15;:27::i;:::-;-1:-1:-1;49595:16:0;;49579:33;;:15;:33::i;:::-;;49483:153;49674:16;;;49731:14;;;;49792;;49853:16;;;;49924;;;;;49653:397;;-1:-1:-1;;;;;49653:397:0;;;;;;;;49731:14;49792;;49853:16;;49924;;49990:30;;;;49653:397;;;;;;;;;;-1:-1:-1;;50070:14:0;;;;;-1:-1:-1;;48241:1868:0:o;56321:877::-;56473:7;;56535:17;;56531:494;;56592:15;56573;;:34;56569:243;;56649:17;:15;:17::i;:::-;56745:16;;56628:38;;-1:-1:-1;56704:92:0;;-1:-1:-1;56789:6:0;;-1:-1:-1;56704:58:0;;56628:38;;56704:58;:40;:58;:::i;:92::-;56687:109;;56569:243;56852:16;;56846:48;;-1:-1:-1;;;;;56846:48:0;;56828:15;;56846:68;;56899:14;;-1:-1:-1;;;;;56852:16:0;;56846:33;;:48;;56888:4;;56846:48;;;;:68;56828:86;;56948:7;56933:12;:22;56929:85;;;56991:7;56976:22;;56929:85;56531:494;;57044:146;57083:12;57110:33;57128:14;57110:17;:33::i;:::-;57158:21;57044:24;:146::i;59407:605::-;59810:11;;;59892:9;;59945:16;;59805:199;;-1:-1:-1;;;;;59805:199:0;;59498:25;;;;;;59810:11;;;;-1:-1:-1;;;;;59810:11:0;;;;59805:44;;:199;;59872:4;;59892:9;;;59945:16;;;;59805:199;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59805:199:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59805:199:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;59805:199:0;;;;;;;;;59748:256;;;;-1:-1:-1;59748:256:0;;-1:-1:-1;59407:605:0;;-1:-1:-1;;59407:605:0:o;54947:351::-;55049:7;55074:24;55101:36;55118:18;;55101:12;;:16;;:36;;;;:::i;:::-;55074:63;-1:-1:-1;55157:21:0;:133;;55278:12;;55157:133;;;55194:81;55258:16;55194:41;:11;55228:6;55194:41;:33;:41;:::i;37999:2212::-;38112:22;38160:15;38152:30;;;;-1:-1:-1;;;;;38152:30:0;;;;;;;;;38212:21;38222:10;38212:9;:21::i;:::-;38199:10;:34;38195:101;;;38263:21;38273:10;38263:9;:21::i;:::-;38250:34;;38195:101;38312:21;:28;:33;38308:270;;38362:27;38386:1;38362:15;:27::i;:::-;;38404:25;38420:8;38404:15;:25::i;:::-;-1:-1:-1;38448:10:0;-1:-1:-1;;;;;38448:22:0;;;38444:72;;38489:27;38505:10;38489:15;:27::i;:::-;;38444:72;38308:270;;;38549:17;:15;:17::i;:::-;38590:20;38613:33;38625:20;38643:1;38625:17;:20::i;38613:33::-;38590:56;-1:-1:-1;38659:22:0;38684:40;38717:6;38684:28;:10;38590:56;38684:28;:14;:28;:::i;:40::-;38781:16;;38775:48;;-1:-1:-1;;;;;38775:48:0;;38659:65;;-1:-1:-1;38735:37:0;;-1:-1:-1;;;;;38781:16:0;;;;38775:33;;:48;;38817:4;;38775:48;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38775:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;38775:48:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;38775:48:0;;;;;;;;;38735:88;;38853:14;38836:31;;38899:29;38882:14;:46;38878:1026;;;38945:21;38969:49;:14;38988:29;38969:49;:18;:49;:::i;:::-;38945:73;-1:-1:-1;39033:26:0;39062:43;39092:12;39062:25;38945:73;39080:6;39062:25;:17;:25;:::i;:43::-;39143:18;;39033:72;;-1:-1:-1;39143:42:0;;39033:72;39143:42;:22;:42;:::i;:::-;39122:18;:63;-1:-1:-1;;;;;39204:36:0;;;;;;:26;:36;;;;;:42;;;;;39200:630;;;-1:-1:-1;;;;;39283:36:0;;39267:13;39283:36;;;:26;:36;;;;;:42;39382:21;:28;;:59;;39422:18;;39283:42;;39382:28;;;;;;;;;;;;;;;;:35;;;:39;;:59;;;;:::i;:::-;39344:21;39366:5;39344:28;;;;;;;;;;;;;;;;;;:35;;:97;;;;39200:630;;;;39509:122;;;;;;;;-1:-1:-1;;;;;39509:122:0;;;;;;;;;;;;;39482:21;27:10:-1;;39:1;23:18;;;45:23;;-1:-1;39482:150:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;;39482:150:0;;;;;;;;;;;;;;;;;;;39690:124;;;;;;;39730:28;;-1:-1:-1;;39730:30:0;39690:124;;;;;;;;39651:36;;;:26;:36;;;;;;;:163;;;;;;;;;;-1:-1:-1;;39651:163:0;;;;;;;;;;39200:630;39863:29;39846:46;;38878:1026;;;39916:59;39922:10;39934;39946:14;39962:12;39916:5;:59::i;:::-;40019:10;39992:38;;;;:26;:38;;;;;:44;;;;;;:73;;-1:-1:-1;40049:10:0;40040:20;;;;:8;:20;;;;;;:25;;39992:73;39988:216;;;40100:10;40082:29;;;;:17;:29;;;;;:44;;;39988:216;;;40177:10;40191:1;40159:29;;;:17;:29;;;;;:33;39988:216;37999:2212;;;;;;;:::o;60993:449::-;61158:7;61190:16;:244;;61428:6;61190:244;;;61222:190;61405:6;61222:160;61369:12;61222:124;61334:11;61222:74;61287:8;61222:124;:12;61405:6;61222:42;:34;:42;:::i;41944:380::-;42076:7;42108:208;42309:6;42108:161;42262:6;42108:135;42223:19;42108:96;42195:8;;42108:68;42169:6;42108:42;42141:8;42108:14;;:32;;:42;;;;:::i;50117:672::-;50287:16;;50281:48;;-1:-1:-1;;;;;50281:48:0;;50228:7;;;;-1:-1:-1;;;;;50287:16:0;;;;50281:33;;:48;;50323:4;;50281:48;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50281:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50281:48:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;50281:48:0;;;;;;;;;50253:76;-1:-1:-1;50344:22:0;50340:49;;50388:1;50381:8;;;;;50340:49;50402:22;50427:21;:19;:21::i;:::-;50402:46;;50483:14;50463:17;:34;50459:165;;;50534:37;:17;50556:14;50534:37;:21;:37;:::i;:::-;50514:57;;50459:165;;;50611:1;50604:8;;;;;;50459:165;50655:17;50640:12;:32;50636:114;;;50737:1;50730:8;;;;;;50636:114;-1:-1:-1;50769:12:0;;50117:672;-1:-1:-1;;50117:672:0:o;46564:1640::-;46855:14;;;;46808:21;;46847:34;;;;-1:-1:-1;;;;;46847:34:0;;;;;;;;;-1:-1:-1;46920:31:0;;;;:15;:31;;;;;;46970:18;46962:33;;;;-1:-1:-1;;;;;46962:33:0;;;;;;;;;47008:17;:15;:17::i;:::-;47038:26;47067:28;;;:13;:28;;;;;:56;;;:61;47141:638;;;;47213:183;47285:13;47317:11;47329:1;47317:14;;;;47360:21;47213:23;:183::i;:::-;47178:218;;47179:14;;;47178:218;;;47453:14;;;:31;47141:638;;;47649:14;;;;47590:177;;47692:20;47710:1;47692:17;:20::i;:::-;47731:21;47590:24;:177::i;:::-;47573:194;;47141:638;47795:16;;;;-1:-1:-1;;;;;47795:30:0;47791:175;;47953:1;47936:14;;;:18;47791:175;47978:20;48001:139;48039:13;48067;48095:11;48121:8;48001:23;:139::i;:::-;48175:14;;;;47978:162;;-1:-1:-1;48159:30:0;;48151:45;;;;-1:-1:-1;;;;;48151:45:0;;;;;;;;;46564:1640;;;;;;;;;:::o;4204:175::-;-1:-1:-1;;;;;4275:23:0;;4267:32;;;;;;4332:5;;4311:38;;-1:-1:-1;;;;;4311:38:0;;;;4332:5;;4311:38;;4332:5;;4311:38;4356:5;:17;;-1:-1:-1;;;;;;4356:17:0;-1:-1:-1;;;;;4356:17:0;;;;;;;;;;4204:175::o;61450:390::-;61557:7;61586:16;;61606:1;61586:21;;:41;;;;-1:-1:-1;61611:16:0;;;61586:41;61582:251;;;61699:81;61768:11;61699:46;61738:6;61699:16;;:38;;:46;;;;:::i;43949:329::-;44052:15;;44023:7;;-1:-1:-1;;;;;44052:15:0;:29;44048:222;;-1:-1:-1;44103:15:0;;-1:-1:-1;;;;;44103:15:0;44096:22;;44048:222;44138:21;:28;:33;44134:136;;44193:21;44215:1;44193:24;;;;;;;;;;;;;;;;;;;;;:31;-1:-1:-1;;;;;44193:31:0;;-1:-1:-1;44186:38:0;;44134:136;-1:-1:-1;44268:1:0;44253:17;;54079:821;54239:21;:28;54270:1;-1:-1:-1;54235:362:0;;;54380:21;54402:28;;-1:-1:-1;;54402:32:0;;;54380:55;;;;;;;;;;;;;;;;54349:21;54371:5;54349:28;;;;;;;;;;;;;;;:86;;:28;;;;;:86;;-1:-1:-1;;;;;;54349:86:0;-1:-1:-1;;;;;54349:86:0;;;;;;;;;;;;;;;;;;;;54535:21;:28;;54580:5;;54508:26;;54349:28;;54580:5;;54535:28;;;;;;;;;;;;;;;;;;;;;:35;-1:-1:-1;;;;;54535:35:0;54508:63;;;;;;;;;;;;:77;54235:362;54650:21;:30;;;;;-1:-1:-1;;54650:30:0;;;:::i;:::-;-1:-1:-1;;;;;;54691:34:0;;;54734:1;54691:34;;;:26;:34;;;;;:44;;;54746:40;;:48;;-1:-1:-1;;54746:48:0;;;54821:15;;;;;54811:25;54807:86;;;54853:15;:28;;-1:-1:-1;;;;;;54853:28:0;;;54807:86;54079:821;;:::o;10145:444::-;-1:-1:-1;;;;;10312:17:0;;10304:45;;;;-1:-1:-1;;;;;10304:45:0;;;;;;;;;10375:12;;:30;;10392:12;10375:30;:16;:30;:::i;:::-;10360:12;:45;-1:-1:-1;;;;;10432:13:0;;;;;;:8;:13;;;;;;:31;;10450:12;10432:31;:17;:31;:::i;:::-;-1:-1:-1;;;;;10416:13:0;;;;;;:8;:13;;;;;;;:47;;;;10481:45;;;;;;10491:12;;10505;;10519:6;;10481:45;;;;;;;;;;10563:3;-1:-1:-1;;;;;10542:39:0;10559:1;-1:-1:-1;;;;;10542:39:0;-1:-1:-1;;;;;;;;;;;10568:12:0;10542:39;;;;;;;;;;;;;;;10145:444;;;;:::o;43279:662::-;43502:20;43524:29;43586:124;43625:12;43652:11;43678:21;43586:24;:124::i;:::-;43571:139;-1:-1:-1;43789:120:0;43891:17;43789:83;43852:19;43789:44;:12;43571:139;43789:44;:30;:44;:::i;:120::-;43765:144;;43279:662;;;;;;;:::o;51207:2864::-;51369:16;;;51429;;;;51484;;;;51534:14;;;;51583;;;;51638;;;;51688;;;;51740;;;;51429:16;;51484;-1:-1:-1;;;;;51771:31:0;;51767:606;;51859:16;;51853:109;;-1:-1:-1;;;;;51853:109:0;;-1:-1:-1;;;;;51859:16:0;;;;51853:32;;:109;;51904:8;;51931:16;;51853:109;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51853:109:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51853:109:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;51853:109:0;;;;;;;;;51845:124;;;;-1:-1:-1;;;;;51845:124:0;;;;;;;;;52005:16;51990:12;:31;51986:223;;;52056:16;;52105:8;;52050:136;;-1:-1:-1;;;;;52050:136:0;;-1:-1:-1;;;;;52056:16:0;;;;52050:32;;:136;;52105:8;;;52136:31;;;;52050:136;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52050:136:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52050:136:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;52050:136:0;;;;;;;;;52042:151;;;;-1:-1:-1;;;;;52042:151:0;;;;;;;;;51767:606;;;52255:16;;52300:8;;52249:105;;-1:-1:-1;;;;;52249:105:0;;-1:-1:-1;;;;;52255:16:0;;;;52249:32;;:105;;52300:8;;;52327:12;;52249:105;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52249:105:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52249:105:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;52249:105:0;;;;;;;;;52241:120;;;;-1:-1:-1;;;;;52241:120:0;;;;;;;;;52389:24;;52385:1058;;52434:9;:14;52430:1002;;52503:12;;-1:-1:-1;;;;;52477:38:0;;;52503:12;;52477:38;:95;;;;;52563:9;52540:19;:32;52477:95;52469:110;;;;-1:-1:-1;;;;;52469:110:0;;;;;;;;;52614:12;;;;;;;;;-1:-1:-1;;;;;52614:12:0;-1:-1:-1;;;;;52600:35:0;;52642:19;52600:64;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52600:64:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;52754:8:0;;52693:130;;-1:-1:-1;;;;;52693:130:0;;-1:-1:-1;;;;;52693:38:0;;;;-1:-1:-1;52693:38:0;;-1:-1:-1;52693:130:0;;-1:-1:-1;52754:8:0;;;;52785:19;;52693:130;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52693:130:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52693:130:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;52693:130:0;;;;;;;;;52685:145;;;;-1:-1:-1;;;;;52685:145:0;;;;;;;;;52430:1002;;;52901:16;;-1:-1:-1;;;;;52875:42:0;;;52901:16;;52875:42;52871:546;;;52958:38;:13;52976:19;52958:38;:17;:38;:::i;:::-;52942:54;;52871:546;;;53052:17;-1:-1:-1;;;;;53026:43:0;:22;-1:-1:-1;;;;;53026:43:0;;53022:395;;;53111:39;:14;53130:19;53111:39;:18;:39;:::i;:::-;53094:56;;53022:395;;;53313:8;;53207:183;;-1:-1:-1;;;;;53207:183:0;;-1:-1:-1;;;;;53207:42:0;;;;;;:183;;53276:10;;53313:8;;53348:19;;53207:183;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53207:183:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53207:183:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;53207:183:0;;;;;;;;;53199:198;;;;-1:-1:-1;;;;;53199:198:0;;;;;;;;;53459:18;;53455:389;;53498:16;;-1:-1:-1;;;;;53498:37:0;;;:16;;:37;53494:339;;;53573:33;:14;53592:13;53573:33;:18;:33;:::i;:::-;53556:50;;53494:339;;;53661:16;;53747:8;;53655:155;;-1:-1:-1;;;;;53655:155:0;;-1:-1:-1;;;;;53661:16:0;;;;53655:36;;:155;;53714:10;;53747:8;;;;53778:13;;53655:155;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53655:155:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53655:155:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;53655:155:0;;;;;;;;;53647:170;;;;-1:-1:-1;;;;;53647:170:0;;;;;;;;;53860:19;;53856:208;;53989:8;;53904:141;;-1:-1:-1;;;;;53904:141:0;;-1:-1:-1;;;;;53904:37:0;;;;;;:141;;53960:10;;53989:8;;54016:14;;53904:141;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53904:141:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53904:141:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;53904:141:0;;;;;;;;;53896:156;;;;-1:-1:-1;;;;;53896:156:0;;;;;;;;;51207:2864;;;;;;;;;;:::o;57206:2193::-;57392:16;;57445:173;57493:20;:124;;57616:1;57493:124;;;57533:80;57601:11;57533:45;:15;57571:6;57533:45;:37;:45;:::i;:80::-;57445:29;57462:11;57445:16;:29::i;:173::-;57426:192;;57631:15;57657;57700:8;57689;:19;57685:1679;;;57791:22;:8;57804;57791:22;:12;:22;:::i;:::-;57780:33;;57843:8;57832;:19;57828:61;;;57881:8;57870:19;;57828:61;57916:99;58011:3;57916:72;57985:2;57916:46;57953:8;;57916:14;;:36;;:46;;;;:::i;:99::-;57906:109;;58043:127;58162:7;58043:96;58130:8;58043:64;58074:32;58087:9;58098:7;58074:12;:32::i;:::-;58043:8;;:64;:30;:64;:::i;:127::-;58032:138;;57685:1679;;;58207:21;:44;;;;;58243:8;58232;:19;58207:44;58203:200;;;58379:8;58368:19;;58203:200;58435:8;58423;:20;58419:779;;58475:120;58586:8;;58475:84;58552:6;58475:50;58510:14;;58475:8;:34;;:50;;;;:::i;:120::-;58626:8;;58663:14;;58464:131;;-1:-1:-1;58626:8:0;-1:-1:-1;58663:50:0;;58626:8;58663:50;:40;:50;:::i;:::-;58653:60;;58419:779;;;58754:23;58780:21;:19;:21::i;:::-;58754:47;;58820:29;58852:27;:25;:27::i;:::-;58820:59;-1:-1:-1;58909:134:0;59027:15;58909:91;58993:6;58909:57;:8;58820:59;58909:57;:34;:57;:::i;:134::-;58898:145;-1:-1:-1;59074:15:0;;-1:-1:-1;59074:15:0;;59118:64;:21;59074:15;59118:64;:47;:64;:::i;:::-;59108:74;;58419:779;;;59229:7;59218:8;:18;59214:138;;;59266:7;59255:18;;59214:138;;;59308:7;59297:8;:18;59293:59;;;59345:7;59334:18;;59293:59;-1:-1:-1;;;57206:2193:0;;;;;:::o;10597:849::-;-1:-1:-1;;;;;10781:14:0;;;;;;:8;:14;;;;;;10765:30;;;10757:69;;;;-1:-1:-1;;;;;10757:69:0;;;;;;;;;-1:-1:-1;;;;;11037:14:0;;;;;;:8;:14;;;;;;:32;;11056:12;11037:32;:18;:32;:::i;:::-;-1:-1:-1;;;;;11020:14:0;;;;;;:8;:14;;;;;:49;;;11102:2;-1:-1:-1;11080:181:0;;-1:-1:-1;;;;;11201:14:0;;;;;;:8;:14;;;;;;11184:32;;:12;;:32;:16;:32;:::i;:::-;-1:-1:-1;;;;;11231:14:0;;11248:1;11231:14;;;:8;:14;;;;;:18;11169:47;-1:-1:-1;11080:181:0;11288:12;;:30;;11305:12;11288:30;:16;:30;:::i;:::-;11273:12;:45;11336:46;;-1:-1:-1;;;;;11336:46:0;;;;;;;11347:12;;11361;;11375:6;;11336:46;;;;;;;;;;11421:1;-1:-1:-1;;;;;11398:40:0;11407:4;-1:-1:-1;;;;;11398:40:0;-1:-1:-1;;;;;;;;;;;11425:12:0;11398:40;;;;;;;60020:965;60205:20;60227;60265:24;;:::i;:::-;-1:-1:-1;60292:28:0;;;;:13;:28;;;;;;;;;60265:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60331:48;;;;-1:-1:-1;;;;;60331:48:0;;;;;;;;;60512:28;;;;60407:214;;60446:95;;:43;:13;60482:6;60446:43;:35;:43;:::i;:95::-;60556:18;:16;:18::i;:::-;60589:21;60407:24;:214::i;:::-;60392:229;;60724:253;60948:8;:28;;;60724:205;60782:146;60813:12;60844:8;:36;;;60899:8;:28;;;60782:12;:146::i;:::-;60724:39;:13;60756:6;60724:39;:31;:39;:::i;:253::-;60709:268;;60020:965;;;;;;;:::o;62527:327::-;62769:66;62763:73;;62723:124::o;15187:50367::-;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;-1:-1;15187:50367:0;;;-1:-1:-1;;15187:50367:0:o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;;15187:50367:0;;;;;;;;;;;;;;;;5:130:-1;72:20;;97:33;72:20;97:33;;142:134;220:13;;238:33;220:13;238:33;;283:124;347:20;;372:30;347:20;372:30;;414:128;489:13;;507:30;489:13;507:30;;549:130;616:20;;641:33;616:20;641:33;;687:440;;788:3;781:4;773:6;769:17;765:27;755:2;;806:1;803;796:12;755:2;843:6;830:20;865:64;880:48;921:6;880:48;;;865:64;;;856:73;;949:6;942:5;935:21;985:4;977:6;973:17;1018:4;1011:5;1007:16;1053:3;1044:6;1039:3;1035:16;1032:25;1029:2;;;1070:1;1067;1060:12;1029:2;1080:41;1114:6;1109:3;1104;1080:41;;1169:1771;;1284:5;1272:9;1267:3;1263:19;1259:31;1256:2;;;1303:1;1300;1293:12;1256:2;1321:21;1336:5;1321:21;;;1312:30;-1:-1;1404:1;1435:49;1480:3;1460:9;1435:49;;;1411:74;;-1:-1;1562:2;1595:49;1640:3;1616:22;;;1595:49;;;1588:4;1581:5;1577:16;1570:75;1506:150;1724:2;1757:49;1802:3;1793:6;1782:9;1778:22;1757:49;;;1750:4;1743:5;1739:16;1732:75;1666:152;1877:2;1910:49;1955:3;1946:6;1935:9;1931:22;1910:49;;;1903:4;1896:5;1892:16;1885:75;1828:143;2032:3;2066:49;2111:3;2102:6;2091:9;2087:22;2066:49;;;2059:4;2052:5;2048:16;2041:75;1981:146;2187:3;2221:49;2266:3;2257:6;2246:9;2242:22;2221:49;;;2214:4;2207:5;2203:16;2196:75;2137:145;2347:3;2381:49;2426:3;2417:6;2406:9;2402:22;2381:49;;;2374:4;2367:5;2363:16;2356:75;2292:150;2511:3;2545:49;2590:3;2581:6;2570:9;2566:22;2545:49;;;2538:4;2531:5;2527:16;2520:75;2452:154;2679:3;2714:49;2759:3;2750:6;2739:9;2735:22;2714:49;;;2706:5;2699;2695:17;2688:76;2616:159;2834:3;2869:49;2914:3;2905:6;2894:9;2890:22;2869:49;;;2861:5;2854;2850:17;2843:76;2785:145;1250:1690;;;;;2984:1947;;3102:5;3090:9;3085:3;3081:19;3077:31;3074:2;;;3121:1;3118;3111:12;3074:2;3139:21;3154:5;3139:21;;;3130:30;-1:-1;3212:1;3243:49;3288:3;3268:9;3243:49;;;3219:74;;-1:-1;3378:2;3411:49;3456:3;3432:22;;;3411:49;;;3404:4;3397:5;3393:16;3386:75;3314:158;3544:2;3577:49;3622:3;3613:6;3602:9;3598:22;3577:49;;;3570:4;3563:5;3559:16;3552:75;3482:156;3705:2;3738:49;3783:3;3774:6;3763:9;3759:22;3738:49;;;3731:4;3724:5;3720:16;3713:75;3648:151;3864:3;3898:49;3943:3;3934:6;3923:9;3919:22;3898:49;;;3891:4;3884:5;3880:16;3873:75;3809:150;4032:3;4066:49;4111:3;4102:6;4091:9;4087:22;4066:49;;;4059:4;4052:5;4048:16;4041:75;3969:158;4198:3;4232:49;4277:3;4268:6;4257:9;4253:22;4232:49;;;4225:4;4218:5;4214:16;4207:75;4137:156;4364:3;4398:49;4443:3;4434:6;4423:9;4419:22;4398:49;;;4391:4;4384:5;4380:16;4373:75;4303:156;4528:3;4563:49;4608:3;4599:6;4588:9;4584:22;4563:49;;;4555:5;4548;4544:17;4537:76;4469:155;4676:3;4711:46;4753:3;4744:6;4733:9;4729:22;4711:46;;;4703:5;4696;4692:17;4685:73;4634:135;4825:3;4860:49;4905:3;4896:6;4885:9;4881:22;4860:49;;;4852:5;4845;4841:17;4834:76;4779:142;3068:1863;;;;;5075:134;5153:13;;5171:33;5153:13;5171:33;;5216:241;;5320:2;5308:9;5299:7;5295:23;5291:32;5288:2;;;5336:1;5333;5326:12;5288:2;5371:1;5388:53;5433:7;5413:9;5388:53;;5464:263;;5579:2;5567:9;5558:7;5554:23;5550:32;5547:2;;;5595:1;5592;5585:12;5547:2;5630:1;5647:64;5703:7;5683:9;5647:64;;5734:366;;;5855:2;5843:9;5834:7;5830:23;5826:32;5823:2;;;5871:1;5868;5861:12;5823:2;5906:1;5923:53;5968:7;5948:9;5923:53;;;5913:63;;5885:97;6013:2;6031:53;6076:7;6067:6;6056:9;6052:22;6031:53;;;6021:63;;5992:98;5817:283;;;;;;6107:491;;;;6245:2;6233:9;6224:7;6220:23;6216:32;6213:2;;;6261:1;6258;6251:12;6213:2;6296:1;6313:53;6358:7;6338:9;6313:53;;;6303:63;;6275:97;6403:2;6421:53;6466:7;6457:6;6446:9;6442:22;6421:53;;;6411:63;;6382:98;6511:2;6529:53;6574:7;6565:6;6554:9;6550:22;6529:53;;;6519:63;;6490:98;6207:391;;;;;;6605:470;;;6735:2;6723:9;6714:7;6710:23;6706:32;6703:2;;;6751:1;6748;6741:12;6703:2;6786:1;6803:53;6848:7;6828:9;6803:53;;;6793:63;;6765:97;6921:2;6910:9;6906:18;6893:32;6945:18;6937:6;6934:30;6931:2;;;6977:1;6974;6967:12;6931:2;6997:62;7051:7;7042:6;7031:9;7027:22;6997:62;;7082:366;;;7203:2;7191:9;7182:7;7178:23;7174:32;7171:2;;;7219:1;7216;7209:12;7171:2;7254:1;7271:53;7316:7;7296:9;7271:53;;;7261:63;;7233:97;7361:2;7379:53;7424:7;7415:6;7404:9;7400:22;7379:53;;7455:257;;7567:2;7555:9;7546:7;7542:23;7538:32;7535:2;;;7583:1;7580;7573:12;7535:2;7618:1;7635:61;7688:7;7668:9;7635:61;;7719:241;;7823:2;7811:9;7802:7;7798:23;7794:32;7791:2;;;7839:1;7836;7829:12;7791:2;7874:1;7891:53;7936:7;7916:9;7891:53;;7967:850;;;;;;8191:3;8179:9;8170:7;8166:23;8162:33;8159:2;;;8208:1;8205;8198:12;8159:2;8243:1;8260:79;8331:7;8311:9;8260:79;;;8250:89;;8222:123;8376:3;8395:82;8469:7;8460:6;8449:9;8445:22;8395:82;;;8385:92;;8355:128;8514:3;8533:53;8578:7;8569:6;8558:9;8554:22;8533:53;;;8523:63;;8493:99;8623:3;8642:53;8687:7;8678:6;8667:9;8663:22;8642:53;;;8632:63;;8602:99;8732:3;8751:50;8793:7;8784:6;8773:9;8769:22;8751:50;;;8741:60;;8711:96;8153:664;;;;;;;;;9072:263;;9187:2;9175:9;9166:7;9162:23;9158:32;9155:2;;;9203:1;9200;9193:12;9155:2;9238:1;9255:64;9311:7;9291:9;9255:64;;9342:360;;;9460:2;9448:9;9439:7;9435:23;9431:32;9428:2;;;9476:1;9473;9466:12;9428:2;9511:1;9528:53;9573:7;9553:9;9528:53;;;9518:63;;9490:97;9618:2;9636:50;9678:7;9669:6;9658:9;9654:22;9636:50;;9709:535;;;;9858:2;9846:9;9837:7;9833:23;9829:32;9826:2;;;9874:1;9871;9864:12;9826:2;9909:1;9926:64;9982:7;9962:9;9926:64;;;9916:74;;9888:108;10027:2;10045:64;10101:7;10092:6;10081:9;10077:22;10045:64;;;10035:74;;10006:109;10146:2;10164:64;10220:7;10211:6;10200:9;10196:22;10164:64;;10251:617;;;;;10406:3;10394:9;10385:7;10381:23;10377:33;10374:2;;;10423:1;10420;10413:12;10374:2;10458:1;10475:53;10520:7;10500:9;10475:53;;;10465:63;;10437:97;10565:2;10583:53;10628:7;10619:6;10608:9;10604:22;10583:53;;;10573:63;;10544:98;10673:2;10691:53;10736:7;10727:6;10716:9;10712:22;10691:53;;;10681:63;;10652:98;10781:2;10799:53;10844:7;10835:6;10824:9;10820:22;10799:53;;;10789:63;;10760:98;10368:500;;;;;;;;10875:672;;;;;11041:3;11029:9;11020:7;11016:23;11012:33;11009:2;;;11058:1;11055;11048:12;11009:2;11093:1;11110:64;11166:7;11146:9;11110:64;;;11100:74;;11072:108;11211:2;11229:64;11285:7;11276:6;11265:9;11261:22;11229:64;;;11219:74;;11190:109;11330:2;11348:64;11404:7;11395:6;11384:9;11380:22;11348:64;;;11338:74;;11309:109;11449:2;11467:64;11523:7;11514:6;11503:9;11499:22;11467:64;;11554:1099;;;;;;;;11769:3;11757:9;11748:7;11744:23;11740:33;11737:2;;;11786:1;11783;11776:12;11737:2;11821:1;11838:53;11883:7;11863:9;11838:53;;;11828:63;;11800:97;11928:2;11946:53;11991:7;11982:6;11971:9;11967:22;11946:53;;;11936:63;;11907:98;12036:2;12054:53;12099:7;12090:6;12079:9;12075:22;12054:53;;;12044:63;;12015:98;12144:2;12162:53;12207:7;12198:6;12187:9;12183:22;12162:53;;;12152:63;;12123:98;12252:3;12271:53;12316:7;12307:6;12296:9;12292:22;12271:53;;;12261:63;;12231:99;12361:3;12380:53;12425:7;12416:6;12405:9;12401:22;12380:53;;;12370:63;;12340:99;12498:3;12487:9;12483:19;12470:33;12523:18;12515:6;12512:30;12509:2;;;12555:1;12552;12545:12;12509:2;12575:62;12629:7;12620:6;12609:9;12605:22;12575:62;;;12565:72;;12449:194;11731:922;;;;;;;;;;;12660:1247;;;;;;;;;;12900:3;12888:9;12879:7;12875:23;12871:33;12868:2;;;12917:1;12914;12907:12;12868:2;12952:1;12969:53;13014:7;12994:9;12969:53;;;12959:63;;12931:97;13059:2;13077:53;13122:7;13113:6;13102:9;13098:22;13077:53;;;13067:63;;13038:98;13167:2;13185:53;13230:7;13221:6;13210:9;13206:22;13185:53;;;13175:63;;13146:98;13275:2;13293:53;13338:7;13329:6;13318:9;13314:22;13293:53;;;13283:63;;13254:98;13383:3;13402:53;13447:7;13438:6;13427:9;13423:22;13402:53;;;13392:63;;13362:99;13492:3;13511:53;13556:7;13547:6;13536:9;13532:22;13511:53;;;13501:63;;13471:99;13601:3;13620:53;13665:7;13656:6;13645:9;13641:22;13620:53;;;13610:63;;13580:99;13710:3;13729:53;13774:7;13765:6;13754:9;13750:22;13729:53;;;13719:63;;13689:99;13819:3;13838:53;13883:7;13874:6;13863:9;13859:22;13838:53;;;13828:63;;13798:99;12862:1045;;;;;;;;;;;;13914:1477;;;;;;;;;;;14180:3;14168:9;14159:7;14155:23;14151:33;14148:2;;;14197:1;14194;14187:12;14148:2;14232:1;14249:53;14294:7;14274:9;14249:53;;;14239:63;;14211:97;14339:2;14357:53;14402:7;14393:6;14382:9;14378:22;14357:53;;;14347:63;;14318:98;14447:2;14465:53;14510:7;14501:6;14490:9;14486:22;14465:53;;;14455:63;;14426:98;14555:2;14573:53;14618:7;14609:6;14598:9;14594:22;14573:53;;;14563:63;;14534:98;14663:3;14682:53;14727:7;14718:6;14707:9;14703:22;14682:53;;;14672:63;;14642:99;14772:3;14791:53;14836:7;14827:6;14816:9;14812:22;14791:53;;;14781:63;;14751:99;14881:3;14900:53;14945:7;14936:6;14925:9;14921:22;14900:53;;;14890:63;;14860:99;14990:3;15009:53;15054:7;15045:6;15034:9;15030:22;15009:53;;;14999:63;;14969:99;15099:3;15118:53;15163:7;15154:6;15143:9;15139:22;15118:53;;;15108:63;;15078:99;15236:3;15225:9;15221:19;15208:33;15261:18;15253:6;15250:30;15247:2;;;15293:1;15290;15283:12;15247:2;15313:62;15367:7;15358:6;15347:9;15343:22;15313:62;;;15303:72;;15187:194;14142:1249;;;;;;;;;;;;;;15398:1477;;;;;;;;;;;15664:3;15652:9;15643:7;15639:23;15635:33;15632:2;;;15681:1;15678;15671:12;15632:2;15716:1;15733:53;15778:7;15758:9;15733:53;;;15723:63;;15695:97;15823:2;15841:53;15886:7;15877:6;15866:9;15862:22;15841:53;;;15831:63;;15802:98;15931:2;15949:53;15994:7;15985:6;15974:9;15970:22;15949:53;;;15939:63;;15910:98;16039:2;16057:53;16102:7;16093:6;16082:9;16078:22;16057:53;;;16047:63;;16018:98;16147:3;16166:53;16211:7;16202:6;16191:9;16187:22;16166:53;;;16156:63;;16126:99;16256:3;16275:53;16320:7;16311:6;16300:9;16296:22;16275:53;;16883:173;;16970:46;17012:3;17004:6;16970:46;;;-1:-1;;17045:4;17036:14;;16963:93;17065:173;;17152:46;17194:3;17186:6;17152:46;;17246:142;17337:45;17376:5;17337:45;;;17332:3;17325:58;17319:69;;;17395:103;17468:24;17486:5;17468:24;;17658:660;17791:52;17837:5;17791:52;;;17856:84;17933:6;17928:3;17856:84;;;17849:91;;17961:54;18009:5;17961:54;;;18035:7;18063:1;18048:258;18073:6;18070:1;18067:13;18048:258;;;18140:6;18134:13;18161:63;18220:3;18205:13;18161:63;;;18154:70;;18241:58;18292:6;18241:58;;;18231:68;-1:-1;;18095:1;18088:9;18048:258;;;18052:14;17770:548;;;;;;18359:660;18492:52;18538:5;18492:52;;;18557:84;18634:6;18629:3;18557:84;;;18550:91;;18662:54;18710:5;18662:54;;;18736:7;18764:1;18749:258;18774:6;18771:1;18768:13;18749:258;;;18841:6;18835:13;18862:63;18921:3;18906:13;18862:63;;;18855:70;;18942:58;18993:6;18942:58;;;18932:68;-1:-1;;18796:1;18789:9;18749:258;;19058:690;;19203:54;19251:5;19203:54;;;19270:86;19349:6;19344:3;19270:86;;;19263:93;;19377:56;19427:5;19377:56;;;19453:7;19481:1;19466:260;19491:6;19488:1;19485:13;19466:260;;;19558:6;19552:13;19579:63;19638:3;19623:13;19579:63;;;19572:70;;19659:60;19712:6;19659:60;;;19649:70;-1:-1;;19513:1;19506:9;19466:260;;;-1:-1;19739:3;;19182:566;-1:-1;;;;;19182:566;19756:104;19833:21;19848:5;19833:21;;19867:113;19950:24;19968:5;19950:24;;19987:343;;20097:38;20129:5;20097:38;;;20147:70;20210:6;20205:3;20147:70;;;20140:77;;20222:52;20267:6;20262:3;20255:4;20248:5;20244:16;20222:52;;;20295:29;20317:6;20295:29;;;20286:39;;;;20077:253;-1:-1;;;20077:253;20337:356;;20465:38;20497:5;20465:38;;;20515:88;20596:6;20591:3;20515:88;;;20508:95;;20608:52;20653:6;20648:3;20641:4;20634:5;20630:16;20608:52;;;20672:16;;;;;20445:248;-1:-1;;20445:248;20700:142;20791:45;20830:5;20791:45;;21196:363;;21356:66;21420:1;21415:3;21356:66;;;-1:-1;;;;;21435:87;;21550:2;21541:12;;21342:217;-1:-1;;21342:217;21568:363;;21728:66;21792:1;21787:3;21728:66;;;-1:-1;;;;;21807:87;;21922:2;21913:12;;21714:217;-1:-1;;21714:217;21940:363;;22100:66;22164:1;22159:3;22100:66;;;-1:-1;;;;;22179:87;;22294:2;22285:12;;22086:217;-1:-1;;22086:217;22312:363;;22472:66;22536:1;22531:3;22472:66;;;-1:-1;;;;;22551:87;;22666:2;22657:12;;22458:217;-1:-1;;22458:217;22684:363;;22844:66;22908:1;22903:3;22844:66;;;-1:-1;;;;;22923:87;;23038:2;23029:12;;22830:217;-1:-1;;22830:217;23056:363;;23216:66;23280:1;23275:3;23216:66;;;-1:-1;;;;;23295:87;;23410:2;23401:12;;23202:217;-1:-1;;23202:217;23428:363;;23588:66;23652:1;23647:3;23588:66;;;-1:-1;;;;;23667:87;;23782:2;23773:12;;23574:217;-1:-1;;23574:217;23800:363;;23960:66;24024:1;24019:3;23960:66;;;-1:-1;;;;;24039:87;;24154:2;24145:12;;23946:217;-1:-1;;23946:217;24172:363;;24332:66;24396:1;24391:3;24332:66;;;-1:-1;;;;;24411:87;;24526:2;24517:12;;24318:217;-1:-1;;24318:217;24544:363;;24704:66;24768:1;24763:3;24704:66;;;-1:-1;;;;;24783:87;;24898:2;24889:12;;24690:217;-1:-1;;24690:217;24916:363;;25076:66;25140:1;25135:3;25076:66;;;-1:-1;;;;;25155:87;;25270:2;25261:12;;25062:217;-1:-1;;25062:217;25288:364;;25448:67;25512:2;25507:3;25448:67;;;25548:66;25528:87;;25643:2;25634:12;;25434:218;-1:-1;;25434:218;25661:363;;25821:66;25885:1;25880:3;25821:66;;;-1:-1;;;;;25900:87;;26015:2;26006:12;;25807:217;-1:-1;;25807:217;26033:363;;26193:66;26257:1;26252:3;26193:66;;;-1:-1;;;;;26272:87;;26387:2;26378:12;;26179:217;-1:-1;;26179:217;26405:363;;26565:66;26629:1;26624:3;26565:66;;;-1:-1;;;;;26644:87;;26759:2;26750:12;;26551:217;-1:-1;;26551:217;26777:363;;26937:66;27001:1;26996:3;26937:66;;;-1:-1;;;;;27016:87;;27131:2;27122:12;;26923:217;-1:-1;;26923:217;27149:363;;27309:66;27373:1;27368:3;27309:66;;;-1:-1;;;;;27388:87;;27503:2;27494:12;;27295:217;-1:-1;;27295:217;27521:363;;27681:66;27745:1;27740:3;27681:66;;;-1:-1;;;;;27760:87;;27875:2;27866:12;;27667:217;-1:-1;;27667:217;27893:363;;28053:66;28117:1;28112:3;28053:66;;;-1:-1;;;;;28132:87;;28247:2;28238:12;;28039:217;-1:-1;;28039:217;28265:363;;28425:66;28489:1;28484:3;28425:66;;;-1:-1;;;;;28504:87;;28619:2;28610:12;;28411:217;-1:-1;;28411:217;28637:363;;28797:66;28861:1;28856:3;28797:66;;;-1:-1;;;;;28876:87;;28991:2;28982:12;;28783:217;-1:-1;;28783:217;29009:363;;29169:66;29233:1;29228:3;29169:66;;;-1:-1;;;;;29248:87;;29363:2;29354:12;;29155:217;-1:-1;;29155:217;29381:363;;29541:66;29605:1;29600:3;29541:66;;;-1:-1;;;;;29620:87;;29735:2;29726:12;;29527:217;-1:-1;;29527:217;29753:363;;29913:66;29977:1;29972:3;29913:66;;;-1:-1;;;;;29992:87;;30107:2;30098:12;;29899:217;-1:-1;;29899:217;30125:364;;30285:67;30349:2;30344:3;30285:67;;;30385:66;30365:87;;30480:2;30471:12;;30271:218;-1:-1;;30271:218;30498:363;;30658:66;30722:1;30717:3;30658:66;;;-1:-1;;;;;30737:87;;30852:2;30843:12;;30644:217;-1:-1;;30644:217;30870:364;;31030:67;31094:2;31089:3;31030:67;;;31130:66;31110:87;;31225:2;31216:12;;31016:218;-1:-1;;31016:218;31243:364;;31403:67;31467:2;31462:3;31403:67;;;31503:66;31483:87;;31598:2;31589:12;;31389:218;-1:-1;;31389:218;31616:363;;31776:66;31840:1;31835:3;31776:66;;;-1:-1;;;;;31855:87;;31970:2;31961:12;;31762:217;-1:-1;;31762:217;31988:363;;32148:66;32212:1;32207:3;32148:66;;;-1:-1;;;;;32227:87;;32342:2;32333:12;;32134:217;-1:-1;;32134:217;32360:296;;32537:83;32618:1;32613:3;32537:83;;32665:363;;32825:66;32889:1;32884:3;32825:66;;;-1:-1;;;;;32904:87;;33019:2;33010:12;;32811:217;-1:-1;;32811:217;33037:363;;33197:66;33261:1;33256:3;33197:66;;;-1:-1;;;;;33276:87;;33391:2;33382:12;;33183:217;-1:-1;;33183:217;33409:363;;33569:66;33633:1;33628:3;33569:66;;;-1:-1;;;;;33648:87;;33763:2;33754:12;;33555:217;-1:-1;;33555:217;33781:363;;33941:66;34005:1;34000:3;33941:66;;;-1:-1;;;;;34020:87;;34135:2;34126:12;;33927:217;-1:-1;;33927:217;34153:364;;34313:67;34377:2;34372:3;34313:67;;;34413:66;34393:87;;34508:2;34499:12;;34299:218;-1:-1;;34299:218;34526:363;;34686:66;34750:1;34745:3;34686:66;;;-1:-1;;;;;34765:87;;34880:2;34871:12;;34672:217;-1:-1;;34672:217;34898:363;;35058:66;35122:1;35117:3;35058:66;;;-1:-1;;;;;35137:87;;35252:2;35243:12;;35044:217;-1:-1;;35044:217;35270:363;;35430:66;35494:1;35489:3;35430:66;;;-1:-1;;;;;35509:87;;35624:2;35615:12;;35416:217;-1:-1;;35416:217;35642:363;;35802:66;35866:1;35861:3;35802:66;;;-1:-1;;;;;35881:87;;35996:2;35987:12;;35788:217;-1:-1;;35788:217;36014:364;;36174:67;36238:2;36233:3;36174:67;;;36274:66;36254:87;;36369:2;36360:12;;36160:218;-1:-1;;36160:218;36616:107;36695:22;36711:5;36695:22;;36730:262;;36874:93;36963:3;36954:6;36874:93;;36999:370;;37197:147;37340:3;37197:147;;37376:213;37494:2;37479:18;;37508:71;37483:9;37552:6;37508:71;;37596:229;37722:2;37707:18;;37736:79;37711:9;37788:6;37736:79;;37832:467;38022:2;38007:18;;38036:79;38011:9;38088:6;38036:79;;;38126:80;38202:2;38191:9;38187:18;38178:6;38126:80;;;38217:72;38285:2;38274:9;38270:18;38261:6;38217:72;;38306:451;38488:2;38473:18;;38502:79;38477:9;38554:6;38502:79;;;38592:72;38660:2;38649:9;38645:18;38636:6;38592:72;;;38675;38743:2;38732:9;38728:18;38719:6;38675:72;;38764:451;38946:2;38931:18;;38960:79;38935:9;39012:6;38960:79;;;39050:72;39118:2;39107:9;39103:18;39094:6;39050:72;;39222:324;39368:2;39353:18;;39382:71;39357:9;39426:6;39382:71;;;39464:72;39532:2;39521:9;39517:18;39508:6;39464:72;;39553:659;39783:3;39768:19;;39798:71;39772:9;39842:6;39798:71;;;39880:72;39948:2;39937:9;39933:18;39924:6;39880:72;;;39963;40031:2;40020:9;40016:18;40007:6;39963:72;;;40046;40114:2;40103:9;40099:18;40090:6;40046:72;;;40129:73;40197:3;40186:9;40182:19;40173:6;40129:73;;40219:435;40393:2;40378:18;;40407:71;40382:9;40451:6;40407:71;;40661:340;40815:2;40800:18;;40829:71;40804:9;40873:6;40829:71;;;40911:80;40987:2;40976:9;40972:18;40963:6;40911:80;;41008:324;41154:2;41139:18;;41168:71;41143:9;41212:6;41168:71;;;41250:72;41318:2;41307:9;41303:18;41294:6;41250:72;;41339:423;41507:2;41492:18;;41521:71;41496:9;41565:6;41521:71;;;41603:72;41671:2;41660:9;41656:18;41647:6;41603:72;;;41686:66;41748:2;41737:9;41733:18;41724:6;41686:66;;41769:361;41937:2;41951:47;;;41922:18;;42012:108;41922:18;42106:6;42012:108;;42137:201;42249:2;42234:18;;42263:65;42238:9;42301:6;42263:65;;42345:213;42463:2;42448:18;;42477:71;42452:9;42521:6;42477:71;;42565:817;42877:3;42862:19;;42892:71;42866:9;42936:6;42892:71;;;42974:118;43088:2;43077:9;43073:18;43064:6;42974:118;;;43103:119;43217:3;43206:9;43202:19;43193:6;43103:119;;;43271:9;43265:4;43261:20;43255:3;43244:9;43240:19;43233:49;43296:76;43367:4;43358:6;43296:76;;43389:771;43647:3;43632:19;;43662:71;43636:9;43706:6;43662:71;;;43744:72;43812:2;43801:9;43797:18;43788:6;43744:72;;;43827;43895:2;43884:9;43880:18;43871:6;43827:72;;;43910;43978:2;43967:9;43963:18;43954:6;43910:72;;;43993:73;44061:3;44050:9;44046:19;44037:6;43993:73;;;44077;44145:3;44134:9;44130:19;44121:6;44077:73;;;43618:542;;;;;;;;;;44167:293;44301:2;44315:47;;;44286:18;;44376:74;44286:18;44436:6;44376:74;;44467:407;44658:2;44672:47;;;44643:18;;44733:131;44643:18;44733:131;;44881:407;45072:2;45086:47;;;45057:18;;45147:131;45057:18;45147:131;;45295:407;45486:2;45500:47;;;45471:18;;45561:131;45471:18;45561:131;;45709:407;45900:2;45914:47;;;45885:18;;45975:131;45885:18;45975:131;;46123:407;46314:2;46328:47;;;46299:18;;46389:131;46299:18;46389:131;;46537:407;46728:2;46742:47;;;46713:18;;46803:131;46713:18;46803:131;;46951:407;47142:2;47156:47;;;47127:18;;47217:131;47127:18;47217:131;;47365:407;47556:2;47570:47;;;47541:18;;47631:131;47541:18;47631:131;;47779:407;47970:2;47984:47;;;47955:18;;48045:131;47955:18;48045:131;;48193:407;48384:2;48398:47;;;48369:18;;48459:131;48369:18;48459:131;;48607:407;48798:2;48812:47;;;48783:18;;48873:131;48783:18;48873:131;;49021:407;49212:2;49226:47;;;49197:18;;49287:131;49197:18;49287:131;;49435:407;49626:2;49640:47;;;49611:18;;49701:131;49611:18;49701:131;;49849:407;50040:2;50054:47;;;50025:18;;50115:131;50025:18;50115:131;;50263:407;50454:2;50468:47;;;50439:18;;50529:131;50439:18;50529:131;;50677:407;50868:2;50882:47;;;50853:18;;50943:131;50853:18;50943:131;;51091:407;51282:2;51296:47;;;51267:18;;51357:131;51267:18;51357:131;;51505:407;51696:2;51710:47;;;51681:18;;51771:131;51681:18;51771:131;;51919:407;52110:2;52124:47;;;52095:18;;52185:131;52095:18;52185:131;;52333:407;52524:2;52538:47;;;52509:18;;52599:131;52509:18;52599:131;;52747:407;52938:2;52952:47;;;52923:18;;53013:131;52923:18;53013:131;;53161:407;53352:2;53366:47;;;53337:18;;53427:131;53337:18;53427:131;;53575:407;53766:2;53780:47;;;53751:18;;53841:131;53751:18;53841:131;;53989:407;54180:2;54194:47;;;54165:18;;54255:131;54165:18;54255:131;;54403:407;54594:2;54608:47;;;54579:18;;54669:131;54579:18;54669:131;;54817:407;55008:2;55022:47;;;54993:18;;55083:131;54993:18;55083:131;;55231:407;55422:2;55436:47;;;55407:18;;55497:131;55407:18;55497:131;;55645:407;55836:2;55850:47;;;55821:18;;55911:131;55821:18;55911:131;;56059:407;56250:2;56264:47;;;56235:18;;56325:131;56235:18;56325:131;;56473:407;56664:2;56678:47;;;56649:18;;56739:131;56649:18;56739:131;;56887:407;57078:2;57092:47;;;57063:18;;57153:131;57063:18;57153:131;;57301:407;57492:2;57506:47;;;57477:18;;57567:131;57477:18;57567:131;;57715:407;57906:2;57920:47;;;57891:18;;57981:131;57891:18;57981:131;;58129:407;58320:2;58334:47;;;58305:18;;58395:131;58305:18;58395:131;;58543:407;58734:2;58748:47;;;58719:18;;58809:131;58719:18;58809:131;;58957:407;59148:2;59162:47;;;59133:18;;59223:131;59133:18;59223:131;;59371:407;59562:2;59576:47;;;59547:18;;59637:131;59547:18;59637:131;;59785:407;59976:2;59990:47;;;59961:18;;60051:131;59961:18;60051:131;;60199:407;60390:2;60404:47;;;60375:18;;60465:131;60375:18;60465:131;;60613:407;60804:2;60818:47;;;60789:18;;60879:131;60789:18;60879:131;;61247:312;61387:2;61372:18;;61401:71;61376:9;61445:6;61401:71;;;61483:66;61545:2;61534:9;61530:18;61521:6;61483:66;;61566:647;61790:3;61775:19;;61805:71;61779:9;61849:6;61805:71;;;61887:72;61955:2;61944:9;61940:18;61931:6;61887:72;;;61970;62038:2;62027:9;62023:18;62014:6;61970:72;;;62053;62121:2;62110:9;62106:18;62097:6;62053:72;;;62136:67;62198:3;62187:9;62183:19;62174:6;62136:67;;62220:435;62394:2;62379:18;;62408:71;62383:9;62452:6;62408:71;;;62490:72;62558:2;62547:9;62543:18;62534:6;62490:72;;62662:547;62864:3;62849:19;;62879:71;62853:9;62923:6;62879:71;;;62961:72;63029:2;63018:9;63014:18;63005:6;62961:72;;;63044;63112:2;63101:9;63097:18;63088:6;63044:72;;;63127;63195:2;63184:9;63180:18;63171:6;63127:72;;63216:205;63330:2;63315:18;;63344:67;63319:9;63384:6;63344:67;;63428:256;63490:2;63484:9;63516:17;;;63591:18;63576:34;;63612:22;;;63573:62;63570:2;;;63648:1;63645;63638:12;63570:2;63664;63657:22;63468:216;;-1:-1;63468:216;63691:258;;63834:18;63826:6;63823:30;63820:2;;;63866:1;63863;63856:12;63820:2;-1:-1;63939:4;63910;63887:17;;;;-1:-1;;63883:33;63929:15;;63757:192;64205:123;64315:4;64303:17;;64283:45;64338:96;-1:-1;64426:3;;64410:24;64441:96;-1:-1;64529:3;;64513:24;64544:107;64634:12;;64618:33;65551:178;65669:19;;;65718:4;65709:14;;65662:67;66233:91;;66295:24;66313:5;66295:24;;66331:85;66397:13;66390:21;;66373:43;66502:121;-1:-1;;;;;66564:54;;66547:76;66709:81;66780:4;66769:16;;66752:38;66797:129;;66884:37;66915:5;66884:37;;66933:116;;67020:24;67038:5;67020:24;;67056:121;;67135:37;67166:5;67135:37;;67300:145;67381:6;67376:3;67371;67358:30;-1:-1;67437:1;67419:16;;67412:27;67351:94;67454:268;67519:1;67526:101;67540:6;67537:1;67534:13;67526:101;;;67607:11;;;67601:18;67588:11;;;67581:39;67562:2;67555:10;67526:101;;;67642:6;67639:1;67636:13;67633:2;;;67707:1;67698:6;67693:3;67689:16;67682:27;67633:2;67503:219;;;;;67730:97;67818:2;67798:14;-1:-1;;67794:28;;67778:49;67835:117;67904:24;67922:5;67904:24;;;67897:5;67894:35;67884:2;;67943:1;67940;67933:12;67959:111;68025:21;68040:5;68025:21;;68077:117;68146:24;68164:5;68146:24;

Swarm Source

bzzr://0725eca12df935cc7620fa4d6a3b0c229ad5188b26747029c507f11779ab374d

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.