ETH Price: $2,919.69 (+3.53%)
 

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Withdraw Token165468482023-02-03 7:45:11644 days ago1675410311IN
Kyber: Reserve Eth2Dai 2
0 ETH0.0008321922.2590198
Withdraw Ether165468442023-02-03 7:44:23644 days ago1675410263IN
Kyber: Reserve Eth2Dai 2
0 ETH0.0007157322.10699734
Set Contracts104105742020-07-07 6:10:311585 days ago1594102231IN
Kyber: Reserve Eth2Dai 2
0 ETH0.0013672144
Delist Token94410092020-02-08 8:26:351735 days ago1581150395IN
Kyber: Reserve Eth2Dai 2
0 ETH0.000209098
Set Fee Bps94409952020-02-08 8:24:031735 days ago1581150243IN
Kyber: Reserve Eth2Dai 2
0 ETH0.000113698
Set Contracts94407122020-02-08 7:23:171735 days ago1581146597IN
Kyber: Reserve Eth2Dai 2
0 ETH0.000248488
Add Alerter94407052020-02-08 7:21:391735 days ago1581146499IN
Kyber: Reserve Eth2Dai 2
0 ETH0.000705968
Add Operator94407032020-02-08 7:21:021735 days ago1581146462IN
Kyber: Reserve Eth2Dai 2
0 ETH0.00070568
Set Token Config...94372842020-02-07 18:47:561735 days ago1581101276IN
Kyber: Reserve Eth2Dai 2
0 ETH0.0006947610
List Token94372812020-02-07 18:46:461735 days ago1581101206IN
Kyber: Reserve Eth2Dai 2
0 ETH0.0007509310
Set Token Config...94372792020-02-07 18:45:551735 days ago1581101155IN
Kyber: Reserve Eth2Dai 2
0 ETH0.0006947610
List Token94372762020-02-07 18:45:261735 days ago1581101126IN
Kyber: Reserve Eth2Dai 2
0 ETH0.0007509310
Set Token Config...94372742020-02-07 18:44:501735 days ago1581101090IN
Kyber: Reserve Eth2Dai 2
0 ETH0.0006947610
List Token94372622020-02-07 18:43:051735 days ago1581100985IN
Kyber: Reserve Eth2Dai 2
0 ETH0.000659819
0x6080604094371062020-02-07 18:08:521735 days ago1581098932IN
 Contract Creation
0 ETH0.017991864

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
165468442023-02-03 7:44:23644 days ago1675410263
Kyber: Reserve Eth2Dai 2
0.15466341 ETH
108312232020-09-10 2:10:381520 days ago1599703838
Kyber: Reserve Eth2Dai 2
4.98603351 ETH
108312232020-09-10 2:10:381520 days ago1599703838
Kyber: Reserve Eth2Dai 2
4.98603351 ETH
108300892020-09-09 21:50:241520 days ago1599688224
Kyber: Reserve Eth2Dai 2
176.32415262 ETH
108300892020-09-09 21:50:241520 days ago1599688224
Kyber: Reserve Eth2Dai 2
176.32415262 ETH
108300872020-09-09 21:49:411520 days ago1599688181
Kyber: Reserve Eth2Dai 2
135.22734478 ETH
108300872020-09-09 21:49:411520 days ago1599688181
Kyber: Reserve Eth2Dai 2
135.22734478 ETH
108300832020-09-09 21:49:021520 days ago1599688142
Kyber: Reserve Eth2Dai 2
253.971 ETH
108300832020-09-09 21:49:021520 days ago1599688142
Kyber: Reserve Eth2Dai 2
253.971 ETH
108300772020-09-09 21:47:021520 days ago1599688022
Kyber: Reserve Eth2Dai 2
278.06134731 ETH
108300772020-09-09 21:47:021520 days ago1599688022
Kyber: Reserve Eth2Dai 2
278.06134731 ETH
108300762020-09-09 21:47:001520 days ago1599688020
Kyber: Reserve Eth2Dai 2
278.06134731 ETH
108300762020-09-09 21:47:001520 days ago1599688020
Kyber: Reserve Eth2Dai 2
278.06134731 ETH
108300752020-09-09 21:46:431520 days ago1599688003
Kyber: Reserve Eth2Dai 2
348.07178897 ETH
108300752020-09-09 21:46:431520 days ago1599688003
Kyber: Reserve Eth2Dai 2
348.07178897 ETH
108300752020-09-09 21:46:431520 days ago1599688003
Kyber: Reserve Eth2Dai 2
322.09253158 ETH
108300752020-09-09 21:46:431520 days ago1599688003
Kyber: Reserve Eth2Dai 2
322.09253158 ETH
108300012020-09-09 21:32:091520 days ago1599687129
Kyber: Reserve Eth2Dai 2
134.99240075 ETH
108300012020-09-09 21:32:091520 days ago1599687129
Kyber: Reserve Eth2Dai 2
134.99240075 ETH
108227172020-09-08 18:46:201521 days ago1599590780
Kyber: Reserve Eth2Dai 2
40.69472401 ETH
108227172020-09-08 18:46:201521 days ago1599590780
Kyber: Reserve Eth2Dai 2
40.69472401 ETH
108210162020-09-08 12:32:551521 days ago1599568375
Kyber: Reserve Eth2Dai 2
38.21473005 ETH
108210162020-09-08 12:32:551521 days ago1599568375
Kyber: Reserve Eth2Dai 2
38.21473005 ETH
108210152020-09-08 12:32:541521 days ago1599568374
Kyber: Reserve Eth2Dai 2
38.21473005 ETH
108210152020-09-08 12:32:541521 days ago1599568374
Kyber: Reserve Eth2Dai 2
38.21473005 ETH
View All Internal Transactions
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0xB5A6De4D...0BA5DDb7F
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
Eth2DaiReserve

Compiler Version
v0.5.11+commit.c082d0b4

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity Multiple files format)

File 1 of 7: Eth2DaiReserve.sol
pragma solidity 0.5.11;

import "./IERC20.sol";
import "./IKyberReserve.sol";
import "./WithdrawableV5.sol";
import "./UtilsV5.sol";
import "./IOtc.sol";

contract IWeth is IERC20 {
    function deposit() public payable;
    function withdraw(uint) public;
}

contract Eth2DaiReserve is IKyberReserve, Withdrawable, Utils {

    // constants
    uint constant internal INVALID_ID = uint(-1);
    uint constant internal POW_2_32 = 2 ** 32;
    uint constant internal POW_2_96 = 2 ** 96;
    uint constant internal BPS = 10000; // 10^4

    // values
    address public kyberNetwork;
    bool public tradeEnabled;
    uint public feeBps;

    IOtc public otc;
    IWeth public wethToken;// = IWeth(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);

    mapping(address => bool) public isTokenListed;
    // 1 bit: isInternalInventoryEnabled, 95 bits: min token, 96 bits: max token, 32 bits: premiumBps, 32 bits: minSpreadBps;
    mapping(address => uint) internal internalInventoryData;
    // basicData contains compact data of min eth support, max traverse and max takes
    // min eth support (first 192 bits) + max traverse (32 bits) + max takes (32 bits) = 256 bits
    mapping(address => uint) internal tokenBasicData;
    // factorData contains compact data of factors to compute max traverse, max takes, and min take order size
    // 6 params, each 32 bits (6 * 32 = 192 bits)
    mapping(address => uint) internal tokenFactorData;

    struct BasicDataConfig {
        uint minETHSupport;
        uint maxTraverse;
        uint maxTakes;
    }

    struct FactorDataConfig {
        uint maxTraverseX;
        uint maxTraverseY;
        uint maxTakeX;
        uint maxTakeY;
        uint minOrderSizeX;
        uint minOrderSizeY;
    }

    struct InternalInventoryData {
        bool isEnabled;
        uint minTokenBal;
        uint maxTokenBal;
        uint premiumBps;
        uint minSpreadBps;
    }

    struct OfferData {
        uint payAmount;
        uint buyAmount;
        uint id;
    }

    constructor(address _kyberNetwork, uint _feeBps, address _otc, address _weth, address _admin) 
        public Withdrawable(_admin)
    {
        require(_kyberNetwork != address(0), "constructor: kyberNetwork's address is missing");
        require(_otc != address(0), "constructor: otc's address is missing");
        require(_weth != address(0), "constructor: weth's address is missing");
        require(_feeBps < BPS, "constructor: fee >= bps");
        
        wethToken = IWeth(_weth);
        require(getDecimals(wethToken) == MAX_DECIMALS, "constructor: wethToken's decimals is not MAX_DECIMALS");
        require(wethToken.approve(_otc, 2**255), "constructor: failed to approve otc (wethToken)");

        kyberNetwork = _kyberNetwork;
        otc = IOtc(_otc);
        feeBps = _feeBps;
        admin = _admin;
        tradeEnabled = true;
    }

    function() external payable {} // solhint-disable-line no-empty-blocks

    /**
        Returns conversion rate of given pair and srcQty, use 1 as srcQty if srcQty = 0
        Using eth amount to compute offer limit configurations
        => need to check spread is ok for token -> eth
        Last bit of the rate indicates whether to use internal inventory:
          0 - use eth2dai
          1 - use internal inventory
    */
    function getConversionRate(IERC20 src, IERC20 dest, uint srcQty, uint) public view returns(uint) {
        if (!tradeEnabled) { return 0; }
        if (srcQty == 0) { return 0; }
        // check if token's listed
        IERC20 token = src == ETH_TOKEN_ADDRESS ? dest : src;
        if (!isTokenListed[address(token)]) { return 0; }

        OfferData memory bid;
        OfferData memory ask;
        (bid, ask) = getFirstBidAndAskOrders(token);

        // if token is src, need to check for valid spread
        if (token == src && !checkValidSpread(bid, ask, false, 0)) { return 0; }

        uint destQty;
        OfferData[] memory offers;

        if (src == ETH_TOKEN_ADDRESS) {
            (destQty, offers) = findBestOffers(dest, wethToken, srcQty, bid, ask);
        } else {
            (destQty, offers) = findBestOffers(wethToken, src, srcQty, bid, ask);
        }

        if (offers.length == 0 || destQty == 0) { return 0; } // no offer or destQty == 0, return 0 for rate

        uint rate = calcRateFromQty(srcQty, destQty, MAX_DECIMALS, MAX_DECIMALS);

        bool useInternalInventory;
        uint premiumBps;

        if (src == ETH_TOKEN_ADDRESS) {
            (useInternalInventory, premiumBps) = shouldUseInternalInventory(dest,
                                                                            destQty,
                                                                            srcQty,
                                                                            true,
                                                                            bid,
                                                                            ask
                                                                            );
        } else {
            (useInternalInventory, premiumBps) = shouldUseInternalInventory(src,
                                                                            srcQty,
                                                                            destQty,
                                                                            false,
                                                                            bid,
                                                                            ask
                                                                            );
        }

        if (useInternalInventory) {
            rate = valueAfterAddingPremium(rate, premiumBps);
        } else {
            rate = valueAfterReducingFee(rate);
        }

        return applyInternalInventoryHintToRate(rate, useInternalInventory);
    }

    event TradeExecute(
        address indexed origin,
        address src,
        uint srcAmount,
        address destToken,
        uint destAmount,
        address payable destAddress
    );

    function trade(
        IERC20 srcToken,
        uint srcAmount,
        IERC20 destToken,
        address payable destAddress,
        uint conversionRate,
        bool validate
    )
        public
        payable
        returns(bool)
    {
        require(tradeEnabled, "trade: tradeEnabled is false");
        require(msg.sender == kyberNetwork, "trade: not call from kyberNetwork's contract");
        require(srcToken == ETH_TOKEN_ADDRESS || destToken == ETH_TOKEN_ADDRESS, "trade: srcToken or destToken must be ETH");

        IERC20 token = srcToken == ETH_TOKEN_ADDRESS ? destToken : srcToken;
        require(isTokenListed[address(token)], "trade: token is not listed");

        require(doTrade(srcToken, srcAmount, destToken, destAddress, conversionRate, validate), "trade: doTrade returns false");
        return true;
    }

    event TokenConfigDataSet(
        IERC20 token, uint maxTraverse, uint traveseFactorX, uint traveseFactorY,
        uint maxTake, uint takeFactorX, uint takeFactorY,
        uint minSizeFactorX, uint minSizeFactorY, uint minETHSupport
    );

    function setTokenConfigData(
        IERC20 token, uint maxTraverse, uint traveseFactorX, uint traveseFactorY,
        uint maxTake, uint takeFactorX, uint takeFactorY,
        uint minSizeFactorX, uint minSizeFactorY, uint minETHSupport
    )
        public onlyAdmin
    {
        address tokenAddr = address(token);
        require(isTokenListed[tokenAddr]);
        tokenBasicData[tokenAddr] = encodeTokenBasicData(minETHSupport, maxTraverse, maxTake);
        tokenFactorData[tokenAddr] = encodeFactorData(
            traveseFactorX,
            traveseFactorY,
            takeFactorX,
            takeFactorY,
            minSizeFactorX,
            minSizeFactorY
        );
        emit TokenConfigDataSet(
            token, maxTraverse, traveseFactorX, takeFactorY,
            maxTake, takeFactorX, takeFactorY,
            minSizeFactorX, minSizeFactorY, minETHSupport
        );
    }

    event TradeEnabled(bool enable);

    function enableTrade() public onlyAdmin returns(bool) {
        tradeEnabled = true;
        emit TradeEnabled(true);

        return true;
    }

    function disableTrade() public onlyAlerter returns(bool) {
        tradeEnabled = false;
        emit TradeEnabled(false);

        return true;
    }

    event ContractsSet(address kyberNetwork, address otc);

    function setContracts(address _kyberNetwork, address _otc) public onlyAdmin {
        require(_kyberNetwork != address(0), "setContracts: kyberNetwork's address is missing");
        require(_otc != address(0), "setContracts: otc's address is missing");

        kyberNetwork = _kyberNetwork;

        if (_otc != address(otc)) {
            // new otc address
            require(wethToken.approve(address(otc), 0), "setContracts: failed to reset allowance for old otc (wethToken)");
            otc = IOtc(_otc);
            require(wethToken.approve(_otc, 2**255), "setContracts: failed to approve otc (wethToken)");
        }

        emit ContractsSet(_kyberNetwork, _otc);
    }

    event InternalInventoryDataSet(uint minToken, uint maxToken, uint pricePremiumBps, uint minSpreadBps);

    function setInternalInventoryData(
        IERC20 token,
        bool isEnabled,
        uint minToken,
        uint maxToken,
        uint pricePremiumBps,
        uint minSpreadBps
    )
        public onlyAdmin
    {
        require(isTokenListed[address(token)], "setInternalInventoryData: token is not listed");
        require(minToken < POW_2_96/2, "setInternalInventoryData: minToken > 2**95");
        require(maxToken < POW_2_96, "setInternalInventoryData: maxToken > 2**96");
        require(pricePremiumBps < POW_2_32, "setInternalInventoryData: pricePremiumBps > 2**32");
        require(minSpreadBps < POW_2_32, "setInternalInventoryData: minSpreadBps > 2**32");

        internalInventoryData[address(token)] = encodeInternalInventoryData(isEnabled, minToken, maxToken, pricePremiumBps, minSpreadBps);

        emit InternalInventoryDataSet(minToken, maxToken, pricePremiumBps, minSpreadBps);
    }

    event TokenListed(IERC20 token);

    function listToken(IERC20 token) public onlyAdmin {
        address tokenAddr = address(token);

        require(tokenAddr != address(0), "listToken: token's address is missing");
        require(!isTokenListed[tokenAddr], "listToken: token's alr listed");
        require(getDecimals(token) == MAX_DECIMALS, "listToken: token's decimals is not MAX_DECIMALS");
        require(token.approve(address(otc), 2**255), "listToken: approve token otc failed");

        isTokenListed[tokenAddr] = true;

        emit TokenListed(token);
    }

    event TokenDelisted(IERC20 token);

    function delistToken(IERC20 token) public onlyAdmin {
        address tokenAddr = address(token);

        require(isTokenListed[tokenAddr], "delistToken: token is not listed");
        require(token.approve(address(otc), 0), "delistToken: reset approve token failed");

        delete isTokenListed[tokenAddr];
        delete internalInventoryData[tokenAddr];
        delete tokenFactorData[tokenAddr];
        delete tokenBasicData[tokenAddr];

        emit TokenDelisted(token);
    }

    event FeeBpsSet(uint feeBps);

    function setFeeBps(uint _feeBps) public onlyAdmin {
        require(_feeBps < BPS, "setFeeBps: feeBps >= bps");

        feeBps = _feeBps;
        emit FeeBpsSet(feeBps);
    }

    function showBestOffers(IERC20 token, bool isEthToToken, uint srcAmountToken)
        public view
        returns(uint destAmount, uint destAmountToken, uint[] memory offerIds) 
    {
        if (srcAmountToken == 0) {
            // return 0
            destAmount = 0;
            destAmountToken = 0;
            offerIds = new uint[](0);
            return (destAmount, destAmountToken, offerIds);
        }

        OfferData[] memory offers;
        IERC20 dstToken = isEthToToken ? token : wethToken;
        IERC20 srcToken = isEthToToken ? wethToken : token;

        OfferData memory bid;
        OfferData memory ask;
        (bid, ask) = getFirstBidAndAskOrders(token);

        (destAmount, offers) = findBestOffers(dstToken, srcToken, (srcAmountToken * 10 ** 18), bid, ask);

        destAmountToken = destAmount / 10 ** 18;

        uint i;
        for (i; i < offers.length; i++) {
            if (offers[i].id == 0) {
                break;
            }
        }

        offerIds = new uint[](i);
        for (i = 0; i < offerIds.length; i++) {
            offerIds[i] = offers[i].id;
        }
    }

    function getTokenBasicDataPub(IERC20 token)
        public view
        returns (uint minETHSupport, uint maxTraverse, uint maxTakes)
    {
        (minETHSupport, maxTraverse, maxTakes) = decodeTokenBasicData(tokenBasicData[address(token)]);
    }

    function getFactorDataPub(IERC20 token)
        public view
        returns (uint maxTraverseX, uint maxTraverseY, uint maxTakeX, uint maxTakeY, uint minOrderSizeX, uint minOrderSizeY)
    {
        (maxTraverseX, maxTraverseY, maxTakeX, maxTakeY, minOrderSizeX, minOrderSizeY) = decodeFactorData(tokenFactorData[address(token)]);
    }

    function getInternalInventoryDataPub(IERC20 token)
        public view
        returns(bool isEnabled, uint minTokenBal, uint maxTokenBal, uint premiumBps, uint minSpreadBps)
    {
        (isEnabled, minTokenBal, maxTokenBal, premiumBps, minSpreadBps) = decodeInternalInventoryData(internalInventoryData[address(token)]);
    }

    /// @dev do a trade
    /// @param srcToken Src token
    /// @param srcAmount Amount of src token
    /// @param destToken Destination token
    /// @param destAddress Destination address to send tokens to
    /// @return true iff trade is successful
    function doTrade(
        IERC20 srcToken,
        uint srcAmount,
        IERC20 destToken,
        address payable destAddress,
        uint conversionRate,
        bool validate
    )
        internal
        returns(bool)
    {
        // can skip validation if done at kyber network level
        if (validate) {
            require(conversionRate > 0, "doTrade: conversionRate is 0");
            if (srcToken == ETH_TOKEN_ADDRESS)
                require(msg.value == srcAmount, "doTrade: msg.value != srcAmount");
            else
                require(msg.value == 0, "doTrade: msg.value must be 0");
        }

        uint userExpectedDestAmount = calcDstQty(srcAmount, MAX_DECIMALS, MAX_DECIMALS, conversionRate);
        require(userExpectedDestAmount > 0, "doTrade: userExpectedDestAmount == 0"); // sanity check

        uint actualDestAmount;

        // using hint to check if we should use our internal inventory
        bool useInternalInventory = conversionRate % 2 == 1;

        if (useInternalInventory) {
            // taking from internal inventory and return
            if (srcToken == ETH_TOKEN_ADDRESS) {
                // transfer back only requested dest amount.
                require(destToken.transfer(destAddress, userExpectedDestAmount), "doTrade: (useInternalInventory) can not transfer back token");
            } else {
                // collect src token
                require(srcToken.transferFrom(msg.sender, address(this), srcAmount), "doTrade: (useInternalInventory) can not collect src token");
                // transfer back only requested dest amount.
                destAddress.transfer(userExpectedDestAmount);
            }

            emit TradeExecute(msg.sender, address(srcToken), srcAmount, address(destToken), userExpectedDestAmount, destAddress);
            return true;
        }

        OfferData memory bid;
        OfferData memory ask;
        (bid, ask) = getFirstBidAndAskOrders(srcToken == ETH_TOKEN_ADDRESS ? destToken : srcToken);

        // get offers to take
        OfferData[] memory offers;
        if (srcToken == ETH_TOKEN_ADDRESS) {
            (actualDestAmount, offers) = findBestOffers(destToken, wethToken, srcAmount, bid, ask);
        } else {
            (actualDestAmount, offers) = findBestOffers(wethToken, srcToken, srcAmount, bid, ask);
        }

        require(actualDestAmount >= userExpectedDestAmount, "doTrade: actualDestAmount is less than userExpectedDestAmount");

        if (srcToken == ETH_TOKEN_ADDRESS) {
            wethToken.deposit.value(msg.value)();
            actualDestAmount = takeMatchingOrders(destToken, srcAmount, offers);
            require(actualDestAmount >= userExpectedDestAmount, "doTrade: actualDestAmount is less than userExpectedDestAmount, eth to token");
            // transfer back only requested dest amount
            require(destToken.transfer(destAddress, userExpectedDestAmount), "doTrade: can not transfer back requested token");
        } else {
            // collect src tokens
            require(srcToken.transferFrom(msg.sender, address(this), srcAmount), "doTrade: can not collect src token");
            actualDestAmount = takeMatchingOrders(wethToken, srcAmount, offers);
            require(actualDestAmount >= userExpectedDestAmount, "doTrade: actualDestAmount is less than userExpectedDestAmount, token to eth");
            wethToken.withdraw(actualDestAmount);
            // transfer back only requested dest amount.
            destAddress.transfer(userExpectedDestAmount);
        }

        emit TradeExecute(msg.sender, address(srcToken), srcAmount, address(destToken), userExpectedDestAmount, destAddress);
        return true;
    }

    function takeMatchingOrders(IERC20 destToken, uint srcAmount, OfferData[] memory offers)
        internal
        returns(uint actualDestAmount)
    {
        require(destToken != ETH_TOKEN_ADDRESS, "takeMatchingOrders: destToken is ETH");

        uint lastReserveBalance = destToken.balanceOf(address(this));
        uint remainingSrcAmount = srcAmount;

        for (uint i = 0; i < offers.length; i++) {
            if (offers[i].id == 0 || remainingSrcAmount == 0) { break; }

            uint payAmount = minOf(remainingSrcAmount, offers[i].payAmount);
            uint buyAmount = payAmount * offers[i].buyAmount / offers[i].payAmount;

            otc.take(bytes32(offers[i].id), uint128(buyAmount));
            remainingSrcAmount -= payAmount;
        }

        // must use all amount
        require(remainingSrcAmount == 0, "takeMatchingOrders: did not take all src amount");

        uint newReserveBalance = destToken.balanceOf(address(this));

        require(newReserveBalance > lastReserveBalance, "takeMatchingOrders: newReserveBalance <= lastReserveBalance");

        actualDestAmount = newReserveBalance - lastReserveBalance;
    }

    function shouldUseInternalInventory(
        IERC20 token,
        uint tokenVal,
        uint ethVal,
        bool ethToToken,
        OfferData memory bid,
        OfferData memory ask
    )
        internal view
        returns(bool shouldUse, uint premiumBps)
    {
        shouldUse = false;
        premiumBps = 0;

        if (tokenVal > MAX_QTY) { return (shouldUse, premiumBps); }

        InternalInventoryData memory inventoryData = getInternalInventoryData(token);
        if (!inventoryData.isEnabled) { return (shouldUse, premiumBps); }

        premiumBps = inventoryData.premiumBps;

        uint tokenBalance = token.balanceOf(address(this));

        if (ethToToken) {
            if (tokenBalance < tokenVal) { return (shouldUse, premiumBps); }
            if (tokenBalance - tokenVal < inventoryData.minTokenBal) { return (shouldUse, premiumBps); }
        } else {
            if (address(this).balance < ethVal) { return (shouldUse, premiumBps); }
            if (tokenBalance + tokenVal > inventoryData.maxTokenBal) { return (shouldUse, premiumBps); }
        }

        if (!checkValidSpread(bid, ask, true, inventoryData.minSpreadBps)) {
            return (shouldUse, premiumBps);
        }

        shouldUse = true;
    }

    function applyInternalInventoryHintToRate(
        uint rate,
        bool useInternalInventory
    )
        internal pure
        returns(uint)
    {
        return rate % 2 == (useInternalInventory ? 1 : 0)
            ? rate
            : rate - 1;
    }

    function valueAfterReducingFee(uint val) internal view returns(uint) {
        require(val <= MAX_QTY, "valueAfterReducingFee: val > MAX_QTY");
        return ((BPS - feeBps) * val) / BPS;
    }

    function valueAfterAddingPremium(uint val, uint premium) internal pure returns(uint) {
        require(val <= MAX_QTY, "valueAfterAddingPremium: val > MAX_QTY");
        return val * (BPS + premium) / BPS;
    }

    function findBestOffers(
        IERC20 dstToken,
        IERC20 srcToken,
        uint srcAmount,
        OfferData memory bid,
        OfferData memory ask
    )
        internal view
        returns(uint totalDestAmount, OfferData[] memory offers)
    {
        uint remainingSrcAmount = srcAmount;
        uint maxOrdersToTake;
        uint maxTraversedOrders;
        uint minPayAmount;
        uint numTakenOffer = 0;
        totalDestAmount = 0;
        IERC20 token = srcToken == wethToken ? dstToken : srcToken;

        (maxOrdersToTake, maxTraversedOrders, minPayAmount) = calcOfferLimitsFromFactorData(
            token,
            (srcToken == wethToken),
            bid,
            ask,
            srcAmount
        );

        offers = new OfferData[](maxTraversedOrders);

        // return earlier, we don't want to take any orders
        if (maxTraversedOrders == 0 || maxOrdersToTake == 0) {
            return (totalDestAmount, offers);
        }

        // otc's terminology is of offer maker, so their sellGem is our (the taker's) dest token.
        // if we don't have best offers, get them.
        if ((srcToken == wethToken && bid.id == 0) || (dstToken == wethToken && ask.id == 0)) {
            offers[0].id = otc.getBestOffer(dstToken, srcToken);
            // assuming pay amount is taker pay amount. (in otc it is used differently)
            (offers[0].buyAmount, , offers[0].payAmount, ) = otc.getOffer(offers[0].id);
        } else {
            offers[0] = srcToken == wethToken ? bid : ask;
        }

        uint thisOffer;

        OfferData memory biggestSkippedOffer = OfferData(0, 0, 0);

        for (; maxTraversedOrders > 0; --maxTraversedOrders) {
            thisOffer = numTakenOffer;

            // in case both biggestSkippedOffer & current offer have amount >= remainingSrcAmount
            // biggestSkippedOffer should have better rate than current offer
            if (biggestSkippedOffer.payAmount >= remainingSrcAmount) {
                offers[numTakenOffer].id = biggestSkippedOffer.id;
                offers[numTakenOffer].buyAmount = remainingSrcAmount * biggestSkippedOffer.buyAmount / biggestSkippedOffer.payAmount;
                offers[numTakenOffer].payAmount = remainingSrcAmount;
                totalDestAmount += offers[numTakenOffer].buyAmount;
                ++numTakenOffer;
                remainingSrcAmount = 0;
                break;
            } else if (offers[numTakenOffer].payAmount >= remainingSrcAmount) {
                offers[numTakenOffer].buyAmount = remainingSrcAmount * offers[numTakenOffer].buyAmount / offers[numTakenOffer].payAmount;
                offers[numTakenOffer].payAmount = remainingSrcAmount;
                totalDestAmount += offers[numTakenOffer].buyAmount;
                ++numTakenOffer;
                remainingSrcAmount = 0;
                break;
            } else if ((maxOrdersToTake - numTakenOffer) > 1
                        && offers[numTakenOffer].payAmount >= minPayAmount) {
                totalDestAmount += offers[numTakenOffer].buyAmount;
                remainingSrcAmount -= offers[numTakenOffer].payAmount;
                ++numTakenOffer;
            } else if (offers[numTakenOffer].payAmount > biggestSkippedOffer.payAmount) {
                biggestSkippedOffer.payAmount = offers[numTakenOffer].payAmount;
                biggestSkippedOffer.buyAmount = offers[numTakenOffer].buyAmount;
                biggestSkippedOffer.id = offers[numTakenOffer].id;
            }

            offers[numTakenOffer].id = otc.getWorseOffer(offers[thisOffer].id);
            (offers[numTakenOffer].buyAmount, , offers[numTakenOffer].payAmount, ) = otc.getOffer(offers[numTakenOffer].id);
        }

        if (remainingSrcAmount > 0) totalDestAmount = 0;
        if (totalDestAmount == 0) offers = new OfferData[](0);
    }

    // returns max takes, max traverse, min order size to take using config factor data
    function calcOfferLimitsFromFactorData(
        IERC20 token,
        bool isEthToToken,
        OfferData memory bid,
        OfferData memory ask, uint srcAmount
    )
        internal view
        returns(uint maxTakes, uint maxTraverse, uint minPayAmount)
    {
        if (!isEthToToken && (ask.id == 0 || bid.id == 0)) {
            // need to compute equivalent eth amount but no ask and bid offers are available
            maxTakes = 0;
            maxTraverse = 0;
            minPayAmount = 0;
            return (maxTakes, maxTraverse, minPayAmount);
        }

        uint order0Pay = 0;
        uint order0Buy = 0;

        if (!isEthToToken) {
            // only need to use median when token -> eth trade
            order0Pay = ask.payAmount;
            order0Buy = (ask.buyAmount + ask.payAmount * bid.payAmount / bid.buyAmount) / 2;
        }

        uint ethOrderSize = isEthToToken ? srcAmount : srcAmount * order0Buy / order0Pay;

        BasicDataConfig memory basicData = getTokenBasicData(token);

        if (basicData.minETHSupport > ethOrderSize) {
            maxTakes = 0;
            maxTraverse = 0;
            minPayAmount = 0;
            return (maxTakes, maxTraverse, minPayAmount);
        }

        FactorDataConfig memory factorData = getFactorData(token);

        uint tokenFactorBPS = 100000; // 10^5

        maxTraverse = (factorData.maxTraverseX * ethOrderSize / PRECISION + factorData.maxTraverseY) / tokenFactorBPS;
        maxTraverse = minOf(maxTraverse, basicData.maxTraverse);

        maxTakes = (factorData.maxTakeX * ethOrderSize / PRECISION + factorData.maxTakeY) / tokenFactorBPS;
        maxTakes = minOf(maxTakes, basicData.maxTakes);

        uint minETHAmount = (factorData.minOrderSizeX * ethOrderSize + factorData.minOrderSizeY * PRECISION) / tokenFactorBPS;

        // translate min amount to pay token
        minPayAmount = isEthToToken ? minETHAmount : minETHAmount * order0Pay / order0Buy;
    }

    // bid: buy WETH, ask: sell WETH (their base token is DAI)
    function getFirstBidAndAskOrders(IERC20 token)
        internal view
        returns(OfferData memory bid, OfferData memory ask)
    {
        // getting first bid offer (buy WETH)
        (bid.id, bid.payAmount, bid.buyAmount) = getFirstOffer(token, wethToken);
        // getting first ask offer (sell WETH)
        (ask.id, ask.payAmount, ask.buyAmount) = getFirstOffer(wethToken, token);
    }

    function getFirstOffer(IERC20 offerSellGem, IERC20 offerBuyGem)
        internal view
        returns(uint offerId, uint offerPayAmount, uint offerBuyAmount)
    {
        offerId = otc.getBestOffer(offerSellGem, offerBuyGem);
        (offerBuyAmount, , offerPayAmount, ) = otc.getOffer(offerId);
    }

    function checkValidSpread(OfferData memory bid, OfferData memory ask, bool isCheckingMinSpread, uint minSpreadBps)
        internal pure
        returns(bool)
    {
        // if no bid or ask order, consider as invalid spread?
        if (bid.id == 0 || ask.id == 0 || bid.buyAmount > MAX_QTY || bid.payAmount > MAX_QTY || ask.buyAmount > MAX_QTY || ask.payAmount > MAX_QTY) {
            return false;
        }

        uint x1 = ask.payAmount * bid.payAmount;
        uint x2 = ask.buyAmount * bid.buyAmount;

        // must check sellRate > buyRate
        if (x1 <= x2) { return false; }

        // if no need to check for min spread, return true here
        if (!isCheckingMinSpread) { return true; }

        // spread should be bigger than minSpreadBps
        if (BPS * (x1 - x2) <= x2 * minSpreadBps) { return false; }

        return true;
    }

    function getTokenBasicData(IERC20 token)
        internal view
        returns(BasicDataConfig memory data)
    {
        (data.minETHSupport, data.maxTraverse, data.maxTakes) = decodeTokenBasicData(tokenBasicData[address(token)]);
    }

    function getFactorData(IERC20 token)
        internal view
        returns(FactorDataConfig memory data)
    {
        (data.maxTraverseX, data.maxTraverseY, data.maxTakeX, data.maxTakeY, data.minOrderSizeX, data.minOrderSizeY) = decodeFactorData(tokenFactorData[address(token)]);
    }

    function getInternalInventoryData(IERC20 token)
        internal view
        returns(InternalInventoryData memory data)
    {
        (bool isEnabled, uint minTokenBal, uint maxTokenBal, uint premiumBps, uint minSpreadBps) = decodeInternalInventoryData(internalInventoryData[address(token)]);
        data.isEnabled = isEnabled;
        data.minTokenBal = minTokenBal;
        data.maxTokenBal = maxTokenBal;
        data.premiumBps = premiumBps;
        data.minSpreadBps = minSpreadBps;
    }

    function encodeInternalInventoryData(bool isEnabled, uint minTokenBal, uint maxTokenBal, uint premiumBps, uint minSpreadBps)
        internal pure
        returns(uint data)
    {
        require(minSpreadBps < POW_2_32, "encodeInternalInventoryData: minSpreadBps is too big");
        require(premiumBps < POW_2_32, "encodeInternalInventoryData: premiumBps is too big");
        require(maxTokenBal < POW_2_96, "encodeInternalInventoryData: maxTokenBal is too big");
        require(minTokenBal < POW_2_96, "encodeInternalInventoryData: minTokenBal is too big");
        data = minSpreadBps & (POW_2_32 - 1);
        data |= (premiumBps & (POW_2_32 - 1)) * POW_2_32;
        data |= (maxTokenBal & (POW_2_96 - 1)) * POW_2_32 * POW_2_32;
        data |= (minTokenBal & (POW_2_96 / 2 - 1)) * POW_2_96 * POW_2_32 * POW_2_32;
        data |= (isEnabled ? 1 : 0) * (POW_2_96 / 2) * POW_2_96 * POW_2_32 * POW_2_32;
    }

    function decodeInternalInventoryData(uint data)
        internal pure
        returns(bool isEnabled, uint minTokenBal, uint maxTokenBal, uint premiumBps, uint minSpreadBps)
    {
        minSpreadBps = data & (POW_2_32 - 1);
        premiumBps = (data / POW_2_32) & (POW_2_32 - 1);
        maxTokenBal = (data / (POW_2_32 * POW_2_32)) & (POW_2_96 - 1);
        minTokenBal = (data / (POW_2_96 * POW_2_32 * POW_2_32)) & (POW_2_96 / 2 - 1);
        isEnabled = (data / ((POW_2_96 / 2) * POW_2_96 * POW_2_32 * POW_2_32)) % 2 == 0 ? false : true;
    }

    function encodeTokenBasicData(uint ethSize, uint maxTraverse, uint maxTakes)
        internal pure
        returns(uint data)
    {
        require(maxTakes < POW_2_32, "encodeTokenBasicData: maxTakes is too big");
        require(maxTraverse < POW_2_32, "encodeTokenBasicData: maxTraverse is too big");
        require(ethSize < POW_2_96, "encodeTokenBasicData: ethSize is too big");
        data = maxTakes & (POW_2_32 - 1);
        data |= (maxTraverse & (POW_2_32 - 1)) * POW_2_32;
        data |= (ethSize & (POW_2_96 * POW_2_96 - 1)) * POW_2_32 * POW_2_32;
    }

    function decodeTokenBasicData(uint data)
        internal pure
        returns(uint ethSize, uint maxTraverse, uint maxTakes)
    {
        maxTakes = data & (POW_2_32 - 1);
        maxTraverse = (data / POW_2_32) & (POW_2_32 - 1);
        ethSize = (data / (POW_2_32 * POW_2_32)) & (POW_2_96 * POW_2_96 - 1);
    }

    function encodeFactorData(uint traverseX, uint traverseY, uint takeX, uint takeY, uint minSizeX, uint minSizeY)
        internal pure
        returns(uint data)
    {
        require(minSizeY < POW_2_32, "encodeFactorData: minSizeY is too big");
        require(minSizeX < POW_2_32, "encodeFactorData: minSizeX is too big");
        require(takeY < POW_2_32, "encodeFactorData: takeY is too big");
        require(takeX < POW_2_32, "encodeFactorData: takeX is too big");
        require(traverseY < POW_2_32, "encodeFactorData: traverseY is too big");
        require(traverseX < POW_2_32, "encodeFactorData: traverseX is too big");
        data = (minSizeY & (POW_2_32 - 1));
        data |= (minSizeX & (POW_2_32 - 1)) * POW_2_32;
        data |= (takeY & (POW_2_32 - 1)) * POW_2_32 * POW_2_32;
        data |= (takeX & (POW_2_32 - 1)) * POW_2_96;
        data |= (traverseY & (POW_2_32 - 1)) * POW_2_96 * POW_2_32;
        data |= (traverseX & (POW_2_32 - 1)) * POW_2_96 * POW_2_32 * POW_2_32;
    }

    function decodeFactorData(uint data)
        internal pure
        returns(uint traverseX, uint traverseY, uint takeX, uint takeY, uint minSizeX, uint minSizeY)
    {
        minSizeY = data & (POW_2_32 - 1);
        minSizeX = (data / POW_2_32) & (POW_2_32 - 1);
        takeY = (data / (POW_2_32 * POW_2_32)) & (POW_2_32 - 1);
        takeX = (data / POW_2_96) & (POW_2_32 - 1);
        traverseY = (data / (POW_2_96 * POW_2_32)) & (POW_2_32 - 1);
        traverseX = (data / (POW_2_96 * POW_2_32 * POW_2_32)) & (POW_2_32 - 1);
    }
}

File 2 of 7: IERC20.sol
pragma solidity 0.5.11;


interface IERC20 {
    function transfer(address _to, uint _value) external returns (bool success);
    function transferFrom(address _from, address _to, uint _value) external returns (bool success);
    function approve(address _spender, uint _value) external returns (bool success);
    function totalSupply() external view returns (uint supply);
    function balanceOf(address _owner) external view returns (uint balance);
    function allowance(address _owner, address _spender) external view returns (uint remaining);
    function decimals() external view returns(uint digits);
    event Approval(address indexed _owner, address indexed _spender, uint _value);
}

File 3 of 7: IKyberReserve.sol
pragma solidity 0.5.11;

import "./IERC20.sol";


/// @title Kyber Reserve contract
interface IKyberReserve {

    function trade(
        IERC20 srcToken,
        uint srcAmount,
        IERC20 destToken,
        address payable destAddress,
        uint conversionRate,
        bool validate
    )
        external
        payable
        returns(bool);

    function getConversionRate(IERC20 src, IERC20 dest, uint srcQty, uint blockNumber) external view returns(uint);
}

File 4 of 7: IOtc.sol
pragma solidity 0.5.11;

import "./IERC20.sol";

contract IOtc {
    function getOffer(uint id) external view returns (uint, IERC20, uint, IERC20);
    function getBestOffer(IERC20 sellGem, IERC20 buyGem) external view returns(uint);
    function getWorseOffer(uint id) external view returns(uint);
    function take(bytes32 id, uint128 maxTakeAmount) external;
}

File 5 of 7: PermissionGroupsV5.sol
pragma solidity 0.5.11;


contract PermissionGroups {

    address public admin;
    address public pendingAdmin;
    mapping(address=>bool) internal operators;
    mapping(address=>bool) internal alerters;
    address[] internal operatorsGroup;
    address[] internal alertersGroup;
    uint constant internal MAX_GROUP_SIZE = 50;

    constructor(address _admin) public {
        require(_admin != address(0), "Admin 0");
        admin = _admin;
    }

    modifier onlyAdmin() {
        require(msg.sender == admin);
        _;
    }

    modifier onlyOperator() {
        require(operators[msg.sender]);
        _;
    }

    modifier onlyAlerter() {
        require(alerters[msg.sender]);
        _;
    }

    function getOperators () external view returns(address[] memory) {
        return operatorsGroup;
    }

    function getAlerters () external view returns(address[] memory) {
        return alertersGroup;
    }

    event TransferAdminPending(address pendingAdmin);

    /**
     * @dev Allows the current admin to set the pendingAdmin address.
     * @param newAdmin The address to transfer ownership to.
     */
    function transferAdmin(address newAdmin) public onlyAdmin {
        require(newAdmin != address(0));
        emit TransferAdminPending(pendingAdmin);
        pendingAdmin = newAdmin;
    }

    /**
     * @dev Allows the current admin to set the admin in one tx. Useful initial deployment.
     * @param newAdmin The address to transfer ownership to.
     */
    function transferAdminQuickly(address newAdmin) public onlyAdmin {
        require(newAdmin != address(0));
        emit TransferAdminPending(newAdmin);
        emit AdminClaimed(newAdmin, admin);
        admin = newAdmin;
    }

    event AdminClaimed( address newAdmin, address previousAdmin);

    /**
     * @dev Allows the pendingAdmin address to finalize the change admin process.
     */
    function claimAdmin() public {
        require(pendingAdmin == msg.sender);
        emit AdminClaimed(pendingAdmin, admin);
        admin = pendingAdmin;
        pendingAdmin = address(0);
    }

    event AlerterAdded (address newAlerter, bool isAdd);

    function addAlerter(address newAlerter) public onlyAdmin {
        require(!alerters[newAlerter]); // prevent duplicates.
        require(alertersGroup.length < MAX_GROUP_SIZE);

        emit AlerterAdded(newAlerter, true);
        alerters[newAlerter] = true;
        alertersGroup.push(newAlerter);
    }

    function removeAlerter (address alerter) public onlyAdmin {
        require(alerters[alerter]);
        alerters[alerter] = false;

        for (uint i = 0; i < alertersGroup.length; ++i) {
            if (alertersGroup[i] == alerter) {
                alertersGroup[i] = alertersGroup[alertersGroup.length - 1];
                alertersGroup.length--;
                emit AlerterAdded(alerter, false);
                break;
            }
        }
    }

    event OperatorAdded(address newOperator, bool isAdd);

    function addOperator(address newOperator) public onlyAdmin {
        require(!operators[newOperator]); // prevent duplicates.
        require(operatorsGroup.length < MAX_GROUP_SIZE);

        emit OperatorAdded(newOperator, true);
        operators[newOperator] = true;
        operatorsGroup.push(newOperator);
    }

    function removeOperator (address operator) public onlyAdmin {
        require(operators[operator]);
        operators[operator] = false;

        for (uint i = 0; i < operatorsGroup.length; ++i) {
            if (operatorsGroup[i] == operator) {
                operatorsGroup[i] = operatorsGroup[operatorsGroup.length - 1];
                operatorsGroup.length -= 1;
                emit OperatorAdded(operator, false);
                break;
            }
        }
    }
}

File 6 of 7: UtilsV5.sol
pragma solidity 0.5.11;

import "./IERC20.sol";


/// @title Kyber utils and utils2 contracts
contract Utils {

    IERC20 constant internal ETH_TOKEN_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
    uint  constant internal PRECISION = (10**18);
    uint  constant internal MAX_QTY   = (10**28); // 10B tokens
    uint  constant internal MAX_RATE  = (PRECISION * 10**6); // up to 1M tokens per ETH
    uint  constant internal MAX_DECIMALS = 18;
    uint  constant internal ETH_DECIMALS = 18;

    mapping(address=>uint) internal decimals;

    /// @dev get the balance of a user.
    /// @param token The token type
    /// @return The balance
    function getBalance(IERC20 token, address user) public view returns(uint) {
        if (token == ETH_TOKEN_ADDRESS)
            return user.balance;
        else
            return token.balanceOf(user);
    }

    function setDecimals(IERC20 token) internal {
        if (token == ETH_TOKEN_ADDRESS)
            decimals[address(token)] = ETH_DECIMALS;
        else
            decimals[address(token)] = token.decimals();
    }

    function getDecimals(IERC20 token) internal view returns(uint) {
        if (token == ETH_TOKEN_ADDRESS) return ETH_DECIMALS; // save storage access
        uint tokenDecimals = decimals[address(token)];
        // moreover, very possible that old tokens have decimals 0
        // these tokens will just have higher gas fees.
        if (tokenDecimals == 0) return token.decimals();

        return tokenDecimals;
    }

    function calcDstQty(uint srcQty, uint srcDecimals, uint dstDecimals, uint rate) internal pure returns(uint) {
        require(srcQty <= MAX_QTY);
        require(rate <= MAX_RATE);

        if (dstDecimals >= srcDecimals) {
            require((dstDecimals - srcDecimals) <= MAX_DECIMALS);
            return (srcQty * rate * (10**(dstDecimals - srcDecimals))) / PRECISION;
        } else {
            require((srcDecimals - dstDecimals) <= MAX_DECIMALS);
            return (srcQty * rate) / (PRECISION * (10**(srcDecimals - dstDecimals)));
        }
    }

    function calcSrcQty(uint dstQty, uint srcDecimals, uint dstDecimals, uint rate) internal pure returns(uint) {
        require(dstQty <= MAX_QTY);
        require(rate <= MAX_RATE);

        //source quantity is rounded up. to avoid dest quantity being too low.
        uint numerator;
        uint denominator;
        if (srcDecimals >= dstDecimals) {
            require((srcDecimals - dstDecimals) <= MAX_DECIMALS);
            numerator = (PRECISION * dstQty * (10**(srcDecimals - dstDecimals)));
            denominator = rate;
        } else {
            require((dstDecimals - srcDecimals) <= MAX_DECIMALS);
            numerator = (PRECISION * dstQty);
            denominator = (rate * (10**(dstDecimals - srcDecimals)));
        }
        return (numerator + denominator - 1) / denominator; //avoid rounding down errors
    }

    function calcDestAmount(IERC20 src, IERC20 dest, uint srcAmount, uint rate) internal view returns(uint) {
        return calcDstQty(srcAmount, getDecimals(src), getDecimals(dest), rate);
    }

    function calcSrcAmount(IERC20 src, IERC20 dest, uint destAmount, uint rate) internal view returns(uint) {
        return calcSrcQty(destAmount, getDecimals(src), getDecimals(dest), rate);
    }

    function calcRateFromQty(uint srcAmount, uint destAmount, uint srcDecimals, uint dstDecimals)
        internal pure returns(uint)
    {
        require(srcAmount <= MAX_QTY);
        require(destAmount <= MAX_QTY);

        if (dstDecimals >= srcDecimals) {
            require((dstDecimals - srcDecimals) <= MAX_DECIMALS);
            return (destAmount * PRECISION / ((10 ** (dstDecimals - srcDecimals)) * srcAmount));
        } else {
            require((srcDecimals - dstDecimals) <= MAX_DECIMALS);
            return (destAmount * PRECISION * (10 ** (srcDecimals - dstDecimals)) / srcAmount);
        }
    }

    function minOf(uint x, uint y) internal pure returns(uint) {
        return x > y ? y : x;
    }
}

File 7 of 7: WithdrawableV5.sol
pragma solidity 0.5.11;

import "./IERC20.sol";
import "./PermissionGroupsV5.sol";


contract Withdrawable is PermissionGroups {

    constructor(address _admin) public 
        PermissionGroups(_admin) 
        {}
        
    event TokenWithdraw(IERC20 token, uint amount, address sendTo);

    /**
     * @dev Withdraw all IERC20 compatible tokens
     * @param token IERC20 The address of the token contract
     */
    function withdrawToken(IERC20 token, uint amount, address sendTo) external onlyAdmin {
        require(token.transfer(sendTo, amount));
        emit TokenWithdraw(token, amount, sendTo);
    }

    event EtherWithdraw(uint amount, address sendTo);

    /**
     * @dev Withdraw Ethers
     */
    function withdrawEther(uint amount, address payable sendTo) external onlyAdmin {
        sendTo.transfer(amount);
        emit EtherWithdraw(amount, sendTo);
    }
}

Contract Security Audit

Contract ABI

[{"constant":false,"inputs":[],"name":"enableTrade","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"alerter","type":"address"}],"name":"removeAlerter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"bool","name":"isEthToToken","type":"bool"},{"internalType":"uint256","name":"srcAmountToken","type":"uint256"}],"name":"showBestOffers","outputs":[{"internalType":"uint256","name":"destAmount","type":"uint256"},{"internalType":"uint256","name":"destAmountToken","type":"uint256"},{"internalType":"uint256[]","name":"offerIds","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"listToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"feeBps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pendingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getOperators","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"maxTraverse","type":"uint256"},{"internalType":"uint256","name":"traveseFactorX","type":"uint256"},{"internalType":"uint256","name":"traveseFactorY","type":"uint256"},{"internalType":"uint256","name":"maxTake","type":"uint256"},{"internalType":"uint256","name":"takeFactorX","type":"uint256"},{"internalType":"uint256","name":"takeFactorY","type":"uint256"},{"internalType":"uint256","name":"minSizeFactorX","type":"uint256"},{"internalType":"uint256","name":"minSizeFactorY","type":"uint256"},{"internalType":"uint256","name":"minETHSupport","type":"uint256"}],"name":"setTokenConfigData","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"otc","outputs":[{"internalType":"contract IOtc","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"sendTo","type":"address"}],"name":"withdrawToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newAlerter","type":"address"}],"name":"addAlerter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"wethToken","outputs":[{"internalType":"contract IWeth","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"bool","name":"isEnabled","type":"bool"},{"internalType":"uint256","name":"minToken","type":"uint256"},{"internalType":"uint256","name":"maxToken","type":"uint256"},{"internalType":"uint256","name":"pricePremiumBps","type":"uint256"},{"internalType":"uint256","name":"minSpreadBps","type":"uint256"}],"name":"setInternalInventoryData","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"disableTrade","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC20","name":"srcToken","type":"address"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"contract IERC20","name":"destToken","type":"address"},{"internalType":"address payable","name":"destAddress","type":"address"},{"internalType":"uint256","name":"conversionRate","type":"uint256"},{"internalType":"bool","name":"validate","type":"bool"}],"name":"trade","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_feeBps","type":"uint256"}],"name":"setFeeBps","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"transferAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claimAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"transferAdminQuickly","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getAlerters","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IERC20","name":"src","type":"address"},{"internalType":"contract IERC20","name":"dest","type":"address"},{"internalType":"uint256","name":"srcQty","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"getConversionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOperator","type":"address"}],"name":"addOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"getInternalInventoryDataPub","outputs":[{"internalType":"bool","name":"isEnabled","type":"bool"},{"internalType":"uint256","name":"minTokenBal","type":"uint256"},{"internalType":"uint256","name":"maxTokenBal","type":"uint256"},{"internalType":"uint256","name":"premiumBps","type":"uint256"},{"internalType":"uint256","name":"minSpreadBps","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"delistToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"removeOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"getFactorDataPub","outputs":[{"internalType":"uint256","name":"maxTraverseX","type":"uint256"},{"internalType":"uint256","name":"maxTraverseY","type":"uint256"},{"internalType":"uint256","name":"maxTakeX","type":"uint256"},{"internalType":"uint256","name":"maxTakeY","type":"uint256"},{"internalType":"uint256","name":"minOrderSizeX","type":"uint256"},{"internalType":"uint256","name":"minOrderSizeY","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kyberNetwork","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"sendTo","type":"address"}],"name":"withdrawEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tradeEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_kyberNetwork","type":"address"},{"internalType":"address","name":"_otc","type":"address"}],"name":"setContracts","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"getTokenBasicDataPub","outputs":[{"internalType":"uint256","name":"minETHSupport","type":"uint256"},{"internalType":"uint256","name":"maxTraverse","type":"uint256"},{"internalType":"uint256","name":"maxTakes","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isTokenListed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_kyberNetwork","type":"address"},{"internalType":"uint256","name":"_feeBps","type":"uint256"},{"internalType":"address","name":"_otc","type":"address"},{"internalType":"address","name":"_weth","type":"address"},{"internalType":"address","name":"_admin","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"origin","type":"address"},{"indexed":false,"internalType":"address","name":"src","type":"address"},{"indexed":false,"internalType":"uint256","name":"srcAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"destToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"destAmount","type":"uint256"},{"indexed":false,"internalType":"address payable","name":"destAddress","type":"address"}],"name":"TradeExecute","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"maxTraverse","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"traveseFactorX","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"traveseFactorY","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxTake","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"takeFactorX","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"takeFactorY","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minSizeFactorX","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minSizeFactorY","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minETHSupport","type":"uint256"}],"name":"TokenConfigDataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enable","type":"bool"}],"name":"TradeEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"kyberNetwork","type":"address"},{"indexed":false,"internalType":"address","name":"otc","type":"address"}],"name":"ContractsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minToken","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxToken","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pricePremiumBps","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minSpreadBps","type":"uint256"}],"name":"InternalInventoryDataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20","name":"token","type":"address"}],"name":"TokenListed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20","name":"token","type":"address"}],"name":"TokenDelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"feeBps","type":"uint256"}],"name":"FeeBpsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"sendTo","type":"address"}],"name":"TokenWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"sendTo","type":"address"}],"name":"EtherWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pendingAdmin","type":"address"}],"name":"TransferAdminPending","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"}],"name":"AdminClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAlerter","type":"address"},{"indexed":false,"internalType":"bool","name":"isAdd","type":"bool"}],"name":"AlerterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOperator","type":"address"},{"indexed":false,"internalType":"bool","name":"isAdd","type":"bool"}],"name":"OperatorAdded","type":"event"}]

Deployed Bytecode

0x6080604052600436106101f85760003560e01c806377f50f971161010d578063b6c87f4a116100a0578063d621e8131161006f578063d621e81314610894578063d8952a49146108a9578063dee3ff81146108e4578063e69ec65314610935578063f851a44014610968576101f8565b8063b6c87f4a146107a5578063b78b842d1461080b578063ce56c45414610820578063d4fac45d14610859576101f8565b80639870d7fe116100dc5780639870d7fe146106ac578063a394c85f146106df578063abffc9ac1461073f578063ac8a584a14610772576101f8565b806377f50f97146106065780637acc86781461061b5780637c423f541461064e5780637cd4427214610663576101f8565b806336b61e3c116101905780636526f4e71161015f5780636526f4e7146104f55780636940030f146105485780636cf698111461055d57806372c27b62146105a957806375829def146105d3576101f8565b806336b61e3c146104555780633ccdbb281461046a578063408ee7fe146104ad5780634b57b0be146104e0576101f8565b806324a9d853116101cc57806324a9d8531461032c578063267822471461035357806327a099d81461038457806327d5cc6f146103e9576101f8565b806299d386146101fa57806301a12fd3146102235780630d97fd61146102565780631fc1e25f146102f9575b005b34801561020657600080fd5b5061020f61097d565b604080519115158252519081900360200190f35b34801561022f57600080fd5b506101f86004803603602081101561024657600080fd5b50356001600160a01b03166109e3565b34801561026257600080fd5b506102976004803603606081101561027957600080fd5b506001600160a01b0381351690602081013515159060400135610b46565b6040518084815260200183815260200180602001828103825283818151815260200191508051906020019060200280838360005b838110156102e35781810151838201526020016102cb565b5050505090500194505050505060405180910390f35b34801561030557600080fd5b506101f86004803603602081101561031c57600080fd5b50356001600160a01b0316610ca8565b34801561033857600080fd5b50610341610ed9565b60408051918252519081900360200190f35b34801561035f57600080fd5b50610368610edf565b604080516001600160a01b039092168252519081900360200190f35b34801561039057600080fd5b50610399610eee565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103d55781810151838201526020016103bd565b505050509050019250505060405180910390f35b3480156103f557600080fd5b506101f8600480360361014081101561040d57600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a08101359060c08101359060e081013590610100810135906101200135610f50565b34801561046157600080fd5b50610368611061565b34801561047657600080fd5b506101f86004803603606081101561048d57600080fd5b506001600160a01b03813581169160208101359160409091013516611070565b3480156104b957600080fd5b506101f8600480360360208110156104d057600080fd5b50356001600160a01b031661116b565b3480156104ec57600080fd5b50610368611261565b34801561050157600080fd5b506101f8600480360360c081101561051857600080fd5b506001600160a01b0381351690602081013515159060408101359060608101359060808101359060a00135611270565b34801561055457600080fd5b5061020f61145e565b61020f600480360360c081101561057357600080fd5b506001600160a01b038135811691602081013591604082013581169160608101359091169060808101359060a0013515156114c1565b3480156105b557600080fd5b506101f8600480360360208110156105cc57600080fd5b50356116e8565b3480156105df57600080fd5b506101f8600480360360208110156105f657600080fd5b50356001600160a01b0316611790565b34801561061257600080fd5b506101f861181b565b34801561062757600080fd5b506101f86004803603602081101561063e57600080fd5b50356001600160a01b03166118a5565b34801561065a57600080fd5b50610399611975565b34801561066f57600080fd5b506103416004803603608081101561068657600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356119d5565b3480156106b857600080fd5b506101f8600480360360208110156106cf57600080fd5b50356001600160a01b0316611bcd565b3480156106eb57600080fd5b506107126004803603602081101561070257600080fd5b50356001600160a01b0316611cc3565b60408051951515865260208601949094528484019290925260608401526080830152519081900360a00190f35b34801561074b57600080fd5b506101f86004803603602081101561076257600080fd5b50356001600160a01b0316611cff565b34801561077e57600080fd5b506101f86004803603602081101561079557600080fd5b50356001600160a01b0316611ebf565b3480156107b157600080fd5b506107d8600480360360208110156107c857600080fd5b50356001600160a01b031661201e565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b34801561081757600080fd5b50610368612069565b34801561082c57600080fd5b506101f86004803603604081101561084357600080fd5b50803590602001356001600160a01b0316612078565b34801561086557600080fd5b506103416004803603604081101561087c57600080fd5b506001600160a01b038135811691602001351661210d565b3480156108a057600080fd5b5061020f6121ca565b3480156108b557600080fd5b506101f8600480360360408110156108cc57600080fd5b506001600160a01b03813581169160200135166121da565b3480156108f057600080fd5b506109176004803603602081101561090757600080fd5b50356001600160a01b0316612488565b60408051938452602084019290925282820152519081900360600190f35b34801561094157600080fd5b5061020f6004803603602081101561095857600080fd5b50356001600160a01b03166124bb565b34801561097457600080fd5b506103686124d0565b600080546001600160a01b0316331461099557600080fd5b6007805460ff60a01b1916600160a01b179055604080516001815290517f7d7f00509dd73ac4449f698ae75ccc797895eff5fa9d446d3df387598a26e7359181900360200190a15060015b90565b6000546001600160a01b031633146109fa57600080fd5b6001600160a01b03811660009081526003602052604090205460ff16610a1f57600080fd5b6001600160a01b0381166000908152600360205260408120805460ff191690555b600554811015610b4257816001600160a01b031660058281548110610a6157fe5b6000918252602090912001546001600160a01b03161415610b3a57600580546000198101908110610a8e57fe5b600091825260209091200154600580546001600160a01b039092169183908110610ab457fe5b600091825260209091200180546001600160a01b0319166001600160a01b03929092169190911790556005805490610af0906000198301614525565b50604080516001600160a01b03841681526000602082015281517f5611bf3e417d124f97bf2c788843ea8bb502b66079fbee02158ef30b172cb762929181900390910190a1610b42565b600101610a40565b5050565b600080606083610b6c575050604080516000808252602082019092529091508190610c9f565b6060600086610b8657600a546001600160a01b0316610b88565b875b9050600087610b975788610ba4565b600a546001600160a01b03165b9050610bae61454e565b610bb661454e565b610bbf8b6124df565b9092509050610bdb8484670de0b6b3a76400008c02858561253b565b9098509450670de0b6b3a76400008804965060005b8551811015610c2657858181518110610c0557fe5b60200260200101516040015160001415610c1e57610c26565b600101610bf0565b80604051908082528060200260200182016040528015610c50578160200160208202803883390190505b509650600090505b8651811015610c9857858181518110610c6d57fe5b602002602001015160400151878281518110610c8557fe5b6020908102919091010152600101610c58565b5050505050505b93509350939050565b6000546001600160a01b03163314610cbf57600080fd5b806001600160a01b038116610d055760405162461bcd60e51b8152600401808060200182810382526025815260200180614b1b6025913960400191505060405180910390fd5b6001600160a01b0381166000908152600b602052604090205460ff1615610d73576040805162461bcd60e51b815260206004820152601d60248201527f6c697374546f6b656e3a20746f6b656e277320616c72206c6973746564000000604482015290519081900360640190fd5b6012610d7e83612c01565b14610dba5760405162461bcd60e51b815260040180806020018281038252602f8152602001806145f5602f913960400191505060405180910390fd5b6009546040805163095ea7b360e01b81526001600160a01b039283166004820152600160ff1b602482015290519184169163095ea7b3916044808201926020929091908290030181600087803b158015610e1357600080fd5b505af1158015610e27573d6000803e3d6000fd5b505050506040513d6020811015610e3d57600080fd5b5051610e7a5760405162461bcd60e51b81526004018080602001828103825260238152602001806149b46023913960400191505060405180910390fd5b6001600160a01b038082166000908152600b6020908152604091829020805460ff191660011790558151928516835290517f017664858438d89f547fee46da0bcfc5396ea13a9fb1490b8fdd76cfa979f1a99281900390910190a15050565b60085481565b6001546001600160a01b031681565b60606004805480602002602001604051908101604052809291908181526020018280548015610f4657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610f28575b5050505050905090565b6000546001600160a01b03163314610f6757600080fd5b6001600160a01b038a166000908152600b60205260409020548a9060ff16610f8e57600080fd5b610f99828b89612cbe565b6001600160a01b0382166000908152600d6020526040902055610fc0898988888888612db3565b6001600160a01b038083166000908152600e6020908152604091829020939093558051918e1682529181018c90528082018b9052606081018790526080810189905260a0810188905260c0810187905260e081018690526101008101859052610120810184905290517f6e788b3b3d979873869a780b8dddf124eb258deaebfa5ebb7ceab29e00e48af8918190036101400190a15050505050505050505050565b6009546001600160a01b031681565b6000546001600160a01b0316331461108757600080fd5b826001600160a01b031663a9059cbb82846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156110e757600080fd5b505af11580156110fb573d6000803e3d6000fd5b505050506040513d602081101561111157600080fd5b505161111c57600080fd5b604080516001600160a01b0380861682526020820185905283168183015290517f72cb8a894ddb372ceec3d2a7648d86f17d5a15caae0e986c53109b8a9a9385e69181900360600190a1505050565b6000546001600160a01b0316331461118257600080fd5b6001600160a01b03811660009081526003602052604090205460ff16156111a857600080fd5b6005546032116111b757600080fd5b604080516001600160a01b03831681526001602082015281517f5611bf3e417d124f97bf2c788843ea8bb502b66079fbee02158ef30b172cb762929181900390910190a16001600160a01b03166000818152600360205260408120805460ff191660019081179091556005805491820181559091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180546001600160a01b0319169091179055565b600a546001600160a01b031681565b6000546001600160a01b0316331461128757600080fd5b6001600160a01b0386166000908152600b602052604090205460ff166112de5760405162461bcd60e51b815260040180806020018281038252602d815260200180614bc8602d913960400191505060405180910390fd5b6001605f1b84106113205760405162461bcd60e51b815260040180806020018281038252602a815260200180614c24602a913960400191505060405180910390fd5b600160601b83106113625760405162461bcd60e51b815260040180806020018281038252602a815260200180614c99602a913960400191505060405180910390fd5b600160201b82106113a45760405162461bcd60e51b8152600401808060200182810382526031815260200180614a106031913960400191505060405180910390fd5b600160201b81106113e65760405162461bcd60e51b815260040180806020018281038252602e815260200180614911602e913960400191505060405180910390fd5b6113f38585858585612f90565b6001600160a01b0387166000908152600c602090815260409182902092909255805186815291820185905281810184905260608201839052517fe11123ebc493eacdec0a640e03f608f0cd23d92798800cf039ee95f685662e479181900360800190a1505050505050565b3360009081526003602052604081205460ff1661147a57600080fd5b6007805460ff60a01b19169055604080516000815290517f7d7f00509dd73ac4449f698ae75ccc797895eff5fa9d446d3df387598a26e7359181900360200190a150600190565b600754600090600160a01b900460ff16611522576040805162461bcd60e51b815260206004820152601c60248201527f74726164653a207472616465456e61626c65642069732066616c736500000000604482015290519081900360640190fd5b6007546001600160a01b0316331461156b5760405162461bcd60e51b815260040180806020018281038252602c8152602001806146fe602c913960400191505060405180910390fd5b6001600160a01b03871660008051602061493f83398151915214806115a657506001600160a01b03851660008051602061493f833981519152145b6115e15760405162461bcd60e51b8152600401808060200182810382526028815260200180614a636028913960400191505060405180910390fd5b60006001600160a01b03881660008051602061493f833981519152146116075787611609565b855b6001600160a01b0381166000908152600b602052604090205490915060ff16611679576040805162461bcd60e51b815260206004820152601a60248201527f74726164653a20746f6b656e206973206e6f74206c6973746564000000000000604482015290519081900360640190fd5b611687888888888888613107565b6116d8576040805162461bcd60e51b815260206004820152601c60248201527f74726164653a20646f54726164652072657475726e732066616c736500000000604482015290519081900360640190fd5b60019150505b9695505050505050565b6000546001600160a01b031633146116ff57600080fd5b6127108110611755576040805162461bcd60e51b815260206004820152601860248201527f7365744665654270733a20666565427073203e3d206270730000000000000000604482015290519081900360640190fd5b60088190556040805182815290517f4f78c4ceb393a616bbd264a4584a9ad15d722042ce1e135e6a8380217f5cb42b9181900360200190a150565b6000546001600160a01b031633146117a757600080fd5b6001600160a01b0381166117ba57600080fd5b600154604080516001600160a01b039092168252517f3b81caf78fa51ecbc8acb482fd7012a277b428d9b80f9d156e8a54107496cc409181900360200190a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b0316331461183257600080fd5b600154600054604080516001600160a01b03938416815292909116602083015280517f65da1cfc2c2e81576ad96afb24a581f8e109b7a403b35cbd3243a1c99efdb9ed9281900390910190a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6000546001600160a01b031633146118bc57600080fd5b6001600160a01b0381166118cf57600080fd5b604080516001600160a01b038316815290517f3b81caf78fa51ecbc8acb482fd7012a277b428d9b80f9d156e8a54107496cc409181900360200190a1600054604080516001600160a01b038085168252909216602083015280517f65da1cfc2c2e81576ad96afb24a581f8e109b7a403b35cbd3243a1c99efdb9ed9281900390910190a1600080546001600160a01b0319166001600160a01b0392909216919091179055565b60606005805480602002602001604051908101604052809291908181526020018280548015610f46576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610f28575050505050905090565b600754600090600160a01b900460ff166119f157506000611bc5565b826119fe57506000611bc5565b60006001600160a01b03861660008051602061493f83398151915214611a245785611a26565b845b6001600160a01b0381166000908152600b602052604090205490915060ff16611a53576000915050611bc5565b611a5b61454e565b611a6361454e565b611a6c836124df565b90925090506001600160a01b03838116908916148015611a965750611a94828260008061397a565b155b15611aa75760009350505050611bc5565b600060606001600160a01b038a1660008051602061493f8339815191521415611aee57600a54611ae4908a906001600160a01b03168a878761253b565b9092509050611b0d565b600a54611b07906001600160a01b03168b8a878761253b565b90925090505b80511580611b19575081155b15611b2c57600095505050505050611bc5565b6000611b3b8984601280613a5d565b90506000806001600160a01b038d1660008051602061493f8339815191521415611b7857611b6e8c868d60018b8b613af4565b9092509050611b8d565b611b878d8c8760008b8b613af4565b90925090505b8115611ba457611b9d8382613c36565b9250611bb0565b611bad83613c92565b92505b611bba8383613cf9565b985050505050505050505b949350505050565b6000546001600160a01b03163314611be457600080fd5b6001600160a01b03811660009081526002602052604090205460ff1615611c0a57600080fd5b600454603211611c1957600080fd5b604080516001600160a01b03831681526001602082015281517f091a7a4b85135fdd7e8dbc18b12fabe5cc191ea867aa3c2e1a24a102af61d58b929181900390910190a16001600160a01b03166000818152600260205260408120805460ff191660019081179091556004805491820181559091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319169091179055565b6001600160a01b0381166000908152600c60205260408120548190819081908190611ced90613d28565b939a9299509097509550909350915050565b6000546001600160a01b03163314611d1657600080fd5b6001600160a01b0381166000908152600b6020526040902054819060ff16611d85576040805162461bcd60e51b815260206004820181905260248201527f64656c697374546f6b656e3a20746f6b656e206973206e6f74206c6973746564604482015290519081900360640190fd5b6009546040805163095ea7b360e01b81526001600160a01b03928316600482015260006024820181905291519285169263095ea7b392604480840193602093929083900390910190829087803b158015611dde57600080fd5b505af1158015611df2573d6000803e3d6000fd5b505050506040513d6020811015611e0857600080fd5b5051611e455760405162461bcd60e51b8152600401808060200182810382526027815260200180614b406027913960400191505060405180910390fd5b6001600160a01b038082166000908152600b60209081526040808320805460ff19169055600c8252808320839055600e8252808320839055600d8252808320929092558151928516835290517f6621c4efc5efa31320394260425b7d14cbb9d7e3754b2c98c04af66b1cbf315b9281900390910190a15050565b6000546001600160a01b03163314611ed657600080fd5b6001600160a01b03811660009081526002602052604090205460ff16611efb57600080fd5b6001600160a01b0381166000908152600260205260408120805460ff191690555b600454811015610b4257816001600160a01b031660048281548110611f3d57fe5b6000918252602090912001546001600160a01b0316141561201657600480546000198101908110611f6a57fe5b600091825260209091200154600480546001600160a01b039092169183908110611f9057fe5b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055600480546000190190611fcc9082614525565b50604080516001600160a01b03841681526000602082015281517f091a7a4b85135fdd7e8dbc18b12fabe5cc191ea867aa3c2e1a24a102af61d58b929181900390910190a1610b42565b600101611f1c565b600080600080600080612055600e6000896001600160a01b03166001600160a01b0316815260200190815260200160002054613d8f565b949c939b5091995097509550909350915050565b6007546001600160a01b031681565b6000546001600160a01b0316331461208f57600080fd5b6040516001600160a01b0382169083156108fc029084906000818181858888f193505050501580156120c5573d6000803e3d6000fd5b50604080518381526001600160a01b038316602082015281517fec47e7ed86c86774d1a72c19f35c639911393fe7c1a34031fdbd260890da90de929181900390910190a15050565b60006001600160a01b03831660008051602061493f833981519152141561213f57506001600160a01b038116316121c4565b826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561219557600080fd5b505afa1580156121a9573d6000803e3d6000fd5b505050506040513d60208110156121bf57600080fd5b505190505b92915050565b600754600160a01b900460ff1681565b6000546001600160a01b031633146121f157600080fd5b6001600160a01b0382166122365760405162461bcd60e51b815260040180806020018281038252602f815260200180614bf5602f913960400191505060405180910390fd5b6001600160a01b03811661227b5760405162461bcd60e51b815260040180806020018281038252602681526020018061495f6026913960400191505060405180910390fd5b600780546001600160a01b0319166001600160a01b038481169190911790915560095481169082161461243f57600a546009546040805163095ea7b360e01b81526001600160a01b0392831660048201526000602482018190529151929093169263095ea7b39260448083019360209383900390910190829087803b15801561230357600080fd5b505af1158015612317573d6000803e3d6000fd5b505050506040513d602081101561232d57600080fd5b505161236a5760405162461bcd60e51b815260040180806020018281038252603f815260200180614b89603f913960400191505060405180910390fd5b600980546001600160a01b0319166001600160a01b03838116918217909255600a546040805163095ea7b360e01b81526004810193909352600160ff1b60248401525192169163095ea7b3916044808201926020929091908290030181600087803b1580156123d857600080fd5b505af11580156123ec573d6000803e3d6000fd5b505050506040513d602081101561240257600080fd5b505161243f5760405162461bcd60e51b815260040180806020018281038252602f81526020018061465f602f913960400191505060405180910390fd5b604080516001600160a01b0380851682528316602082015281517f14662a0fccd762a05d5e1fa6afdd204554c4cf90fe58b5c5947f664fb71925f5929181900390910190a15050565b6001600160a01b0381166000908152600d6020526040812054819081906124ae90613dcd565b9196909550909350915050565b600b6020526000908152604090205460ff1681565b6000546001600160a01b031681565b6124e761454e565b6124ef61454e565b600a546125069084906001600160a01b0316613df1565b602085015283526040830152600a54612528906001600160a01b031684613df1565b6020840152825260408201529092909150565b600a546000906060908590839081908190819081906001600160a01b038d8116911614612568578b61256a565b8c5b600a5490915061258c9082906001600160a01b038f81169116148c8c8f613f05565b60408051838152602080850282010190915292975090955093508480156125cd57816020015b6125ba61454e565b8152602001906001900390816125b25790505b5096508315806125db575084155b156125ec5750612bf7945050505050565b600a546001600160a01b038d8116911614801561260b575060408a0151155b806126305750600a546001600160a01b038e8116911614801561263057506040890151155b156127d157600960009054906101000a90046001600160a01b03166001600160a01b0316630374fc6f8e8e6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b1580156126ba57600080fd5b505afa1580156126ce573d6000803e3d6000fd5b505050506040513d60208110156126e457600080fd5b5051875188906000906126f357fe5b60209081029190910101516040015260095487516001600160a01b0390911690634579268a90899060009061272457fe5b6020026020010151604001516040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b15801561276457600080fd5b505afa158015612778573d6000803e3d6000fd5b505050506040513d608081101561278e57600080fd5b508051604090910151885189906000906127a457fe5b6020026020010151602001896000815181106127bc57fe5b60209081029190910101519190915252612807565b600a546001600160a01b038d81169116146127ec57886127ee565b895b876000815181106127fb57fe5b60200260200101819052505b600061281161454e565b60405180606001604052806000815260200160008152602001600081525090505b8515612ba957805184925088116128dc57806040015189858151811061285457fe5b602002602001015160400181815250508060000151816020015189028161287757fe5b0489858151811061288457fe5b60200260200101516020018181525050878985815181106128a157fe5b602002602001015160000181815250508884815181106128bd57fe5b6020026020010151602001518a01995083600101935060009750612ba9565b878985815181106128e957fe5b602002602001015160000151106129335788848151811061290657fe5b60200260200101516000015189858151811061291e57fe5b60200260200101516020015189028161287757fe5b600184880311801561295c57508489858151811061294d57fe5b60200260200101516000015110155b156129a45788848151811061296d57fe5b6020026020010151602001518a01995088848151811061298957fe5b60200260200101516000015188039750836001019350612a26565b80600001518985815181106129b557fe5b6020026020010151600001511115612a26578884815181106129d357fe5b602090810291909101015151815288518990859081106129ef57fe5b602002602001015160200151816020018181525050888481518110612a1057fe5b6020026020010151604001518160400181815250505b60095489516001600160a01b039091169063943911bc908b9085908110612a4957fe5b6020026020010151604001516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015612a8957600080fd5b505afa158015612a9d573d6000803e3d6000fd5b505050506040513d6020811015612ab357600080fd5b505189518a9086908110612ac357fe5b60209081029190910101516040015260095489516001600160a01b0390911690634579268a908b9087908110612af557fe5b6020026020010151604001516040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b158015612b3557600080fd5b505afa158015612b49573d6000803e3d6000fd5b505050506040513d6080811015612b5f57600080fd5b5080516040909101518a518b9087908110612b7657fe5b60200260200101516020018b8781518110612b8d57fe5b6020908102919091010151919091525260001990950194612832565b8715612bb457600099505b89612bee576040805160008082526020820190925290612bea565b612bd761454e565b815260200190600190039081612bcf5790505b5098505b50505050505050505b9550959350505050565b60006001600160a01b03821660008051602061493f8339815191521415612c2a57506012612cb9565b6001600160a01b03821660009081526006602052604090205480612cb657826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015612c8157600080fd5b505afa158015612c95573d6000803e3d6000fd5b505050506040513d6020811015612cab57600080fd5b50519150612cb99050565b90505b919050565b6000600160201b8210612d025760405162461bcd60e51b8152600401808060200182810382526029815260200180614d376029913960400191505060405180910390fd5b600160201b8310612d445760405162461bcd60e51b815260040180806020018281038252602c8152602001806147cb602c913960400191505060405180910390fd5b600160601b8410612d865760405162461bcd60e51b8152600401808060200182810382526028815260200180614d0f6028913960400191505060405180910390fd5b5063ffffffff908116600160201b9290911691909102176001600160c01b0391909116600160401b021790565b6000600160201b8210612df75760405162461bcd60e51b815260040180806020018281038252602581526020018061468e6025913960400191505060405180910390fd5b600160201b8310612e395760405162461bcd60e51b815260040180806020018281038252602581526020018061474e6025913960400191505060405180910390fd5b600160201b8410612e7b5760405162461bcd60e51b8152600401808060200182810382526022815260200180614a416022913960400191505060405180910390fd5b600160201b8510612ebd5760405162461bcd60e51b8152600401808060200182810382526022815260200180614b676022913960400191505060405180910390fd5b600160201b8610612eff5760405162461bcd60e51b8152600401808060200182810382526026815260200180614cc36026913960400191505060405180910390fd5b600160201b8710612f415760405162461bcd60e51b81526004018080602001828103825260268152602001806147f76026913960400191505060405180910390fd5b50600160a01b63ffffffff96871602600160801b95871695909502938616600160601b02600160401b93871693909302918616600160201b029516949094179390931792909217919091171790565b6000600160201b8210612fd45760405162461bcd60e51b81526004018080602001828103825260348152602001806147976034913960400191505060405180910390fd5b600160201b83106130165760405162461bcd60e51b81526004018080602001828103825260328152602001806148886032913960400191505060405180910390fd5b600160601b84106130585760405162461bcd60e51b81526004018080602001828103825260338152602001806148ba6033913960400191505060405180910390fd5b600160601b851061309a5760405162461bcd60e51b8152600401808060200182810382526033815260200180614ae86033913960400191505060405180910390fd5b5063ffffffff818116600160201b9184168202176bffffffffffffffffffffffff8516600160401b02179080600160601b60016002820403881602020217600160201b80600160601b60028104896130f35760006130f6565b60015b60ff16020202021795945050505050565b6000811561322f5760008311613164576040805162461bcd60e51b815260206004820152601c60248201527f646f54726164653a20636f6e76657273696f6e52617465206973203000000000604482015290519081900360640190fd5b6001600160a01b03871660008051602061493f83398151915214156131dc578534146131d7576040805162461bcd60e51b815260206004820152601f60248201527f646f54726164653a206d73672e76616c756520213d20737263416d6f756e7400604482015290519081900360640190fd5b61322f565b341561322f576040805162461bcd60e51b815260206004820152601c60248201527f646f54726164653a206d73672e76616c7565206d757374206265203000000000604482015290519081900360640190fd5b600061323e876012808761408f565b90506000811161327f5760405162461bcd60e51b815260040180806020018281038252602481526020018061472a6024913960400191505060405180910390fd5b600060018086161480156134d4576001600160a01b038a1660008051602061493f833981519152141561337857876001600160a01b031663a9059cbb88856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561330c57600080fd5b505af1158015613320573d6000803e3d6000fd5b505050506040513d602081101561333657600080fd5b50516133735760405162461bcd60e51b815260040180806020018281038252603b815260200180614624603b913960400191505060405180910390fd5b61346c565b604080516323b872dd60e01b8152336004820152306024820152604481018b905290516001600160a01b038c16916323b872dd9160648083019260209291908290030181600087803b1580156133cd57600080fd5b505af11580156133e1573d6000803e3d6000fd5b505050506040513d60208110156133f757600080fd5b50516134345760405162461bcd60e51b81526004018080602001828103825260398152602001806149d76039913960400191505060405180910390fd5b6040516001600160a01b0388169084156108fc029085906000818181858888f1935050505015801561346a573d6000803e3d6000fd5b505b604080516001600160a01b038c81168252602082018c90528a8116828401526060820186905289166080820152905133917fea9415385bae08fe9f6dc457b02577166790cde83bb18cc340aac6cb81b824de919081900360a00190a2600193505050506116de565b6134dc61454e565b6134e461454e565b6135126001600160a01b038d1660008051602061493f8339815191521461350b578c61350d565b8a5b6124df565b909250905060606001600160a01b038d1660008051602061493f833981519152141561355c57600a54613552908c906001600160a01b03168e868661253b565b909550905061357b565b600a54613575906001600160a01b03168e8e868661253b565b90955090505b858510156135ba5760405162461bcd60e51b815260040180806020018281038252603d81526020018061481d603d913960400191505060405180910390fd5b6001600160a01b038d1660008051602061493f833981519152141561375a57600a60009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561362957600080fd5b505af115801561363d573d6000803e3d6000fd5b505050505061364d8b8d8361411a565b94508585101561368e5760405162461bcd60e51b815260040180806020018281038252604b8152602001806146b3604b913960600191505060405180910390fd5b8a6001600160a01b031663a9059cbb8b886040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156136ee57600080fd5b505af1158015613702573d6000803e3d6000fd5b505050506040513d602081101561371857600080fd5b50516137555760405162461bcd60e51b815260040180806020018281038252602e81526020018061485a602e913960400191505060405180910390fd5b61390b565b604080516323b872dd60e01b8152336004820152306024820152604481018e905290516001600160a01b038f16916323b872dd9160648083019260209291908290030181600087803b1580156137af57600080fd5b505af11580156137c3573d6000803e3d6000fd5b505050506040513d60208110156137d957600080fd5b50516138165760405162461bcd60e51b8152600401808060200182810382526022815260200180614a8b6022913960400191505060405180910390fd5b600a5461382d906001600160a01b03168d8361411a565b94508585101561386e5760405162461bcd60e51b815260040180806020018281038252604b815260200180614c4e604b913960600191505060405180910390fd5b600a5460408051632e1a7d4d60e01b81526004810188905290516001600160a01b0390921691632e1a7d4d9160248082019260009290919082900301818387803b1580156138bb57600080fd5b505af11580156138cf573d6000803e3d6000fd5b50506040516001600160a01b038d16925088156108fc02915088906000818181858888f19350505050158015613909573d6000803e3d6000fd5b505b604080516001600160a01b038f81168252602082018f90528d811682840152606082018990528c166080820152905133917fea9415385bae08fe9f6dc457b02577166790cde83bb18cc340aac6cb81b824de919081900360a00190a25060019c9b505050505050505050505050565b600084604001516000148061399157506040840151155b806139ab57506b204fce5e3e250261100000008560200151115b806139c2575084516b204fce5e3e25026110000000105b806139dc57506b204fce5e3e250261100000008460200151115b806139f3575083516b204fce5e3e25026110000000105b15613a0057506000611bc5565b8451845160208088015190870151919092029102808211613a2657600092505050611bc5565b84613a3657600192505050611bc5565b8381028183036127100211613a5057600092505050611bc5565b5060019695505050505050565b60006b204fce5e3e25026110000000851115613a7857600080fd5b6b204fce5e3e25026110000000841115613a9157600080fd5b828210613aca5760128383031115613aa857600080fd5b84838303600a0a02670de0b6b3a7640000850281613ac257fe5b049050611bc5565b60128284031115613ada57600080fd5b84828403600a0a670de0b6b3a764000086020281613ac257fe5b6000806b204fce5e3e25026110000000871115613b1057613c2b565b613b1861456f565b613b2189614432565b8051909150613b305750613c2b565b6060810151604080516370a0823160e01b815230600482015290519193506000916001600160a01b038c16916370a08231916024808301926020929190829003018186803b158015613b8157600080fd5b505afa158015613b95573d6000803e3d6000fd5b505050506040513d6020811015613bab57600080fd5b505190508615613be05788811015613bc55750613c2b9050565b81602001518982031015613bdb5750613c2b9050565b613c07565b3031881115613bf15750613c2b9050565b81604001518982011115613c075750613c2b9050565b613c1886866001856080015161397a565b613c245750613c2b9050565b6001935050505b965096945050505050565b60006b204fce5e3e25026110000000831115613c835760405162461bcd60e51b8152600401808060200182810382526026815260200180614ce96026913960400191505060405180910390fd5b50612710908101919091020490565b60006b204fce5e3e25026110000000821115613cdf5760405162461bcd60e51b81526004018080602001828103825260248152602001806148ed6024913960400191505060405180910390fd5b61271082600854612710030281613cf257fe5b0492915050565b600081613d07576000613d0a565b60015b60ff166002840614613d1f5760018303613d21565b825b9392505050565b60006b7fffffffffffffffffffffff600160a01b8304166bffffffffffffffffffffffff600160401b84041663ffffffff600160201b850481169085166002600160ff1b870481613d7557fe5b0615613d82576001613d85565b60005b9693955091935091565b600160a01b810463ffffffff90811692600160801b8304821692600160601b8104831692600160401b8204811692600160201b830482169290911690565b6001600160c01b03600160401b8204169163ffffffff600160201b83048116921690565b60095460408051630374fc6f60e01b81526001600160a01b0385811660048301528481166024830152915160009384938493911691630374fc6f91604480820192602092909190829003018186803b158015613e4c57600080fd5b505afa158015613e60573d6000803e3d6000fd5b505050506040513d6020811015613e7657600080fd5b5051600954604080516322bc934560e11b81526004810184905290519295506001600160a01b0390911691634579268a91602480820192608092909190829003018186803b158015613ec757600080fd5b505afa158015613edb573d6000803e3d6000fd5b505050506040513d6080811015613ef157600080fd5b508051604090910151939693955093505050565b600080600086158015613f26575060408501511580613f2657506040860151155b15613f3957506000915081905080614084565b60008088613f6b57865160208901518951919350600291840281613f5957fe5b0488602001510181613f6757fe5b0490505b600089613f83578282880281613f7d57fe5b04613f85565b865b9050613f8f61454e565b613f988c61448b565b90508181600001511115613fba57506000955085945084935061408492505050565b613fc26145a0565b613fcb8d6144c6565b60208101518151919250620186a091829190670de0b6b3a7640000908702040181613ff257fe5b049750614003888460200151614510565b9750808260600151670de0b6b3a7640000868560400151028161402257fe5b04018161402b57fe5b04985061403c898460400151614510565b9850600081670de0b6b3a76400008460a001510286856080015102018161405f57fe5b0490508d61407857858782028161407257fe5b0461407a565b805b9750505050505050505b955095509592505050565b60006b204fce5e3e250261100000008511156140aa57600080fd5b69d3c21bcecceda10000008211156140c157600080fd5b8383106140f057601284840311156140d857600080fd5b670de0b6b3a7640000858302858503600a0a02613ac2565b6012838503111561410057600080fd5b828403600a0a670de0b6b3a76400000282860281613ac257fe5b60006001600160a01b03841660008051602061493f83398151915214156141725760405162461bcd60e51b81526004018080602001828103825260248152602001806147736024913960400191505060405180910390fd5b604080516370a0823160e01b815230600482015290516000916001600160a01b038716916370a0823191602480820192602092909190829003018186803b1580156141bc57600080fd5b505afa1580156141d0573d6000803e3d6000fd5b505050506040513d60208110156141e657600080fd5b505190508360005b84518110156143315784818151811061420357fe5b6020026020010151604001516000148061421b575081155b1561422557614331565b60006142488387848151811061423757fe5b602002602001015160000151614510565b9050600086838151811061425857fe5b60200260200101516000015187848151811061427057fe5b60200260200101516020015183028161428557fe5b60095489519290910492506001600160a01b0316906349606455908990869081106142ac57fe5b60200260200101516040015160001b836040518363ffffffff1660e01b815260040180838152602001826001600160801b03166001600160801b0316815260200192505050600060405180830381600087803b15801561430b57600080fd5b505af115801561431f573d6000803e3d6000fd5b505050919093039250506001016141ee565b50801561436f5760405162461bcd60e51b815260040180806020018281038252602f815260200180614985602f913960400191505060405180910390fd5b604080516370a0823160e01b815230600482015290516000916001600160a01b038916916370a0823191602480820192602092909190829003018186803b1580156143b957600080fd5b505afa1580156143cd573d6000803e3d6000fd5b505050506040513d60208110156143e357600080fd5b505190508281116144255760405162461bcd60e51b815260040180806020018281038252603b815260200180614aad603b913960400191505060405180910390fd5b9190910395945050505050565b61443a61456f565b6001600160a01b0382166000908152600c6020526040812054819081908190819061446490613d28565b9315158a5260208a0192909252604089015260608801526080870152509395945050505050565b61449361454e565b6001600160a01b0382166000908152600d60205260409020546144b590613dcd565b604084015260208301528152919050565b6144ce6145a0565b6001600160a01b0382166000908152600e60205260409020546144f090613d8f565b60a087015260808601526060850152604084015260208301528152919050565b600081831161451f5782613d21565b50919050565b815481835581811115614549576000838152602090206145499181019083016145d6565b505050565b60405180606001604052806000815260200160008152602001600081525090565b6040518060a00160405280600015158152602001600081526020016000815260200160008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6109e091905b808211156145f057600081556001016145dc565b509056fe6c697374546f6b656e3a20746f6b656e277320646563696d616c73206973206e6f74204d41585f444543494d414c53646f54726164653a2028757365496e7465726e616c496e76656e746f7279292063616e206e6f74207472616e73666572206261636b20746f6b656e736574436f6e7472616374733a206661696c656420746f20617070726f7665206f7463202877657468546f6b656e29656e636f6465466163746f72446174613a206d696e53697a655920697320746f6f20626967646f54726164653a2061637475616c44657374416d6f756e74206973206c657373207468616e2075736572457870656374656444657374416d6f756e742c2065746820746f20746f6b656e74726164653a206e6f742063616c6c2066726f6d206b796265724e6574776f726b277320636f6e7472616374646f54726164653a2075736572457870656374656444657374416d6f756e74203d3d2030656e636f6465466163746f72446174613a206d696e53697a655820697320746f6f2062696774616b654d61746368696e674f72646572733a2064657374546f6b656e20697320455448656e636f6465496e7465726e616c496e76656e746f7279446174613a206d696e53707265616442707320697320746f6f20626967656e636f6465546f6b656e4261736963446174613a206d6178547261766572736520697320746f6f20626967656e636f6465466163746f72446174613a2074726176657273655820697320746f6f20626967646f54726164653a2061637475616c44657374416d6f756e74206973206c657373207468616e2075736572457870656374656444657374416d6f756e74646f54726164653a2063616e206e6f74207472616e73666572206261636b2072657175657374656420746f6b656e656e636f6465496e7465726e616c496e76656e746f7279446174613a207072656d69756d42707320697320746f6f20626967656e636f6465496e7465726e616c496e76656e746f7279446174613a206d6178546f6b656e42616c20697320746f6f2062696776616c756541667465725265647563696e674665653a2076616c203e204d41585f515459736574496e7465726e616c496e76656e746f7279446174613a206d696e537072656164427073203e20322a2a3332000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee736574436f6e7472616374733a206f746327732061646472657373206973206d697373696e6774616b654d61746368696e674f72646572733a20646964206e6f742074616b6520616c6c2073726320616d6f756e746c697374546f6b656e3a20617070726f766520746f6b656e206f7463206661696c6564646f54726164653a2028757365496e7465726e616c496e76656e746f7279292063616e206e6f7420636f6c6c6563742073726320746f6b656e736574496e7465726e616c496e76656e746f7279446174613a2070726963655072656d69756d427073203e20322a2a3332656e636f6465466163746f72446174613a2074616b655920697320746f6f2062696774726164653a20737263546f6b656e206f722064657374546f6b656e206d75737420626520455448646f54726164653a2063616e206e6f7420636f6c6c6563742073726320746f6b656e74616b654d61746368696e674f72646572733a206e65775265736572766542616c616e6365203c3d206c6173745265736572766542616c616e6365656e636f6465496e7465726e616c496e76656e746f7279446174613a206d696e546f6b656e42616c20697320746f6f206269676c697374546f6b656e3a20746f6b656e27732061646472657373206973206d697373696e6764656c697374546f6b656e3a20726573657420617070726f766520746f6b656e206661696c6564656e636f6465466163746f72446174613a2074616b655820697320746f6f20626967736574436f6e7472616374733a206661696c656420746f20726573657420616c6c6f77616e636520666f72206f6c64206f7463202877657468546f6b656e29736574496e7465726e616c496e76656e746f7279446174613a20746f6b656e206973206e6f74206c6973746564736574436f6e7472616374733a206b796265724e6574776f726b27732061646472657373206973206d697373696e67736574496e7465726e616c496e76656e746f7279446174613a206d696e546f6b656e203e20322a2a3935646f54726164653a2061637475616c44657374416d6f756e74206973206c657373207468616e2075736572457870656374656444657374416d6f756e742c20746f6b656e20746f20657468736574496e7465726e616c496e76656e746f7279446174613a206d6178546f6b656e203e20322a2a3936656e636f6465466163746f72446174613a2074726176657273655920697320746f6f2062696776616c75654166746572416464696e675072656d69756d3a2076616c203e204d41585f515459656e636f6465546f6b656e4261736963446174613a2065746853697a6520697320746f6f20626967656e636f6465546f6b656e4261736963446174613a206d617854616b657320697320746f6f20626967a265627a7a72315820f7176853b66f2143cb40c5e1f89ef13c30e774c34072fdf646619a54003488a264736f6c634300050b0032

Deployed Bytecode Sourcemap

260:32944:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8148:145;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8148:145:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;2466:456:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2466:456:4;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;2466:456:4;-1:-1:-1;;;;;2466:456:4;;:::i;11561:1120:0:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11561:1120:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;11561:1120:0;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;11561:1120:0;;;;;;;;;;;;;;;;;;;10270:535;;8:9:-1;5:2;;;30:1;27;20:12;5:2;10270:535:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10270:535:0;-1:-1:-1;;;;;10270:535:0;;:::i;616:18::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;616:18:0;;;:::i;:::-;;;;;;;;;;;;;;;;85:27:4;;8:9:-1;5:2;;;30:1;27;20:12;5:2;85:27:4;;;:::i;:::-;;;;-1:-1:-1;;;;;85:27:4;;;;;;;;;;;;;;716:103;;8:9:-1;5:2;;;30:1;27;20:12;5:2;716:103:4;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;716:103:4;;;;;;;;;;;;;;;;;7205:899:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7205:899:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;7205:899:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;641:15::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;641:15:0;;;:::i;424:192:6:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;424:192:6;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;424:192:6;;;;;;;;;;;;;;;;;:::i;2154:306:4:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2154:306:4;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;2154:306:4;-1:-1:-1;;;;;2154:306:4;;:::i;662:22:0:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;662:22:0;;;:::i;9313:913::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9313:913:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;9313:913:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;8299:150::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8299:150:0;;;:::i;6114:838::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;6114:838:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;11379:176::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11379:176:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;11379:176:0;;:::i;1134:188:4:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1134:188:4;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1134:188:4;-1:-1:-1;;;;;1134:188:4;;:::i;1896:194::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1896:194:4;;;:::i;1497:228::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1497:228:4;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1497:228:4;-1:-1:-1;;;;;1497:228:4;;:::i;825:101::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;825:101:4;;;:::i;3306:2605:0:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3306:2605:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;3306:2605:0;;;;;;;;;;;;;;;;;;;;;;:::i;2987:317:4:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2987:317:4;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;2987:317:4;-1:-1:-1;;;;;2987:317:4;;:::i;13283:328:0:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13283:328:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;13283:328:0;-1:-1:-1;;;;;13283:328:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10851:487;;8:9:-1;5:2;;;30:1;27;20:12;5:2;10851:487:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10851:487:0;-1:-1:-1;;;;;10851:487:0;;:::i;3310:474:4:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3310:474:4;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;3310:474:4;-1:-1:-1;;;;;3310:474:4;;:::i;12941:336:0:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12941:336:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12941:336:0;-1:-1:-1;;;;;12941:336:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;553:27;;8:9:-1;5:2;;;30:1;27;20:12;5:2;553:27:0;;;:::i;721:163:6:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;721:163:6;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;721:163:6;;;;;;-1:-1:-1;;;;;721:163:6;;:::i;665:209:5:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;665:209:5;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;665:209:5;;;;;;;;;;:::i;586:24:0:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;586:24:0;;;:::i;8515:684::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8515:684:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;8515:684:0;;;;;;;;;;:::i;12687:248::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12687:248:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12687:248:0;-1:-1:-1;;;;;12687:248:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;746:45;;8:9:-1;5:2;;;30:1;27;20:12;5:2;746:45:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;746:45:0;-1:-1:-1;;;;;746:45:0;;:::i;59:20:4:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59:20:4;;;:::i;8148:145:0:-;8196:4;512:5:4;;-1:-1:-1;;;;;512:5:4;498:10;:19;490:28;;;;;;8212:12:0;:19;;-1:-1:-1;;;;8212:19:0;-1:-1:-1;;;8212:19:0;;;8246:18;;;8227:4;8246:18;;;;;;;;;;;;;-1:-1:-1;8282:4:0;528:1:4;8148:145:0;:::o;2466:456:4:-;512:5;;-1:-1:-1;;;;;512:5:4;498:10;:19;490:28;;;;;;-1:-1:-1;;;;;2542:17:4;;;;;;:8;:17;;;;;;;;2534:26;;;;;;-1:-1:-1;;;;;2570:17:4;;2590:5;2570:17;;;:8;:17;;;;;:25;;-1:-1:-1;;2570:25:4;;;2606:310;2627:13;:20;2623:24;;2606:310;;;2692:7;-1:-1:-1;;;;;2672:27:4;:13;2686:1;2672:16;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2672:16:4;:27;2668:238;;;2738:13;2752:20;;-1:-1:-1;;2752:24:4;;;2738:39;;;;;;;;;;;;;;;;2719:13;:16;;-1:-1:-1;;;;;2738:39:4;;;;2733:1;;2719:16;;;;;;;;;;;;;;;:58;;-1:-1:-1;;;;;;2719:58:4;-1:-1:-1;;;;;2719:58:4;;;;;;;;;;2795:13;:22;;;;;-1:-1:-1;;2795:22:4;;;:::i;:::-;-1:-1:-1;2840:28:4;;;-1:-1:-1;;;;;2840:28:4;;;;2862:5;2840:28;;;;;;;;;;;;;;;;;2886:5;;2668:238;2649:3;;2606:310;;;;2466:456;:::o;11561:1120:0:-;11675:15;;11714:22;11757:19;11753:219;;-1:-1:-1;;11888:13:0;;;11829:1;11888:13;;;;;;;;;11829:1;;-1:-1:-1;11829:1:0;;11915:46;;11753:219;11982:25;12017:15;12035:12;:32;;12058:9;;-1:-1:-1;;;;;12058:9:0;12035:32;;;12050:5;12035:32;12017:50;;12077:15;12095:12;:32;;12122:5;12095:32;;;12110:9;;-1:-1:-1;;;;;12110:9:0;12095:32;12077:50;;12138:20;;:::i;:::-;12168;;:::i;:::-;12211:30;12235:5;12211:23;:30::i;:::-;12198:43;;-1:-1:-1;12198:43:0;-1:-1:-1;12275:73:0;12290:8;12300;12328;12311:25;;12198:43;;12275:14;:73::i;:::-;12252:96;;-1:-1:-1;12252:96:0;-1:-1:-1;12390:8:0;12252:96;12377:21;12359:39;;12409:6;12425:117;12437:6;:13;12433:1;:17;12425:117;;;12475:6;12482:1;12475:9;;;;;;;;;;;;;;:12;;;12491:1;12475:17;12471:61;;;12512:5;;12471:61;12452:3;;12425:117;;;12574:1;12563:13;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;12563:13:0;;12552:24;;12595:1;12591:5;;12586:89;12602:8;:15;12598:1;:19;12586:89;;;12652:6;12659:1;12652:9;;;;;;;;;;;;;;:12;;;12638:8;12647:1;12638:11;;;;;;;;;;;;;;;;;:26;12619:3;;12586:89;;;11561:1120;;;;;;;;;;;;;;:::o;10270:535::-;512:5:4;;-1:-1:-1;;;;;512:5:4;498:10;:19;490:28;;;;;;10358:5:0;-1:-1:-1;;;;;10383:23:0;;10375:73;;;;-1:-1:-1;;;10375:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;10467:24:0;;;;;;:13;:24;;;;;;;;10466:25;10458:67;;;;;-1:-1:-1;;;10458:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;458:2:5;10543:18:0;10555:5;10543:11;:18::i;:::-;:34;10535:94;;;;-1:-1:-1;;;10535:94:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10669:3;;10647:35;;;-1:-1:-1;;;10647:35:0;;-1:-1:-1;;;;;10669:3:0;;;10647:35;;;;-1:-1:-1;;;10647:35:0;;;;;;:13;;;;;;:35;;;;;;;;;;;;;;;10669:3;10647:13;:35;;;5:2:-1;;;;30:1;27;20:12;5:2;10647:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;10647:35:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10647:35:0;10639:83;;;;-1:-1:-1;;;10639:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;10733:24:0;;;;;;;:13;:24;;;;;;;;;:31;;-1:-1:-1;;10733:31:0;10760:4;10733:31;;;10780:18;;;;;;;;;;;;;;;;;;;528:1:4;10270:535:0;:::o;616:18::-;;;;:::o;85:27:4:-;;;-1:-1:-1;;;;;85:27:4;;:::o;716:103::-;763:16;798:14;791:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;791:21:4;;;;;;;;;;;;;;;;;;;;;;;716:103;:::o;7205:899:0:-;512:5:4;;-1:-1:-1;;;;;512:5:4;498:10;:19;490:28;;;;;;-1:-1:-1;;;;;7540:24:0;;7488:17;7540:24;;;:13;:24;;;;;;7516:5;;7540:24;;7532:33;;;;;;7603:57;7624:13;7639:11;7652:7;7603:20;:57::i;:::-;-1:-1:-1;;;;;7575:25:0;;;;;;:14;:25;;;;;:85;7699:188;7729:14;7757;7785:11;7810;7835:14;7863;7699:16;:188::i;:::-;-1:-1:-1;;;;;7670:26:0;;;;;;;:15;:26;;;;;;;;;:217;;;;7902:195;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;528:1:4;7205:899:0;;;;;;;;;;:::o;641:15::-;;;-1:-1:-1;;;;;641:15:0;;:::o;424:192:6:-;512:5:4;;-1:-1:-1;;;;;512:5:4;498:10;:19;490:28;;;;;;527:5:6;-1:-1:-1;;;;;527:14:6;;542:6;550;527:30;;;;;;;;;;;;;-1:-1:-1;;;;;527:30:6;-1:-1:-1;;;;;527:30:6;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;527:30:6;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;527:30:6;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;527:30:6;519:39;;;;;;573:36;;;-1:-1:-1;;;;;573:36:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;424:192;;;:::o;2154:306:4:-;512:5;;-1:-1:-1;;;;;512:5:4;498:10;:19;490:28;;;;;;-1:-1:-1;;;;;2230:20:4;;;;;;:8;:20;;;;;;;;2229:21;2221:30;;;;;;2292:13;:20;328:2;-1:-1:-1;2284:46:4;;;;;;2346:30;;;-1:-1:-1;;;;;2346:30:4;;;;2371:4;2346:30;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2386:20:4;;;;;:8;:20;;;;;:27;;-1:-1:-1;;2386:27:4;2409:4;2386:27;;;;;;2423:13;27:10:-1;;23:18;;;45:23;;2423:30:4;;;;;;;-1:-1:-1;;;;;;2423:30:4;;;;;;2154:306::o;662:22:0:-;;;-1:-1:-1;;;;;662:22:0;;:::o;9313:913::-;512:5:4;;-1:-1:-1;;;;;512:5:4;498:10;:19;490:28;;;;;;-1:-1:-1;;;;;9549:29:0;;;;;;:13;:29;;;;;;;;9541:87;;;;-1:-1:-1;;;9541:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;9646:21:0;;9638:76;;;;-1:-1:-1;;;9638:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;9732:8:0;:19;9724:74;;;;-1:-1:-1;;;9724:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;9816:15:0;:26;9808:88;;;;-1:-1:-1;;;9808:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;9914:12:0;:23;9906:82;;;;-1:-1:-1;;;9906:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10039:89;10067:9;10078:8;10088;10098:15;10115:12;10039:27;:89::i;:::-;-1:-1:-1;;;;;9999:37:0;;;;;;:21;:37;;;;;;;;;:129;;;;10144:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9313:913;;;;;;:::o;8299:150::-;680:10:4;8350:4:0;671:20:4;;;:8;:20;;;;;;;;663:29;;;;;;8366:12:0;:20;;-1:-1:-1;;;;8366:20:0;;;8401:19;;;8381:5;8401:19;;;;;;;;;;;;;-1:-1:-1;8438:4:0;8299:150;:::o;6114:838::-;6374:12;;6346:4;;-1:-1:-1;;;6374:12:0;;;;6366:53;;;;;-1:-1:-1;;;6366:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;6451:12;;-1:-1:-1;;;;;6451:12:0;6437:10;:26;6429:83;;;;-1:-1:-1;;;6429:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;6530:29:0;;-1:-1:-1;;;;;;;;;;;6530:29:0;;:63;;-1:-1:-1;;;;;;6563:30:0;;-1:-1:-1;;;;;;;;;;;6563:30:0;6530:63;6522:116;;;;-1:-1:-1;;;6522:116:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6649:12;-1:-1:-1;;;;;6664:29:0;;-1:-1:-1;;;;;;;;;;;6664:29:0;:52;;6708:8;6664:52;;;6696:9;6664:52;-1:-1:-1;;;;;6734:29:0;;;;;;:13;:29;;;;;;6649:67;;-1:-1:-1;6734:29:0;;6726:68;;;;;-1:-1:-1;;;6726:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;6813:78;6821:8;6831:9;6842;6853:11;6866:14;6882:8;6813:7;:78::i;:::-;6805:119;;;;;-1:-1:-1;;;6805:119:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;6941:4;6934:11;;;6114:838;;;;;;;;;:::o;11379:176::-;512:5:4;;-1:-1:-1;;;;;512:5:4;498:10;:19;490:28;;;;;;519:5:0;11447:7;:13;11439:50;;;;;-1:-1:-1;;;11439:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;11500:6;:16;;;11531:17;;;;;;;;;;;;;;;;;11379:176;:::o;1134:188:4:-;512:5;;-1:-1:-1;;;;;512:5:4;498:10;:19;490:28;;;;;;-1:-1:-1;;;;;1210:22:4;;1202:31;;;;;;1269:12;;1248:34;;;-1:-1:-1;;;;;1269:12:4;;;1248:34;;;;;;;;;;;;1292:12;:23;;-1:-1:-1;;;;;;1292:23:4;-1:-1:-1;;;;;1292:23:4;;;;;;;;;;1134:188::o;1896:194::-;1943:12;;-1:-1:-1;;;;;1943:12:4;1959:10;1943:26;1935:35;;;;;;1998:12;;;2012:5;1985:33;;;-1:-1:-1;;;;;1998:12:4;;;1985:33;;2012:5;;;;1985:33;;;;;;;;;;;;;;;;2036:12;;;;2028:20;;-1:-1:-1;;;;;;2028:20:4;;;-1:-1:-1;;;;;2036:12:4;;2028:20;;;;2058:25;;;1896:194::o;1497:228::-;512:5;;-1:-1:-1;;;;;512:5:4;498:10;:19;490:28;;;;;;-1:-1:-1;;;;;1580:22:4;;1572:31;;;;;;1618:30;;;-1:-1:-1;;;;;1618:30:4;;;;;;;;;;;;;;;1686:5;;1663:29;;;-1:-1:-1;;;;;1663:29:4;;;;;1686:5;;;1663:29;;;;;;;;;;;;;;;;1702:5;:16;;-1:-1:-1;;;;;;1702:16:4;-1:-1:-1;;;;;1702:16:4;;;;;;;;;;1497:228::o;825:101::-;871:16;906:13;899:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;899:20:4;;;;;;;;;;;;;;;;;;;;;;825:101;:::o;3306:2605:0:-;3418:12;;3397:4;;-1:-1:-1;;;3418:12:0;;;;3413:32;;-1:-1:-1;3441:1:0;3434:8;;3413:32;3458:11;3454:30;;-1:-1:-1;3480:1:0;3473:8;;3454:30;3528:12;-1:-1:-1;;;;;3543:24:0;;-1:-1:-1;;;;;;;;;;;3543:24:0;:37;;3577:3;3543:37;;;3570:4;3543:37;-1:-1:-1;;;;;3595:29:0;;;;;;:13;:29;;;;;;3528:52;;-1:-1:-1;3595:29:0;;3590:49;;3635:1;3628:8;;;;;3590:49;3649:20;;:::i;:::-;3679;;:::i;:::-;3722:30;3746:5;3722:23;:30::i;:::-;3709:43;;-1:-1:-1;3709:43:0;-1:-1:-1;;;;;;3826:12:0;;;;;;;:53;;;;;3843:36;3860:3;3865;3870:5;3877:1;3843:16;:36::i;:::-;3842:37;3826:53;3822:72;;;3890:1;3883:8;;;;;;;3822:72;3904:12;3926:25;-1:-1:-1;;;;;3966:24:0;;-1:-1:-1;;;;;;;;;;;3966:24:0;3962:223;;;4047:9;;4026:49;;4041:4;;-1:-1:-1;;;;;4047:9:0;4058:6;4066:3;4071;4026:14;:49::i;:::-;4006:69;;-1:-1:-1;4006:69:0;-1:-1:-1;3962:223:0;;;4141:9;;4126:48;;-1:-1:-1;;;;;4141:9:0;4152:3;4157:6;4165:3;4170;4126:14;:48::i;:::-;4106:68;;-1:-1:-1;4106:68:0;-1:-1:-1;3962:223:0;4199:13;;:18;;:34;;-1:-1:-1;4221:12:0;;4199:34;4195:53;;;4244:1;4237:8;;;;;;;;;4195:53;4305:9;4317:60;4333:6;4341:7;458:2:5;;4317:15:0;:60::i;:::-;4305:72;-1:-1:-1;4388:25:0;;-1:-1:-1;;;;;4453:24:0;;-1:-1:-1;;;;;;;;;;;4453:24:0;4449:1204;;;4530:522;4557:4;4639:7;4724:6;4808:4;4890:3;4971;4530:26;:522::i;:::-;4493:559;;-1:-1:-1;4493:559:0;-1:-1:-1;4449:1204:0;;;5120:522;5147:3;5228:6;5312:7;5397:5;5480:3;5561;5120:26;:522::i;:::-;5083:559;;-1:-1:-1;5083:559:0;-1:-1:-1;4449:1204:0;5667:20;5663:164;;;5710:41;5734:4;5740:10;5710:23;:41::i;:::-;5703:48;;5663:164;;;5789:27;5811:4;5789:21;:27::i;:::-;5782:34;;5663:164;5844:60;5877:4;5883:20;5844:32;:60::i;:::-;5837:67;;;;;;;;;;3306:2605;;;;;;;:::o;2987:317:4:-;512:5;;-1:-1:-1;;;;;512:5:4;498:10;:19;490:28;;;;;;-1:-1:-1;;;;;3065:22:4;;;;;;:9;:22;;;;;;;;3064:23;3056:32;;;;;;3129:14;:21;328:2;-1:-1:-1;3121:47:4;;;;;;3184:32;;;-1:-1:-1;;;;;3184:32:4;;;;3211:4;3184:32;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3226:22:4;;;;;:9;:22;;;;;:29;;-1:-1:-1;;3226:29:4;3251:4;3226:29;;;;;;3265:14;27:10:-1;;23:18;;;45:23;;3265:32:4;;;;;;;-1:-1:-1;;;;;;3265:32:4;;;;;;2987:317::o;13283:328:0:-;-1:-1:-1;;;;;13566:37:0;;13370:14;13566:37;;;:21;:37;;;;;;13370:14;;;;;;;;13538:66;;:27;:66::i;:::-;13472:132;;;;-1:-1:-1;13472:132:0;;-1:-1:-1;13472:132:0;-1:-1:-1;13472:132:0;;-1:-1:-1;13283:328:0;-1:-1:-1;;13283:328:0:o;10851:487::-;512:5:4;;-1:-1:-1;;;;;512:5:4;498:10;:19;490:28;;;;;;-1:-1:-1;;;;;10966:24:0;;10913:17;10966:24;;;:13;:24;;;;;;10941:5;;10966:24;;10958:69;;;;;-1:-1:-1;;;10958:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11067:3;;11045:30;;;-1:-1:-1;;;11045:30:0;;-1:-1:-1;;;;;11067:3:0;;;11045:30;;;;11067:3;11045:30;;;;;;;;:13;;;;;;:30;;;;;;;;;;;;;;;;;;:13;:30;;;5:2:-1;;;;30:1;27;20:12;5:2;11045:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;11045:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;11045:30:0;11037:82;;;;-1:-1:-1;;;11037:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;11137:24:0;;;;;;;:13;:24;;;;;;;;11130:31;;-1:-1:-1;;11130:31:0;;;11178:21;:32;;;;;11171:39;;;11227:15;:26;;;;;11220:33;;;11270:14;:25;;;;;11263:32;;;;11311:20;;;;;;;;;;;;;;;;;;;528:1:4;10851:487:0;:::o;3310:474:4:-;512:5;;-1:-1:-1;;;;;512:5:4;498:10;:19;490:28;;;;;;-1:-1:-1;;;;;3388:19:4;;;;;;:9;:19;;;;;;;;3380:28;;;;;;-1:-1:-1;;;;;3418:19:4;;3440:5;3418:19;;;:9;:19;;;;;:27;;-1:-1:-1;;3418:27:4;;;3456:322;3477:14;:21;3473:25;;3456:322;;;3544:8;-1:-1:-1;;;;;3523:29:4;:14;3538:1;3523:17;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3523:17:4;:29;3519:249;;;3592:14;3607:21;;-1:-1:-1;;3607:25:4;;;3592:41;;;;;;;;;;;;;;;;3572:14;:17;;-1:-1:-1;;;;;3592:41:4;;;;3587:1;;3572:17;;;;;;;;;;;;;;;:61;;-1:-1:-1;;;;;;3572:61:4;-1:-1:-1;;;;;3572:61:4;;;;;;;;;;3651:14;:26;;-1:-1:-1;;3651:26:4;;;;;;:::i;:::-;-1:-1:-1;3700:30:4;;;-1:-1:-1;;;;;3700:30:4;;;;3724:5;3700:30;;;;;;;;;;;;;;;;;3748:5;;3519:249;3500:3;;3456:322;;12941:336:0;13018:17;13037;13056:13;13071;13086:18;13106;13221:49;13238:15;:31;13262:5;-1:-1:-1;;;;;13238:31:0;-1:-1:-1;;;;;13238:31:0;;;;;;;;;;;;;13221:16;:49::i;:::-;13140:130;;;;-1:-1:-1;13140:130:0;;-1:-1:-1;13140:130:0;-1:-1:-1;13140:130:0;-1:-1:-1;13140:130:0;;-1:-1:-1;12941:336:0;-1:-1:-1;;12941:336:0:o;553:27::-;;;-1:-1:-1;;;;;553:27:0;;:::o;721:163:6:-;512:5:4;;-1:-1:-1;;;;;512:5:4;498:10;:19;490:28;;;;;;810:23:6;;-1:-1:-1;;;;;810:15:6;;;:23;;;;;826:6;;810:23;;;;826:6;810:15;:23;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;848:29:6;;;;;;-1:-1:-1;;;;;848:29:6;;;;;;;;;;;;;;;;;;;721:163;;:::o;665:209:5:-;733:4;-1:-1:-1;;;;;753:26:5;;-1:-1:-1;;;;;;;;;;;753:26:5;749:118;;;-1:-1:-1;;;;;;800:12:5;;;793:19;;749:118;846:5;-1:-1:-1;;;;;846:15:5;;862:4;846:21;;;;;;;;;;;;;-1:-1:-1;;;;;846:21:5;-1:-1:-1;;;;;846:21:5;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;846:21:5;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;846:21:5;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;846:21:5;;-1:-1:-1;749:118:5;665:209;;;;:::o;586:24:0:-;;;-1:-1:-1;;;586:24:0;;;;;:::o;8515:684::-;512:5:4;;-1:-1:-1;;;;;512:5:4;498:10;:19;490:28;;;;;;-1:-1:-1;;;;;8609:27:0;;8601:87;;;;-1:-1:-1;;;8601:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;8706:18:0;;8698:69;;;;-1:-1:-1;;;8698:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8778:12;:28;;-1:-1:-1;;;;;;8778:28:0;-1:-1:-1;;;;;8778:28:0;;;;;;;;;;8837:3;;;;8821:20;;;;8817:327;;8896:9;;8922:3;;8896:34;;;-1:-1:-1;;;8896:34:0;;-1:-1:-1;;;;;8922:3:0;;;8896:34;;;;:9;:34;;;;;;;;:9;;;;;:17;;:34;;;;;;;;;;;;;;;;:9;:34;;;5:2:-1;;;;30:1;27;20:12;5:2;8896:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;8896:34:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;8896:34:0;8888:110;;;;-1:-1:-1;;;8888:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9012:3;:16;;-1:-1:-1;;;;;;9012:16:0;-1:-1:-1;;;;;9012:16:0;;;;;;;;;9050:9;;:31;;;-1:-1:-1;;;9050:31:0;;;;;;;;;-1:-1:-1;;;9050:31:0;;;;;:9;;;:17;;:31;;;;;;;;;;;;;;;-1:-1:-1;9050:9:0;:31;;;5:2:-1;;;;30:1;27;20:12;5:2;9050:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;9050:31:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;9050:31:0;9042:91;;;;-1:-1:-1;;;9042:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9159:33;;;-1:-1:-1;;;;;9159:33:0;;;;;;;;;;;;;;;;;;;;;;;;8515:684;;:::o;12687:248::-;-1:-1:-1;;;;;12897:30:0;;12768:18;12897:30;;;:14;:30;;;;;;12768:18;;;;12876:52;;:20;:52::i;:::-;12835:93;;;;-1:-1:-1;12835:93:0;;-1:-1:-1;12687:248:0;-1:-1:-1;;12687:248:0:o;746:45::-;;;;;;;;;;;;;;;:::o;59:20:4:-;;;-1:-1:-1;;;;;59:20:4;;:::o;26675:397:0:-;26760:20;;:::i;:::-;26782;;:::i;:::-;26926:9;;26905:31;;26919:5;;-1:-1:-1;;;;;26926:9:0;26905:13;:31::i;:::-;26888:13;;;26864:72;;;26865:6;;;26864:72;27048:9;;27034:31;;-1:-1:-1;;;;;27048:9:0;27059:5;27034:13;:31::i;:::-;27017:13;;;26993:72;;;26994:6;;;26993:72;26675:397;;26994:3;;-1:-1:-1;26675:397:0:o;20679:3864::-;21167:9;;20881:20;;20903:25;;20970:9;;20881:20;;;;;;;;;;-1:-1:-1;;;;;21155:21:0;;;21167:9;;21155:21;:43;;21190:8;21155:43;;;21179:8;21155:43;21338:9;;21140:58;;-1:-1:-1;21263:152:0;;21140:58;;-1:-1:-1;;;;;21326:21:0;;;21338:9;;21326:21;21362:3;21379;21396:9;21263:29;:152::i;:::-;21435:35;;;;;;;;;;;;;;;;21209:206;;-1:-1:-1;21209:206:0;;-1:-1:-1;21209:206:0;-1:-1:-1;21209:206:0;21435:35;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;21426:44:0;-1:-1:-1;21545:23:0;;;:47;;-1:-1:-1;21572:20:0;;21545:47;21541:110;;;-1:-1:-1;21608:32:0;;-1:-1:-1;;;;;21608:32:0;21541:110;21827:9;;-1:-1:-1;;;;;21815:21:0;;;21827:9;;21815:21;:36;;;;-1:-1:-1;21840:6:0;;;;:11;21815:36;21814:80;;;-1:-1:-1;21869:9:0;;-1:-1:-1;;;;;21857:21:0;;;21869:9;;21857:21;:36;;;;-1:-1:-1;21882:6:0;;;;:11;21857:36;21810:415;;;21925:3;;;;;;;;;-1:-1:-1;;;;;21925:3:0;-1:-1:-1;;;;;21925:16:0;;21942:8;21952;21925:36;;;;;;;;;;;;;-1:-1:-1;;;;;21925:36:0;-1:-1:-1;;;;;21925:36:0;;;;;;-1:-1:-1;;;;;21925:36:0;-1:-1:-1;;;;;21925:36:0;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21925:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;21925:36:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21925:36:0;21910:9;;:6;;21917:1;;21910:9;;;;;;;;;;;;;;:12;;:51;22112:3;;22125:9;;-1:-1:-1;;;;;22112:3:0;;;;:12;;22125:6;;22112:3;;22125:9;;;;;;;;;;:12;;;22112:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22112:26:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;22112:26:0;;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;22112:26:0;;;;;;;22064:9;;:6;;22071:1;;22064:9;;;;;;;;;;:19;;22087:6;22094:1;22087:9;;;;;;;;;;;;;;;;;;22063:75;;;;;21810:415;;;22193:9;;-1:-1:-1;;;;;22181:21:0;;;22193:9;;22181:21;:33;;22211:3;22181:33;;;22205:3;22181:33;22169:6;22176:1;22169:9;;;;;;;;;;;;;:45;;;;21810:415;22235:14;22260:36;;:::i;:::-;22299:18;;;;;;;;22309:1;22299:18;;;;22312:1;22299:18;;;;22315:1;22299:18;;;22260:57;;22328:2088;22335:22;;22328:2088;;22615:29;;22407:13;;-1:-1:-1;22615:51:0;-1:-1:-1;22611:1589:0;;22713:19;:22;;;22686:6;22693:13;22686:21;;;;;;;;;;;;;;:24;;:49;;;;;22840:19;:29;;;22808:19;:29;;;22787:18;:50;:82;;;;;;22753:6;22760:13;22753:21;;;;;;;;;;;;;;:31;;:116;;;;;22921:18;22887:6;22894:13;22887:21;;;;;;;;;;;;;;:31;;:52;;;;;22976:6;22983:13;22976:21;;;;;;;;;;;;;;:31;;;22957:50;;;;23025:15;;;;;23079:1;23058:22;;23098:5;;22611:1589;23163:18;23128:6;23135:13;23128:21;;;;;;;;;;;;;;:31;;;:53;23124:1076;;23290:6;23297:13;23290:21;;;;;;;;;;;;;;:31;;;23256:6;23263:13;23256:21;;;;;;;;;;;;;;:31;;;23235:18;:52;:86;;;;23124:1076;23616:1;23599:13;23581:15;:31;23580:37;:112;;;;;23680:12;23645:6;23652:13;23645:21;;;;;;;;;;;;;;:31;;;:47;;23580:112;23576:624;;;23731:6;23738:13;23731:21;;;;;;;;;;;;;;:31;;;23712:50;;;;23802:6;23809:13;23802:21;;;;;;;;;;;;;;:31;;;23780:53;;;;23851:15;;;;;23576:624;;;23925:19;:29;;;23891:6;23898:13;23891:21;;;;;;;;;;;;;;:31;;;:63;23887:313;;;24006:6;24013:13;24006:21;;;;;;;;;;;;;;;;;;:31;23974:63;;24087:21;;:6;;24094:13;;24087:21;;;;;;;;;;;;:31;;;24055:19;:29;;:63;;;;;24161:6;24168:13;24161:21;;;;;;;;;;;;;;:24;;;24136:19;:22;;:49;;;;;23887:313;24241:3;;24259:17;;-1:-1:-1;;;;;24241:3:0;;;;:17;;24259:6;;24266:9;;24259:17;;;;;;;;;;;;:20;;;24241:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24241:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;24241:39:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24241:39:0;24214:21;;:6;;24221:13;;24214:21;;;;;;;;;;;;;;;;:24;;:66;24367:3;;24380:21;;-1:-1:-1;;;;;24367:3:0;;;;:12;;24380:6;;24387:13;;24380:21;;;;;;;;;;;;:24;;;24367:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24367:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;24367:38:0;;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;24367:38:0;;;;;;;24295:21;;:6;;24302:13;;24295:21;;;;;;;;;;;;:31;;24330:6;24337:13;24330:21;;;;;;;;;;;;;;;;;;24294:111;;;;;-1:-1:-1;;22359:20:0;;;;22328:2088;;;24430:22;;24426:47;;24472:1;24454:19;;24426:47;24487:20;24483:53;;24518:18;;;24534:1;24518:18;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;24509:27;;24483:53;20679:3864;;;;;;;;;;;;;;;;;:::o;1100:420:5:-;1157:4;-1:-1:-1;;;;;1177:26:5;;-1:-1:-1;;;;;;;;;;;1177:26:5;1173:51;;;-1:-1:-1;505:2:5;1205:19;;1173:51;-1:-1:-1;;;;;1278:24:5;;1257:18;1278:24;;;:8;:24;;;;;;1439:18;1435:47;;1466:5;-1:-1:-1;;;;;1466:14:5;;:16;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1466:16:5;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1466:16:5;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1466:16:5;;-1:-1:-1;1459:23:5;;-1:-1:-1;1459:23:5;1435:47;1500:13;-1:-1:-1;1100:420:5;;;;:::o;30764:568:0:-;30879:9;-1:-1:-1;;;30912:8:0;:19;30904:73;;;;-1:-1:-1;;;30904:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;30995:11:0;:22;30987:79;;;;-1:-1:-1;;;30987:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;31084:7:0;:18;31076:71;;;;-1:-1:-1;;;31076:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31176:12:0;31164:25;;;-1:-1:-1;;;31208:28:0;;;;31207:41;;;;31199:49;-1:-1:-1;;;;;31267:35:0;;;;-1:-1:-1;;;31266:59:0;31258:67;;30764:568::o;31659:1002::-;31809:9;-1:-1:-1;;;31842:8:0;:19;31834:69;;;;-1:-1:-1;;;31834:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;31921:8:0;:19;31913:69;;;;-1:-1:-1;;;31913:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32000:5:0;:16;31992:63;;;;-1:-1:-1;;;31992:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32073:5:0;:16;32065:63;;;;-1:-1:-1;;;32065:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32146:9:0;:20;32138:71;;;;-1:-1:-1;;;32138:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32227:9:0;:20;32219:71;;;;-1:-1:-1;;;32219:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;32320:12:0;32594:26;;;32593:61;-1:-1:-1;;;32526:26:0;;;32525:50;;;;32473:22;;;-1:-1:-1;;;32472:35:0;-1:-1:-1;;;32409:22:0;;;32408:46;;;;32353:25;;;-1:-1:-1;;;32352:38:0;32308:25;;32344:46;;;;32400:54;;;;32464:43;;;;32517:58;;;;32585:69;;31659:1002::o;29288:915::-;29451:9;-1:-1:-1;;;29484:12:0;:23;29476:88;;;;-1:-1:-1;;;29476:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;29582:10:0;:21;29574:84;;;;-1:-1:-1;;;29574:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;29676:11:0;:22;29668:86;;;;-1:-1:-1;;;29668:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;29772:11:0;:22;29764:86;;;;-1:-1:-1;;;29764:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;29883:12:0;29867:29;;;-1:-1:-1;;;29915:27:0;;;29914:40;;29906:48;29988:12;29973:28;;-1:-1:-1;;;29972:52:0;29964:60;;430:7;-1:-1:-1;;;29894:1:0;30069;477:7;30058:12;:16;30043:32;;30042:45;:56;:67;30034:75;-1:-1:-1;;;430:7:0;-1:-1:-1;;;30161:1:0;477:7;30150:12;30128:9;:17;;30144:1;30128:17;;;30140:1;30128:17;30127:36;;;:47;:58;:69;30119:77;;29288:915;-1:-1:-1;;;;;29288:915:0:o;13873:3705::-;14093:4;14179:8;14175:319;;;14228:1;14211:14;:18;14203:59;;;;;-1:-1:-1;;;14203:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;14280:29:0;;-1:-1:-1;;;;;;;;;;;14280:29:0;14276:207;;;14348:9;14335;:22;14327:66;;;;;-1:-1:-1;;;14327:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;14276:207;;;14436:9;:14;14428:55;;;;;-1:-1:-1;;;14428:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;14504:27;14534:65;14545:9;458:2:5;;14584:14:0;14534:10;:65::i;:::-;14504:95;;14642:1;14617:22;:26;14609:75;;;;-1:-1:-1;;;14609:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14711:21;14842:18;;;;:23;14876:847;;;;-1:-1:-1;;;;;14977:29:0;;-1:-1:-1;;;;;;;;;;;14977:29:0;14973:584;;;15095:9;-1:-1:-1;;;;;15095:18:0;;15114:11;15127:22;15095:55;;;;;;;;;;;;;-1:-1:-1;;;;;15095:55:0;-1:-1:-1;;;;;15095:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;15095:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;15095:55:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15095:55:0;15087:127;;;;-1:-1:-1;;;15087:127:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14973:584;;;15298:59;;;-1:-1:-1;;;15298:59:0;;15320:10;15298:59;;;;15340:4;15298:59;;;;;;;;;;;;-1:-1:-1;;;;;15298:21:0;;;;;:59;;;;;;;;;;;;;;-1:-1:-1;15298:21:0;:59;;;5:2:-1;;;;30:1;27;20:12;5:2;15298:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;15298:59:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15298:59:0;15290:129;;;;-1:-1:-1;;;15290:129:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15498:44;;-1:-1:-1;;;;;15498:20:0;;;:44;;;;;15519:22;;15498:44;;;;15519:22;15498:20;:44;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;15498:44:0;14973:584;15576:111;;;-1:-1:-1;;;;;15576:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15589:10;;15576:111;;;;;;;;;;15708:4;15701:11;;;;;;;14876:847;15733:20;;:::i;:::-;15763;;:::i;:::-;15806:77;-1:-1:-1;;;;;15830:29:0;;-1:-1:-1;;;;;;;;;;;15830:29:0;:52;;15874:8;15830:52;;;15862:9;15830:52;15806:23;:77::i;:::-;15793:90;;-1:-1:-1;15793:90:0;-1:-1:-1;15924:25:0;-1:-1:-1;;;;;15963:29:0;;-1:-1:-1;;;;;;;;;;;15963:29:0;15959:262;;;16063:9;;16037:57;;16052:9;;-1:-1:-1;;;;;16063:9:0;16074;16085:3;16090;16037:14;:57::i;:::-;16008:86;;-1:-1:-1;16008:86:0;-1:-1:-1;15959:262:0;;;16169:9;;16154:56;;-1:-1:-1;;;;;16169:9:0;16180:8;16190:9;16201:3;16206;16154:14;:56::i;:::-;16125:85;;-1:-1:-1;16125:85:0;-1:-1:-1;15959:262:0;16259:22;16239:16;:42;;16231:116;;;;-1:-1:-1;;;16231:116:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;16362:29:0;;-1:-1:-1;;;;;;;;;;;16362:29:0;16358:1066;;;16407:9;;;;;;;;;-1:-1:-1;;;;;16407:9:0;-1:-1:-1;;;;;16407:17:0;;16431:9;16407:36;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;16407:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;16407:36:0;;;;;16476:48;16495:9;16506;16517:6;16476:18;:48::i;:::-;16457:67;;16566:22;16546:16;:42;;16538:130;;;;-1:-1:-1;;;16538:130:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16746:9;-1:-1:-1;;;;;16746:18:0;;16765:11;16778:22;16746:55;;;;;;;;;;;;;-1:-1:-1;;;;;16746:55:0;-1:-1:-1;;;;;16746:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;16746:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;16746:55:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;16746:55:0;16738:114;;;;-1:-1:-1;;;16738:114:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16358:1066;;;16925:59;;;-1:-1:-1;;;16925:59:0;;16947:10;16925:59;;;;16967:4;16925:59;;;;;;;;;;;;-1:-1:-1;;;;;16925:21:0;;;;;:59;;;;;;;;;;;;;;-1:-1:-1;16925:21:0;:59;;;5:2:-1;;;;30:1;27;20:12;5:2;16925:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;16925:59:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;16925:59:0;16917:106;;;;-1:-1:-1;;;16917:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17075:9;;17056:48;;-1:-1:-1;;;;;17075:9:0;17086;17097:6;17056:18;:48::i;:::-;17037:67;;17146:22;17126:16;:42;;17118:130;;;;-1:-1:-1;;;17118:130:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17262:9;;:36;;;-1:-1:-1;;;17262:36:0;;;;;;;;;;-1:-1:-1;;;;;17262:9:0;;;;:18;;:36;;;;;:9;;:36;;;;;;;;:9;;:36;;;5:2:-1;;;;30:1;27;20:12;5:2;17262:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;17369:44:0;;-1:-1:-1;;;;;17369:20:0;;;-1:-1:-1;17369:44:0;;;;;-1:-1:-1;17390:22:0;;17369:44;;;;17390:22;17369:20;:44;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;17369:44:0;16358:1066;17439:111;;;-1:-1:-1;;;;;17439:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17452:10;;17439:111;;;;;;;;;;-1:-1:-1;17567:4:0;;13873:3705;-1:-1:-1;;;;;;;;;;;;13873:3705:0:o;27386:860::-;27539:4;27626:3;:6;;;27636:1;27626:11;:26;;;-1:-1:-1;27641:6:0;;;;:11;27626:26;:53;;;;304:6:5;27656:3:0;:13;;;:23;27626:53;:80;;;-1:-1:-1;27683:13:0;;304:6:5;-1:-1:-1;27626:80:0;:107;;;;304:6:5;27710:3:0;:13;;;:23;27626:107;:134;;;-1:-1:-1;27737:13:0;;304:6:5;-1:-1:-1;27626:134:0;27622:177;;;-1:-1:-1;27783:5:0;27776:12;;27622:177;27835:13;;27819;;27884;;;;;27868;;;;27819:29;;;;;27868;27953:8;;;27949:31;;27972:5;27965:12;;;;;;27949:31;28059:19;28054:42;;28089:4;28082:11;;;;;;28054:42;28187:12;28182:2;:17;28175:2;28170;:7;519:5;28163:15;:36;28159:59;;28210:5;28203:12;;;;;;28159:59;-1:-1:-1;28235:4:0;;27386:860;-1:-1:-1;;;;;;27386:860:0:o;3329:614:5:-;3453:4;304:6;3481:9;:20;;3473:29;;;;;;304:6;3520:10;:21;;3512:30;;;;;;3572:11;3557;:26;3553:384;;458:2;3622:11;3608;:25;3607:43;;3599:52;;;;;;3737:9;3721:11;3707;:25;3700:2;:33;3699:47;254:6;3673:10;:22;:74;;;;;;3665:83;;;;3553:384;458:2;3802:11;3788;:25;3787:43;;3779:52;;;;;;3916:9;3900:11;3886;:25;3879:2;:33;254:6;3853:10;:22;:60;:72;;;;18743:1249:0;18974:14;;304:6:5;19077:18:0;;19073:59;;;19099:30;;19073:59;19142:42;;:::i;:::-;19187:31;19212:5;19187:24;:31::i;:::-;19233:23;;19142:76;;-1:-1:-1;19228:65:0;;-1:-1:-1;19260:30:0;;19228:65;19316:24;;;;19371:30;;;-1:-1:-1;;;19371:30:0;;19395:4;19371:30;;;;;;19316:24;;-1:-1:-1;19351:17:0;;-1:-1:-1;;;;;19371:15:0;;;;;:30;;;;;;;;;;;;;;:15;:30;;;5:2:-1;;;;30:1;27;20:12;5:2;19371:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;19371:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;19371:30:0;;-1:-1:-1;19412:415:0;;;;19461:8;19446:12;:23;19442:64;;;-1:-1:-1;19473:30:0;;-1:-1:-1;19473:30:0;19442:64;19549:13;:25;;;19538:8;19523:12;:23;:51;19519:92;;;-1:-1:-1;19578:30:0;;-1:-1:-1;19578:30:0;19519:92;19412:415;;;19653:4;19645:21;:30;-1:-1:-1;19641:71:0;;;-1:-1:-1;19679:30:0;;-1:-1:-1;19679:30:0;19641:71;19755:13;:25;;;19744:8;19729:12;:23;:51;19725:92;;;-1:-1:-1;19784:30:0;;-1:-1:-1;19784:30:0;19725:92;19842:60;19859:3;19864;19869:4;19875:13;:26;;;19842:16;:60::i;:::-;19837:122;;-1:-1:-1;19918:30:0;;-1:-1:-1;19918:30:0;19837:122;19981:4;19969:16;;18743:1249;;;;;;;;;;;;:::o;20462:211::-;20541:4;304:6:5;20565:3:0;:14;;20557:65;;;;-1:-1:-1;;;20557:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;519:5:0;20646:13;;;20639:21;;;;:27;;20462:211::o;20262:194::-;20325:4;304:6:5;20349:3:0;:14;;20341:63;;;;-1:-1:-1;;;20341:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;519:5;20439:3;20429:6;;519:5;20423:12;20422:20;20421:28;;;;;;;20262:194;-1:-1:-1;;20262:194:0:o;19998:258::-;20138:4;20178:20;:28;;20205:1;20178:28;;;20201:1;20178:28;20165:42;;20172:1;20165:4;:8;:42;:84;;20248:1;20241:4;:8;20165:84;;;20222:4;20165:84;20158:91;19998:258;-1:-1:-1;;;19998:258:0:o;30209:549::-;30295:14;30630:16;-1:-1:-1;;;30586:39:0;;30585:62;30548:12;-1:-1:-1;;;30515:28:0;;30514:47;30420:12;-1:-1:-1;;;30457:15:0;;30456:34;;;30412:21;;30641:1;-1:-1:-1;;;30586:39:0;30670:56;30669:62;;;;;;:67;:82;;30747:4;30669:82;;;30739:5;30669:82;30657:94;30209:549;;-1:-1:-1;30209:549:0;;-1:-1:-1;30209:549:0;:::o;32667:535::-;-1:-1:-1;;;33138:39:0;;32861:12;33137:58;;;;-1:-1:-1;;;33069:28:0;;33068:47;;;-1:-1:-1;;;33013:15:0;;33012:34;;;-1:-1:-1;;;32948:28:0;;32947:47;;;-1:-1:-1;;;32896:15:0;;32895:34;;;32853:21;;;;32667:535::o;31338:315::-;-1:-1:-1;;;;;;;;31589:28:0;;31588:58;;31497:12;-1:-1:-1;;;31535:15:0;;31534:34;;;31489:21;;31338:315::o;27078:302::-;27260:3;;:43;;;-1:-1:-1;;;27260:43:0;;-1:-1:-1;;;;;27260:43:0;;;;;;;;;;;;;;;;27180:12;;;;;;27260:3;;;:16;;:43;;;;;;;;;;;;;;;:3;:43;;;5:2:-1;;;;30:1;27;20:12;5:2;27260:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27260:43:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;27260:43:0;27352:3;;:21;;;-1:-1:-1;;;27352:21:0;;;;;;;;;;27260:43;;-1:-1:-1;;;;;;27352:3:0;;;;:12;;:21;;;;;;;;;;;;;;;:3;:21;;;5:2:-1;;;;30:1;27;20:12;5:2;27352:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27352:21:0;;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;27352:21:0;;;;;;;27078:302;;27352:21;;-1:-1:-1;27352:21:0;-1:-1:-1;;;27078:302:0:o;24637:1969::-;24845:13;24860:16;24878:17;24916:12;24915:13;:45;;;;-1:-1:-1;24933:6:0;;;;:11;;:26;;-1:-1:-1;24948:6:0;;;;:11;24933:26;24911:298;;;-1:-1:-1;25080:1:0;;-1:-1:-1;25080:1:0;;-1:-1:-1;25080:1:0;25154:44;;24911:298;25219:14;;25281:12;25276:225;;25384:13;;25472;;;;25456;;25384;;-1:-1:-1;25489:1:0;;25440:29;;25472:13;25440:45;;;;;25424:3;:13;;;:61;25423:67;;;;;;25411:79;;25276:225;25511:17;25531:12;:60;;25582:9;25570;25558;:21;:33;;;;;;25531:60;;;25546:9;25531:60;25511:80;;25602:32;;:::i;:::-;25637:24;25655:5;25637:17;:24::i;:::-;25602:59;;25702:12;25676:9;:23;;;:38;25672:198;;;-1:-1:-1;25741:1:0;;-1:-1:-1;25741:1:0;;-1:-1:-1;25741:1:0;;-1:-1:-1;25815:44:0;;-1:-1:-1;;;25815:44:0;25672:198;25880:34;;:::i;:::-;25917:20;25931:5;25917:13;:20::i;:::-;26063:23;;;;26010;;25880:57;;-1:-1:-1;25970:6:0;;;;26063:23;254:6:5;;26010:38:0;;:50;:76;26009:95;;;;;;25995:109;;26128:41;26134:11;26147:9;:21;;;26128:5;:41::i;:::-;26114:55;;26264:14;26241:10;:19;;;254:6:5;26214:12:0;26192:10;:19;;;:34;:46;;;;;;:68;26191:87;;;;;;26180:98;;26299:35;26305:8;26315:9;:18;;;26299:5;:35::i;:::-;26288:46;;26345:17;26448:14;254:6:5;26408:10:0;:24;;;:36;26393:12;26366:10;:24;;;:39;:78;26365:97;;;;;;26345:117;;26533:12;:66;;26590:9;26578;26563:12;:24;:36;;;;;;26533:66;;;26548:12;26533:66;26518:81;;24637:1969;;;;;;;;;;;;;;;;;:::o;1526:558:5:-;1628:4;304:6;1652;:17;;1644:26;;;;;;368:17;1688:16;;;1680:25;;;;;;1735:11;1720;:26;1716:362;;458:2;1785:11;1771;:25;1770:43;;1762:52;;;;;;254:6;1836:13;;;1858:25;;;1853:2;:31;1836:49;1835:63;;1716:362;458:2;1952:11;1938;:25;1937:43;;1929:52;;;;;;2053:11;2039;:25;2034:2;:31;254:6;2021:45;2012:4;2003:6;:13;2002:65;;;;17584:1153:0;17706:21;-1:-1:-1;;;;;17751:30:0;;-1:-1:-1;;;;;;;;;;;17751:30:0;;17743:79;;;;-1:-1:-1;;;17743:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17859:34;;;-1:-1:-1;;;17859:34:0;;17887:4;17859:34;;;;;;17833:23;;-1:-1:-1;;;;;17859:19:0;;;;;:34;;;;;;;;;;;;;;;:19;:34;;;5:2:-1;;;;30:1;27;20:12;5:2;17859:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;17859:34:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;17859:34:0;;-1:-1:-1;17929:9:0;17903:23;17949:398;17970:6;:13;17966:1;:17;17949:398;;;18008:6;18015:1;18008:9;;;;;;;;;;;;;;:12;;;18024:1;18008:17;:44;;;-1:-1:-1;18029:23:0;;18008:44;18004:60;;;18056:5;;18004:60;18078:14;18095:46;18101:18;18121:6;18128:1;18121:9;;;;;;;;;;;;;;:19;;;18095:5;:46::i;:::-;18078:63;;18155:14;18206:6;18213:1;18206:9;;;;;;;;;;;;;;:19;;;18184:6;18191:1;18184:9;;;;;;;;;;;;;;:19;;;18172:9;:31;:53;;;;;18240:3;;18257:9;;18172:53;;;;;-1:-1:-1;;;;;;18240:3:0;;:8;;18257:6;;18264:1;;18257:9;;;;;;;;;;;;:12;;;18249:21;;18280:9;18240:51;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18240:51:0;-1:-1:-1;;;;;18240:51:0;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;18240:51:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;;18305:31:0;;;;;-1:-1:-1;;17985:3:0;;17949:398;;;-1:-1:-1;18396:23:0;;18388:83;;;;-1:-1:-1;;;18388:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18507:34;;;-1:-1:-1;;;18507:34:0;;18535:4;18507:34;;;;;;18482:22;;-1:-1:-1;;;;;18507:19:0;;;;;:34;;;;;;;;;;;;;;;:19;:34;;;5:2:-1;;;;30:1;27;20:12;5:2;18507:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;18507:34:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;18507:34:0;;-1:-1:-1;18560:38:0;;;18552:110;;;;-1:-1:-1;;;18552:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18692:38;;;;;17584:1153;-1:-1:-1;;;;;17584:1153:0:o;28787:495::-;28873:33;;:::i;:::-;-1:-1:-1;;;;;29041:37:0;;28923:14;29041:37;;;:21;:37;;;;;;28923:14;;;;;;;;29013:66;;:27;:66::i;:::-;29089:26;;;;;29125:16;;;:30;;;;29165:16;;;:30;29205:15;;;:28;29243:17;;;:32;-1:-1:-1;29089:4:0;;28787:495;-1:-1:-1;;;;;28787:495:0:o;28252:237::-;28331:27;;:::i;:::-;-1:-1:-1;;;;;28451:30:0;;;;;;:14;:30;;;;;;28430:52;;:20;:52::i;:::-;28413:13;;;28374:108;28395:16;;;28374:108;;;28375:4;28252:237;-1:-1:-1;28252:237:0:o;28495:286::-;28570:28;;:::i;:::-;-1:-1:-1;;;;;28742:31:0;;;;;;:15;:31;;;;;;28725:49;;:16;:49::i;:::-;28703:18;;;28614:160;28683:18;;;28614:160;28668:13;;;28614:160;28653:13;;;28614:160;28634:17;;;28614:160;;;28615:4;28495:286;-1:-1:-1;28495:286:0:o;3949:96:5:-;4002:4;4029:1;4025;:5;:13;;4037:1;4025:13;;;-1:-1:-1;4033:1:5;3949:96;-1:-1:-1;3949:96:5:o;260:32944:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;

Swarm Source

bzzr://f7176853b66f2143cb40c5e1f89ef13c30e774c34072fdf646619a54003488a2

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
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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.