Contract 0x43b4dfb998b4D17705EEBfFCc0380c6b98699252

 
Ad
Ad
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xa8a7adc3ab07c44d27e385f175ce752a96252cfe9101f4781d0bb63892b6a8e7Collect Protocol...180539762021-08-16 17:56:4531 days 10 hrs ago0x861c0457cd6440fa090cd35b555c36fbf1a6373d IN  0x43b4dfb998b4d17705eebffcc0380c6b986992520 MATIC0.000059734
0xf94deac554a38dc64f2e4cf4a9b5c6d192c73ab534f406e693f9baee78725a8aCollect Protocol...171484942021-07-22 15:11:0456 days 13 hrs ago0xa949027ade80946f514c0e8e878e87c69609fa63 IN  0x43b4dfb998b4d17705eebffcc0380c6b986992520 MATIC0.00115251
0x5d34668360868b47bd4e07e79e44e0dee3cf5577be88357808a7224c41d9100f0x61022060162477732021-06-28 12:11:5980 days 16 hrs ago0x80b4d014aa41eff99083336bbeae378617cff076 IN  Contract Creation0 MATIC0.005066787
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PerpetualPool

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 1 of 12: PerpetualPool.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

import './IERC20.sol';
import './IOracle.sol';
import './IBTokenSwapper.sol';
import './IPToken.sol';
import './ILToken.sol';
import './IPerpetualPool.sol';
import './SafeMath.sol';
import './SafeERC20.sol';

/*
Revert Code:

reentry         : reentry is blocked
router only     : can only called by router
wrong dec       : wrong bToken decimals
insuf't b0      : pool insufficient bToken0
insuf't liq     : pool insufficient liquidity
insuf't margin  : trader insufficient margin
cant liquidate  : cannot liquidate trader
*/

contract PerpetualPool is IPerpetualPool {

    using SafeMath for uint256;
    using SafeMath for int256;
    using SafeERC20 for IERC20;

    int256  constant ONE = 10**18;

    // decimals for bToken0 (settlement token), make this immutable to save gas
    uint256 immutable _decimals0;
    int256  immutable _minBToken0Ratio;
    int256  immutable _minPoolMarginRatio;
    int256  immutable _minInitialMarginRatio;
    int256  immutable _minMaintenanceMarginRatio;
    int256  immutable _minLiquidationReward;
    int256  immutable _maxLiquidationReward;
    int256  immutable _liquidationCutRatio;
    int256  immutable _protocolFeeCollectRatio;

    address immutable _lTokenAddress;
    address immutable _pTokenAddress;
    address immutable _routerAddress;
    address immutable _protocolFeeCollector;

    uint256 _lastUpdateBlock;
    int256  _protocolFeeAccrued;

    BTokenInfo[] _bTokens;   // bTokenId indexed
    SymbolInfo[] _symbols;   // symbolId indexed

    bool private _mutex;
    modifier _lock_() {
        require(!_mutex, 'reentry');
        _mutex = true;
        _;
        _mutex = false;
    }

    modifier _router_() {
        require(msg.sender == _routerAddress, 'router only');
        _;
    }

    constructor (uint256[9] memory parameters, address[4] memory addresses) {
        _decimals0 = parameters[0];
        _minBToken0Ratio = int256(parameters[1]);
        _minPoolMarginRatio = int256(parameters[2]);
        _minInitialMarginRatio = int256(parameters[3]);
        _minMaintenanceMarginRatio = int256(parameters[4]);
        _minLiquidationReward = int256(parameters[5]);
        _maxLiquidationReward = int256(parameters[6]);
        _liquidationCutRatio = int256(parameters[7]);
        _protocolFeeCollectRatio = int256(parameters[8]);

        _lTokenAddress = addresses[0];
        _pTokenAddress = addresses[1];
        _routerAddress = addresses[2];
        _protocolFeeCollector = addresses[3];
    }

    function getParameters() external override view returns (
        uint256 decimals0,
        int256  minBToken0Ratio,
        int256  minPoolMarginRatio,
        int256  minInitialMarginRatio,
        int256  minMaintenanceMarginRatio,
        int256  minLiquidationReward,
        int256  maxLiquidationReward,
        int256  liquidationCutRatio,
        int256  protocolFeeCollectRatio
    ) {
        decimals0 = _decimals0;
        minBToken0Ratio = _minBToken0Ratio;
        minPoolMarginRatio = _minPoolMarginRatio;
        minInitialMarginRatio = _minInitialMarginRatio;
        minMaintenanceMarginRatio = _minMaintenanceMarginRatio;
        minLiquidationReward = _minLiquidationReward;
        maxLiquidationReward = _maxLiquidationReward;
        liquidationCutRatio = _liquidationCutRatio;
        protocolFeeCollectRatio = _protocolFeeCollectRatio;
    }

    function getAddresses() external override view returns (
        address lTokenAddress,
        address pTokenAddress,
        address routerAddress,
        address protocolFeeCollector
    ) {
        lTokenAddress = _lTokenAddress;
        pTokenAddress = _pTokenAddress;
        routerAddress = _routerAddress;
        protocolFeeCollector = _protocolFeeCollector;
    }

    function getLengths() external override view returns (uint256, uint256) {
        return (_bTokens.length, _symbols.length);
    }

    function getBToken(uint256 bTokenId) external override view returns (BTokenInfo memory) {
        return _bTokens[bTokenId];
    }

    function getSymbol(uint256 symbolId) external override view returns (SymbolInfo memory) {
        return _symbols[symbolId];
    }

    function getBTokenOracle(uint256 bTokenId) external override view returns (address) {
        return _bTokens[bTokenId].oracleAddress;
    }

    function getSymbolOracle(uint256 symbolId) external override view returns (address) {
        return _symbols[symbolId].oracleAddress;
    }

    function getProtocolFeeAccrued() external override view returns (int256) {
        return _protocolFeeAccrued;
    }

    function collectProtocolFee() external override {
        IERC20 token = IERC20(_bTokens[0].bTokenAddress);
        uint256 amount = _protocolFeeAccrued.itou().rescale(18, _decimals0);
        if (amount > token.balanceOf(address(this))) amount = token.balanceOf(address(this));
        _protocolFeeAccrued -= amount.rescale(_decimals0, 18).utoi();
        token.safeTransfer(_protocolFeeCollector, amount);
        emit ProtocolFeeCollection(_protocolFeeCollector, amount.rescale(_decimals0, 18));
    }

    function addBToken(BTokenInfo memory info) external override _router_ {
        if (_bTokens.length > 0) {
            // approve for non bToken0 swappers
            IERC20(_bTokens[0].bTokenAddress).safeApprove(info.swapperAddress, type(uint256).max);
            IERC20(info.bTokenAddress).safeApprove(info.swapperAddress, type(uint256).max);
            info.price = IOracle(info.oracleAddress).getPrice().utoi();
        } else {
            require(info.decimals == _decimals0, 'wrong dec');
            info.price = ONE;
        }
        _bTokens.push(info);
        ILToken(_lTokenAddress).setNumBTokens(_bTokens.length);
        IPToken(_pTokenAddress).setNumBTokens(_bTokens.length);
    }

    function addSymbol(SymbolInfo memory info) external override _router_ {
        _symbols.push(info);
        IPToken(_pTokenAddress).setNumSymbols(_symbols.length);
    }

    function setBTokenParameters(uint256 bTokenId, address swapperAddress, address oracleAddress, uint256 discount) external override _router_ {
        BTokenInfo storage b = _bTokens[bTokenId];
        b.swapperAddress = swapperAddress;
        if (bTokenId != 0) {
            IERC20(_bTokens[0].bTokenAddress).safeApprove(swapperAddress, 0);
            IERC20(_bTokens[bTokenId].bTokenAddress).safeApprove(swapperAddress, 0);
            IERC20(_bTokens[0].bTokenAddress).safeApprove(swapperAddress, type(uint256).max);
            IERC20(_bTokens[bTokenId].bTokenAddress).safeApprove(swapperAddress, type(uint256).max);
        }
        b.oracleAddress = oracleAddress;
        b.discount = int256(discount);
    }

    function setSymbolParameters(uint256 symbolId, address oracleAddress, uint256 feeRatio, uint256 fundingRateCoefficient) external override _router_ {
        SymbolInfo storage s = _symbols[symbolId];
        s.oracleAddress = oracleAddress;
        s.feeRatio = int256(feeRatio);
        s.fundingRateCoefficient = int256(fundingRateCoefficient);
    }

    // during a migration, this function is intended to be called in the source pool
    function approvePoolMigration(address targetPool) external override _router_ {
        for (uint256 i = 0; i < _bTokens.length; i++) {
            IERC20(_bTokens[i].bTokenAddress).safeApprove(targetPool, type(uint256).max);
        }
        ILToken(_lTokenAddress).setPool(targetPool);
        IPToken(_pTokenAddress).setPool(targetPool);
    }

    // during a migration, this function is intended to be called in the target pool
    function executePoolMigration(address sourcePool) external override _router_ {
        // (uint256 blength, uint256 slength) = IPerpetualPool(sourcePool).getLengths();
        // for (uint256 i = 0; i < blength; i++) {
        //     BTokenInfo memory b = IPerpetualPool(sourcePool).getBToken(i);
        //     IERC20(b.bTokenAddress).safeTransferFrom(sourcePool, address(this), IERC20(b.bTokenAddress).balanceOf(sourcePool));
        //     _bTokens.push(b);
        // }
        // for (uint256 i = 0; i < slength; i++) {
        //     _symbols.push(IPerpetualPool(sourcePool).getSymbol(i));
        // }
        // _protocolFeeAccrued = IPerpetualPool(sourcePool).getProtocolFeeAccrued();
    }


    //================================================================================
    // Core Logics
    //================================================================================

    function addLiquidity(address owner, uint256 bTokenId, uint256 bAmount, uint256 blength, uint256 slength) external override _router_ _lock_ {
        ILToken lToken = ILToken(_lTokenAddress);
        if(!lToken.exists(owner)) lToken.mint(owner);

        _updateBTokenPrice(bTokenId);
        _updatePricesAndDistributePnl(blength, slength);

        BTokenInfo storage b = _bTokens[bTokenId];
        bAmount = _deflationCompatibleSafeTransferFrom(b.bTokenAddress, b.decimals, owner, address(this), bAmount);

        int256 cumulativePnl = b.cumulativePnl;
        ILToken.Asset memory asset = lToken.getAsset(owner, bTokenId);

        int256 delta; // owner's liquidity change amount for bTokenId
        int256 pnl = (cumulativePnl - asset.lastCumulativePnl) * asset.liquidity / ONE; // owner's pnl as LP since last settlement
        if (bTokenId == 0) {
            delta = bAmount.utoi() + pnl.reformat(_decimals0);
            b.pnl -= pnl; // this pnl comes from b.pnl, thus should be deducted from b.pnl
            _protocolFeeAccrued += pnl - pnl.reformat(_decimals0); // deal with accuracy tail
        } else {
            delta = bAmount.utoi();
            asset.pnl += pnl;
        }
        asset.liquidity += delta;
        asset.lastCumulativePnl = cumulativePnl;
        b.liquidity += delta;

        lToken.updateAsset(owner, bTokenId, asset);

        (int256 totalDynamicEquity, int256[] memory dynamicEquities) = _getBTokenDynamicEquities(blength);
        require(_getBToken0Ratio(totalDynamicEquity, dynamicEquities) >= _minBToken0Ratio, "insuf't b0");

        emit AddLiquidity(owner, bTokenId, bAmount);
    }

    function removeLiquidity(address owner, uint256 bTokenId, uint256 bAmount, uint256 blength, uint256 slength) external override _router_ _lock_ {
        _updateBTokenPrice(bTokenId);
        _updatePricesAndDistributePnl(blength, slength);

        BTokenInfo storage b = _bTokens[bTokenId];
        ILToken lToken = ILToken(_lTokenAddress);
        ILToken.Asset memory asset = lToken.getAsset(owner, bTokenId);
        uint256 decimals = b.decimals;
        bAmount = bAmount.reformat(decimals);

        { // scope begin
        int256 cumulativePnl = b.cumulativePnl;
        int256 amount = bAmount.utoi();
        int256 pnl = (cumulativePnl - asset.lastCumulativePnl) * asset.liquidity / ONE;
        int256 deltaLiquidity;
        int256 deltaPnl;
        if (bTokenId == 0) {
            deltaLiquidity = pnl.reformat(_decimals0);
            deltaPnl = -pnl;
            _protocolFeeAccrued += pnl - pnl.reformat(_decimals0); // deal with accuracy tail
        } else {
            asset.pnl += pnl;
            if (asset.pnl < 0) {
                (uint256 amountB0, uint256 amountBX) = IBTokenSwapper(b.swapperAddress).swapBXForExactB0(
                    (-asset.pnl).ceil(_decimals0).itou(), asset.liquidity.itou(), b.price.itou()
                );
                deltaLiquidity = -amountBX.utoi();
                deltaPnl = amountB0.utoi();
                asset.pnl += amountB0.utoi();
            } else if (asset.pnl > 0 && amount >= asset.liquidity) {
                (, uint256 amountBX) = IBTokenSwapper(b.swapperAddress).swapExactB0ForBX(asset.pnl.itou(), b.price.itou());
                deltaLiquidity = amountBX.utoi();
                deltaPnl = -asset.pnl;
                _protocolFeeAccrued += asset.pnl - asset.pnl.reformat(_decimals0); // deal with accuracy tail
                asset.pnl = 0;
            }
        }
        asset.lastCumulativePnl = cumulativePnl;

        if (amount >= asset.liquidity || amount >= asset.liquidity + deltaLiquidity) {
            bAmount = (asset.liquidity + deltaLiquidity).itou();
            b.liquidity -= asset.liquidity;
            asset.liquidity = 0;
        } else {
            asset.liquidity += deltaLiquidity - amount;
            b.liquidity += deltaLiquidity - amount;
        }
        b.pnl += deltaPnl;
        lToken.updateAsset(owner, bTokenId, asset);
        } // scope end

        (int256 totalDynamicEquity, ) = _getBTokenDynamicEquities(blength);
        require(_getPoolMarginRatio(totalDynamicEquity, slength) >= _minPoolMarginRatio, "insuf't liq");

        IERC20(b.bTokenAddress).safeTransfer(owner, bAmount.rescale(18, decimals));
        emit RemoveLiquidity(owner, bTokenId, bAmount);
    }

    function addMargin(address owner, uint256 bTokenId, uint256 bAmount) external override _router_ _lock_ {
        IPToken pToken = IPToken(_pTokenAddress);
        if (!pToken.exists(owner)) pToken.mint(owner);

        BTokenInfo storage b = _bTokens[bTokenId];
        bAmount = _deflationCompatibleSafeTransferFrom(b.bTokenAddress, b.decimals, owner, address(this), bAmount);

        int256 margin = pToken.getMargin(owner, bTokenId) + bAmount.utoi();

        pToken.updateMargin(owner, bTokenId, margin);
        emit AddMargin(owner, bTokenId, bAmount);
    }

    function removeMargin(address owner, uint256 bTokenId, uint256 bAmount, uint256 blength, uint256 slength) external override _router_ _lock_ {
        _updatePricesAndDistributePnl(blength, slength);
        _settleTraderFundingFee(owner, slength);
        _coverTraderDebt(owner, blength);

        IPToken pToken = IPToken(_pTokenAddress);
        BTokenInfo storage b = _bTokens[bTokenId];
        uint256 decimals = b.decimals;
        bAmount = bAmount.reformat(decimals);

        int256 amount = bAmount.utoi();
        int256 margin = pToken.getMargin(owner, bTokenId);

        if (amount >= margin) {
            bAmount = margin.itou();
            if (bTokenId == 0) _protocolFeeAccrued += margin - margin.reformat(_decimals0); // deal with accuracy tail
            margin = 0;
        } else {
            margin -= amount;
        }
        pToken.updateMargin(owner, bTokenId, margin);

        require(_getTraderMarginRatio(owner, blength, slength) >= _minInitialMarginRatio, "insuf't margin");

        IERC20(b.bTokenAddress).safeTransfer(owner, bAmount.rescale(18, decimals));
        emit RemoveMargin(owner, bTokenId, bAmount);
    }

    // struct for temp use in trade function, to prevent stack too deep error
    struct TradeParams {
        int256 curCost;
        int256 fee;
        int256 realizedCost;
        int256 protocolFee;
    }

    function trade(address owner, uint256 symbolId, int256 tradeVolume, uint256 blength, uint256 slength) external override _router_ _lock_ {
        _updatePricesAndDistributePnl(blength, slength);
        _settleTraderFundingFee(owner, slength);

        SymbolInfo storage s = _symbols[symbolId];
        IPToken.Position memory p = IPToken(_pTokenAddress).getPosition(owner, symbolId);

        TradeParams memory params;

        tradeVolume = tradeVolume.reformat(0);
        params.curCost = tradeVolume * s.price / ONE * s.multiplier / ONE;
        params.fee = params.curCost.abs() * s.feeRatio / ONE;

        if (!(p.volume >= 0 && tradeVolume >= 0) && !(p.volume <= 0 && tradeVolume <= 0)) {
            int256 absVolume = p.volume.abs();
            int256 absTradeVolume = tradeVolume.abs();
            if (absVolume <= absTradeVolume) {
                params.realizedCost = params.curCost * absVolume / absTradeVolume + p.cost;
            } else {
                params.realizedCost = p.cost * absTradeVolume / absVolume + params.curCost;
            }
        }

        p.volume += tradeVolume;
        p.cost += params.curCost - params.realizedCost;
        p.lastCumulativeFundingRate = s.cumulativeFundingRate;
        IPToken(_pTokenAddress).updateMargin(
            owner, 0, IPToken(_pTokenAddress).getMargin(owner, 0) - params.fee - params.realizedCost
        );
        IPToken(_pTokenAddress).updatePosition(owner, symbolId, p);

        s.tradersNetVolume += tradeVolume;
        s.tradersNetCost += params.curCost - params.realizedCost;

        params.protocolFee = params.fee * _protocolFeeCollectRatio / ONE;
        _protocolFeeAccrued += params.protocolFee;

        (int256 totalDynamicEquity, int256[] memory dynamicEquities) = _getBTokenDynamicEquities(blength);
        _distributePnlToBTokens(params.fee - params.protocolFee, totalDynamicEquity, dynamicEquities, blength);
        require(_getPoolMarginRatio(totalDynamicEquity, slength) >= _minPoolMarginRatio, "insuf't liq");
        require(_getTraderMarginRatio(owner, blength, slength) >= _minInitialMarginRatio, "insuf't margin");

        emit Trade(owner, symbolId, tradeVolume, s.price.itou());
    }

    function liquidate(address liquidator, address owner, uint256 blength, uint256 slength) external override _router_ _lock_ {
        _updateAllBTokenPrices(blength);
        _updatePricesAndDistributePnl(blength, slength);
        _settleTraderFundingFee(owner, slength);
        require(_getTraderMarginRatio(owner, blength, slength) < _minMaintenanceMarginRatio, 'cant liquidate');

        IPToken pToken = IPToken(_pTokenAddress);
        IPToken.Position[] memory positions = pToken.getPositions(owner);
        int256 netEquity;
        for (uint256 i = 0; i < slength; i++) {
            if (positions[i].volume != 0) {
                _symbols[i].tradersNetVolume -= positions[i].volume;
                _symbols[i].tradersNetCost -= positions[i].cost;
                netEquity += positions[i].volume * _symbols[i].price / ONE * _symbols[i].multiplier / ONE - positions[i].cost;
            }
        }

        int256[] memory margins = pToken.getMargins(owner);
        netEquity += margins[0];
        for (uint256 i = 1; i < blength; i++) {
            if (margins[i] > 0) {
                (uint256 amountB0, ) = IBTokenSwapper(_bTokens[i].swapperAddress).swapExactBXForB0(margins[i].itou(), _bTokens[i].price.itou());
                netEquity += amountB0.utoi();
            }
        }

        int256 reward;
        int256 minReward = _minLiquidationReward;
        int256 maxReward = _maxLiquidationReward;
        if (netEquity <= minReward) {
            reward = minReward;
        } else if (netEquity >= maxReward) {
            reward = maxReward;
        } else {
            reward = ((netEquity - minReward) * _liquidationCutRatio / ONE + minReward).reformat(_decimals0);
        }

        (int256 totalDynamicEquity, int256[] memory dynamicEquities) = _getBTokenDynamicEquities(blength);
        _distributePnlToBTokens(netEquity - reward, totalDynamicEquity, dynamicEquities, blength);

        pToken.burn(owner);
        IERC20(_bTokens[0].bTokenAddress).safeTransfer(liquidator, reward.itou().rescale(18, _decimals0));

        emit Liquidate(owner, liquidator, reward.itou());
    }


    //================================================================================
    // Helpers
    //================================================================================

    // update bTokens/symbols prices
    // distribute pnl to bTokens, which is generated since last update, including pnl and funding fees for opening positions
    // by calling this function at the beginning of each block, all LP/Traders status are settled
    function _updatePricesAndDistributePnl(uint256 blength, uint256 slength) internal {
        uint256 blocknumber = block.number;
        if (blocknumber > _lastUpdateBlock) {
            (int256 totalDynamicEquity, int256[] memory dynamicEquities) = _getBTokenDynamicEquities(blength);
            int256 undistributedPnl = _updateSymbolPrices(totalDynamicEquity, slength);
            _distributePnlToBTokens(undistributedPnl, totalDynamicEquity, dynamicEquities, blength);
            _lastUpdateBlock = blocknumber;
        }
    }

    function _updateAllBTokenPrices(uint256 blength) internal {
        for (uint256 i = 1; i < blength; i++) {
            _bTokens[i].price = IOracle(_bTokens[i].oracleAddress).getPrice().utoi();
        }
    }

    function _updateBTokenPrice(uint256 bTokenId) internal {
        if (bTokenId != 0) _bTokens[bTokenId].price = IOracle(_bTokens[bTokenId].oracleAddress).getPrice().utoi();
    }

    function _getBTokenDynamicEquities(uint256 blength) internal view returns (int256, int256[] memory) {
        int256 totalDynamicEquity;
        int256[] memory dynamicEquities = new int256[](blength);
        for (uint256 i = 0; i < blength; i++) {
            BTokenInfo storage b = _bTokens[i];
            int256 liquidity = b.liquidity;
            // dynamic equities for bTokens are discounted
            int256 equity = liquidity * b.price / ONE * b.discount / ONE + b.pnl;
            if (liquidity > 0 && equity > 0) {
                totalDynamicEquity += equity;
                dynamicEquities[i] = equity;
            }
        }
        return (totalDynamicEquity, dynamicEquities);
    }

    function _distributePnlToBTokens(int256 pnl, int256 totalDynamicEquity, int256[] memory dynamicEquities, uint256 blength) internal {
        if (totalDynamicEquity > 0 && pnl != 0) {
            for (uint256 i = 0; i < blength; i++) {
                if (dynamicEquities[i] > 0) {
                    BTokenInfo storage b = _bTokens[i];
                    int256 distributedPnl = pnl * dynamicEquities[i] / totalDynamicEquity;
                    b.pnl += distributedPnl;
                    // cumulativePnl is as in per liquidity, thus b.liquidity in denominator
                    b.cumulativePnl += distributedPnl * ONE / b.liquidity;
                }
            }
        }
    }

    // update symbol prices and calculate funding and unrealized pnl for all positions since last call
    // the returned undistributedPnl will be distributed and shared by all LPs
    //
    //                 tradersNetVolume * price * multiplier
    // ratePerBlock = --------------------------------------- * price * multiplier * fundingRateCoefficient
    //                         totalDynamicEquity
    //
    function _updateSymbolPrices(int256 totalDynamicEquity, uint256 slength) internal returns (int256) {
        if (totalDynamicEquity <= 0) return 0;
        int256 undistributedPnl;
        for (uint256 i = 0; i < slength; i++) {
            SymbolInfo storage s = _symbols[i];
            int256 price = IOracle(s.oracleAddress).getPrice().utoi();
            int256 tradersNetVolume = s.tradersNetVolume;
            if (tradersNetVolume != 0) {
                int256 multiplier = s.multiplier;
                int256 ratePerBlock = tradersNetVolume * price / ONE * price / ONE * multiplier / ONE * multiplier / ONE * s.fundingRateCoefficient / totalDynamicEquity;
                int256 delta = ratePerBlock * int256(block.number - _lastUpdateBlock);

                undistributedPnl += tradersNetVolume * delta / ONE;
                undistributedPnl -= tradersNetVolume * (price - s.price) / ONE * multiplier / ONE;

                unchecked { s.cumulativeFundingRate += delta; }
            }
            s.price = price;
        }
        return undistributedPnl;
    }

    function _getBToken0Ratio(int256 totalDynamicEquity, int256[] memory dynamicEquities) internal pure returns (int256) {
        return totalDynamicEquity == 0 ? type(int256).max : dynamicEquities[0] * ONE / totalDynamicEquity;
    }

    function _getPoolMarginRatio(int256 totalDynamicEquity, uint256 slength) internal view returns (int256) {
        int256 totalCost;
        for (uint256 i = 0; i < slength; i++) {
            SymbolInfo storage s = _symbols[i];
            int256 tradersNetVolume = s.tradersNetVolume;
            if (tradersNetVolume != 0) {
                int256 cost = tradersNetVolume * s.price / ONE * s.multiplier / ONE;
                totalDynamicEquity -= cost - s.tradersNetCost;
                totalCost += cost.abs(); // netting costs cross symbols is forbidden
            }
        }
        return totalCost == 0 ? type(int256).max : totalDynamicEquity * ONE / totalCost;
    }

    // setting funding fee on trader's side
    // this funding fee is already settled to bTokens in `_update`, thus distribution is not needed
    function _settleTraderFundingFee(address owner, uint256 slength) internal {
        IPToken pToken = IPToken(_pTokenAddress);
        int256 funding;
        IPToken.Position[] memory positions = pToken.getPositions(owner);
        for (uint256 i = 0; i < slength; i++) {
            IPToken.Position memory p = positions[i];
            if (p.volume != 0) {
                int256 cumulativeFundingRate = _symbols[i].cumulativeFundingRate;
                int256 delta;
                unchecked { delta = cumulativeFundingRate - p.lastCumulativeFundingRate; }
                funding += p.volume * delta / ONE;

                p.lastCumulativeFundingRate = cumulativeFundingRate;
                pToken.updatePosition(owner, i, p);
            }
        }
        if (funding != 0) {
            int256 margin = pToken.getMargin(owner, 0) - funding;
            pToken.updateMargin(owner, 0, margin);
        }
    }

    function _coverTraderDebt(address owner, uint256 blength) internal {
        IPToken pToken = IPToken(_pTokenAddress);
        int256[] memory margins = pToken.getMargins(owner);
        if (margins[0] < 0) {
            uint256 amountB0;
            uint256 amountBX;
            for (uint256 i = blength - 1; i > 0; i--) {
                if (margins[i] > 0) {
                    (amountB0, amountBX) = IBTokenSwapper(_bTokens[i].swapperAddress).swapBXForExactB0(
                        (-margins[0]).ceil(_decimals0).itou(), margins[i].itou(), _bTokens[i].price.itou()
                    );
                    margins[0] += amountB0.utoi();
                    margins[i] -= amountBX.utoi();
                }
                if (margins[0] >= 0) break;
            }
            pToken.updateMargins(owner, margins);
        }
    }

    function _getTraderMarginRatio(address owner, uint256 blength, uint256 slength) internal view returns (int256) {
        IPToken pToken = IPToken(_pTokenAddress);

        int256[] memory margins = pToken.getMargins(owner);
        int256 totalDynamicEquity = margins[0];
        int256 totalCost;
        for (uint256 i = 1; i < blength; i++) {
            totalDynamicEquity += margins[i] * _bTokens[i].price / ONE * _bTokens[i].discount / ONE;
        }

        IPToken.Position[] memory positions = pToken.getPositions(owner);
        for (uint256 i = 0; i < slength; i++) {
            if (positions[i].volume != 0) {
                int256 cost = positions[i].volume * _symbols[i].price / ONE * _symbols[i].multiplier / ONE;
                totalDynamicEquity += cost - positions[i].cost;
                totalCost += cost.abs(); // netting costs cross symbols is forbidden
            }
        }

        return totalCost == 0 ? type(int256).max : totalDynamicEquity * ONE / totalCost;
    }

    function _deflationCompatibleSafeTransferFrom(address bTokenAddress, uint256 decimals, address from, address to, uint256 bAmount)
        internal returns (uint256)
    {
        IERC20 token = IERC20(bTokenAddress);

        uint256 balance1 = token.balanceOf(to);
        token.safeTransferFrom(from, to, bAmount.rescale(18, decimals));
        uint256 balance2 = token.balanceOf(to);

        return (balance2 - balance1).rescale(decimals, 18);
    }

}

File 2 of 12: Address.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

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

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

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

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 3 of 12: IBTokenSwapper.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

interface IBTokenSwapper {

    function swapExactB0ForBX(uint256 amountB0, uint256 referencePrice) external returns (uint256 resultB0, uint256 resultBX);

    function swapExactBXForB0(uint256 amountBX, uint256 referencePrice) external returns (uint256 resultB0, uint256 resultBX);

    function swapB0ForExactBX(uint256 amountB0, uint256 amountBX, uint256 referencePrice) external returns (uint256 resultB0, uint256 resultBX);

    function swapBXForExactB0(uint256 amountB0, uint256 amountBX, uint256 referencePrice) external returns (uint256 resultB0, uint256 resultBX);

    function getLimitBX() external view returns (uint256);

    function sync() external;

}

File 4 of 12: IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

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

File 5 of 12: IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

interface IERC20 {

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    event Transfer(address indexed from, address indexed to, uint256 amount);

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

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

    function decimals() external view returns (uint8);

    function totalSupply() external view returns (uint256);

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

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

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

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

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

}

File 6 of 12: IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

import "./IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `operator` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed operator, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in `owner`'s account.
     */
    function balanceOf(address owner) external view returns (uint256);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address);

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Gives permission to `operator` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address
     * clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address operator, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     *   by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first
     * that contract recipients are aware of the ERC721 protocol to prevent
     * tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token
     *   by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement
     *   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     *   by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement
     *   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}

File 7 of 12: ILToken.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

import './IERC721.sol';

interface ILToken is IERC721 {

    struct Asset {
        // amount of base token lp provided, i.e. WETH
        // this will be used as the weight to distribute future pnls
        int256 liquidity;
        // lp's pnl in bToken0
        int256 pnl;
        // snapshot of cumulativePnl for lp at last settlement point (add/remove liquidity), in bToken0, i.e. USDT
        int256 lastCumulativePnl;
    }

    event UpdateAsset(
        address owner,
        uint256 bTokenId,
        int256  liquidity,
        int256  pnl,
        int256  lastCumulativePnl
    );

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

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

    function pool() external view returns (address);

    function totalMinted() external view returns (uint256);

    function totalSupply() external view returns (uint256);

    function numBTokens() external view returns (uint256);

    function setPool(address newPool) external;

    function setNumBTokens(uint256 num) external;

    function exists(address owner) external view returns (bool);

    function getAsset(address owner, uint256 bTokenId) external view returns (Asset memory);

    function getAssets(address owner) external view returns (Asset[] memory);

    function updateAsset(address owner, uint256 bTokenId, Asset memory asset) external;

    function mint(address owner) external;

    function burn(address owner) external;

}

File 8 of 12: IOracle.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

interface IOracle {

    function getPrice() external returns (uint256);

}

File 9 of 12: IPerpetualPool.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

interface IPerpetualPool {

    struct BTokenInfo {
        address bTokenAddress;
        address swapperAddress;
        address oracleAddress;
        uint256 decimals;
        int256  discount;
        int256  price;
        int256  liquidity;
        int256  pnl;
        int256  cumulativePnl;
    }

    struct SymbolInfo {
        string  symbol;
        address oracleAddress;
        int256  multiplier;
        int256  feeRatio;
        int256  fundingRateCoefficient;
        int256  price;
        int256  cumulativeFundingRate;
        int256  tradersNetVolume;
        int256  tradersNetCost;
    }

    event AddLiquidity(address indexed owner, uint256 indexed bTokenId, uint256 bAmount);

    event RemoveLiquidity(address indexed owner, uint256 indexed bTokenId, uint256 bAmount);

    event AddMargin(address indexed owner, uint256 indexed bTokenId, uint256 bAmount);

    event RemoveMargin(address indexed owner, uint256 indexed bTokenId, uint256 bAmount);

    event Trade(address indexed owner, uint256 indexed symbolId, int256 tradeVolume, uint256 price);

    event Liquidate(address indexed owner, address indexed liquidator, uint256 reward);

    event ProtocolFeeCollection(address indexed collector, uint256 amount);

    function getParameters() external view returns (
        uint256 decimals0,
        int256  minBToken0Ratio,
        int256  minPoolMarginRatio,
        int256  minInitialMarginRatio,
        int256  minMaintenanceMarginRatio,
        int256  minLiquidationReward,
        int256  maxLiquidationReward,
        int256  liquidationCutRatio,
        int256  protocolFeeCollectRatio
    );

    function getAddresses() external view returns (
        address lTokenAddress,
        address pTokenAddress,
        address routerAddress,
        address protocolFeeCollector
    );

    function getLengths() external view returns (uint256, uint256);

    function getBToken(uint256 bTokenId) external view returns (BTokenInfo memory);

    function getSymbol(uint256 symbolId) external view returns (SymbolInfo memory);

    function getBTokenOracle(uint256 bTokenId) external view returns (address);

    function getSymbolOracle(uint256 symbolId) external view returns (address);

    function getProtocolFeeAccrued() external view returns (int256);

    function collectProtocolFee() external;

    function addBToken(BTokenInfo memory info) external;

    function addSymbol(SymbolInfo memory info) external;

    function setBTokenParameters(uint256 bTokenId, address swapperAddress, address oracleAddress, uint256 discount) external;

    function setSymbolParameters(uint256 symbolId, address oracleAddress, uint256 feeRatio, uint256 fundingRateCoefficient) external;

    function approvePoolMigration(address targetPool) external;

    function executePoolMigration(address sourcePool) external;

    function addLiquidity(address owner, uint256 bTokenId, uint256 bAmount, uint256 blength, uint256 slength) external;

    function removeLiquidity(address owner, uint256 bTokenId, uint256 bAmount, uint256 blength, uint256 slength) external;

    function addMargin(address owner, uint256 bTokenId, uint256 bAmount) external;

    function removeMargin(address owner, uint256 bTokenId, uint256 bAmount, uint256 blength, uint256 slength) external;

    function trade(address owner, uint256 symbolId, int256 tradeVolume, uint256 blength, uint256 slength) external;

    function liquidate(address liquidator, address owner, uint256 blength, uint256 slength) external;

}

File 10 of 12: IPToken.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

import './IERC721.sol';

interface IPToken is IERC721 {

    struct Position {
        // position volume, long is positive and short is negative
        int256 volume;
        // the cost the establish this position
        int256 cost;
        // the last cumulativeFundingRate since last funding settlement for this position
        // the overflow for this value in intended
        int256 lastCumulativeFundingRate;
    }

    event UpdateMargin(address indexed owner, uint256 indexed bTokenId, int256 amount);

    event UpdatePosition(address indexed owner, uint256 indexed symbolId, int256 volume, int256 cost, int256 lastCumulativeFundingRate);

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

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

    function pool() external view returns (address);

    function totalMinted() external view returns (uint256);

    function totalSupply() external view returns (uint256);

    function numBTokens() external view returns (uint256);

    function numSymbols() external view returns (uint256);

    function setPool(address newPool) external;

    function setNumBTokens(uint256 num) external;

    function setNumSymbols(uint256 num) external;

    function exists(address owner) external view returns (bool);

    function getMargin(address owner, uint256 bTokenId) external view returns (int256);

    function getMargins(address owner) external view returns (int256[] memory);

    function getPosition(address owner, uint256 symbolId) external view returns (Position memory);

    function getPositions(address owner) external view returns (Position[] memory);

    function updateMargin(address owner, uint256 bTokenId, int256 amount) external;

    function updateMargins(address owner, int256[] memory margins) external;

    function updatePosition(address owner, uint256 symbolId, Position memory position) external;

    function mint(address owner) external;

    function burn(address owner) external;

}

File 11 of 12: SafeERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

import "./IERC20.sol";
import "./Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {

    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender) - value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 12 of 12: SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

library SafeMath {

    uint256 constant UMAX = 2**255 - 1;
    int256  constant IMIN = -2**255;

    /// convert uint256 to int256
    function utoi(uint256 a) internal pure returns (int256) {
        require(a <= UMAX, 'UIO');
        return int256(a);
    }

    /// convert int256 to uint256
    function itou(int256 a) internal pure returns (uint256) {
        require(a >= 0, 'IUO');
        return uint256(a);
    }

    /// take abs of int256
    function abs(int256 a) internal pure returns (int256) {
        require(a != IMIN, 'AO');
        return a >= 0 ? a : -a;
    }


    /// rescale a uint256 from base 10**decimals1 to 10**decimals2
    function rescale(uint256 a, uint256 decimals1, uint256 decimals2) internal pure returns (uint256) {
        return decimals1 == decimals2 ? a : a * (10 ** decimals2) / (10 ** decimals1);
    }

    /// rescale a int256 from base 10**decimals1 to 10**decimals2
    function rescale(int256 a, uint256 decimals1, uint256 decimals2) internal pure returns (int256) {
        return decimals1 == decimals2 ? a : a * utoi(10 ** decimals2) / utoi(10 ** decimals1);
    }

    /// reformat a uint256 to be a valid 10**decimals base value
    /// the reformatted value is still in 10**18 base
    function reformat(uint256 a, uint256 decimals) internal pure returns (uint256) {
        return decimals == 18 ? a : rescale(rescale(a, 18, decimals), decimals, 18);
    }

    /// reformat a int256 to be a valid 10**decimals base value
    /// the reformatted value is still in 10**18 base
    function reformat(int256 a, uint256 decimals) internal pure returns (int256) {
        return decimals == 18 ? a : rescale(rescale(a, 18, decimals), decimals, 18);
    }

    /// ceiling value away from zero, return a valid 10**decimals base value, but still in 10**18 based
    function ceil(int256 a, uint256 decimals) internal pure returns (int256) {
        if (reformat(a, decimals) == a) {
            return a;
        } else {
            int256 b = rescale(a, 18, decimals);
            b += a > 0 ? int256(1) : int256(-1);
            return rescale(b, decimals, 18);
        }
    }

}

Contract ABI

[{"inputs":[{"internalType":"uint256[9]","name":"parameters","type":"uint256[9]"},{"internalType":"address[4]","name":"addresses","type":"address[4]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"bTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bAmount","type":"uint256"}],"name":"AddLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"bTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bAmount","type":"uint256"}],"name":"AddMargin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"liquidator","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"Liquidate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collector","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ProtocolFeeCollection","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"bTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bAmount","type":"uint256"}],"name":"RemoveLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"bTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bAmount","type":"uint256"}],"name":"RemoveMargin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"symbolId","type":"uint256"},{"indexed":false,"internalType":"int256","name":"tradeVolume","type":"int256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"Trade","type":"event"},{"inputs":[{"components":[{"internalType":"address","name":"bTokenAddress","type":"address"},{"internalType":"address","name":"swapperAddress","type":"address"},{"internalType":"address","name":"oracleAddress","type":"address"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"int256","name":"discount","type":"int256"},{"internalType":"int256","name":"price","type":"int256"},{"internalType":"int256","name":"liquidity","type":"int256"},{"internalType":"int256","name":"pnl","type":"int256"},{"internalType":"int256","name":"cumulativePnl","type":"int256"}],"internalType":"struct IPerpetualPool.BTokenInfo","name":"info","type":"tuple"}],"name":"addBToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"bTokenId","type":"uint256"},{"internalType":"uint256","name":"bAmount","type":"uint256"},{"internalType":"uint256","name":"blength","type":"uint256"},{"internalType":"uint256","name":"slength","type":"uint256"}],"name":"addLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"bTokenId","type":"uint256"},{"internalType":"uint256","name":"bAmount","type":"uint256"}],"name":"addMargin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"oracleAddress","type":"address"},{"internalType":"int256","name":"multiplier","type":"int256"},{"internalType":"int256","name":"feeRatio","type":"int256"},{"internalType":"int256","name":"fundingRateCoefficient","type":"int256"},{"internalType":"int256","name":"price","type":"int256"},{"internalType":"int256","name":"cumulativeFundingRate","type":"int256"},{"internalType":"int256","name":"tradersNetVolume","type":"int256"},{"internalType":"int256","name":"tradersNetCost","type":"int256"}],"internalType":"struct IPerpetualPool.SymbolInfo","name":"info","type":"tuple"}],"name":"addSymbol","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"targetPool","type":"address"}],"name":"approvePoolMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectProtocolFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sourcePool","type":"address"}],"name":"executePoolMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAddresses","outputs":[{"internalType":"address","name":"lTokenAddress","type":"address"},{"internalType":"address","name":"pTokenAddress","type":"address"},{"internalType":"address","name":"routerAddress","type":"address"},{"internalType":"address","name":"protocolFeeCollector","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"bTokenId","type":"uint256"}],"name":"getBToken","outputs":[{"components":[{"internalType":"address","name":"bTokenAddress","type":"address"},{"internalType":"address","name":"swapperAddress","type":"address"},{"internalType":"address","name":"oracleAddress","type":"address"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"int256","name":"discount","type":"int256"},{"internalType":"int256","name":"price","type":"int256"},{"internalType":"int256","name":"liquidity","type":"int256"},{"internalType":"int256","name":"pnl","type":"int256"},{"internalType":"int256","name":"cumulativePnl","type":"int256"}],"internalType":"struct IPerpetualPool.BTokenInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"bTokenId","type":"uint256"}],"name":"getBTokenOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLengths","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getParameters","outputs":[{"internalType":"uint256","name":"decimals0","type":"uint256"},{"internalType":"int256","name":"minBToken0Ratio","type":"int256"},{"internalType":"int256","name":"minPoolMarginRatio","type":"int256"},{"internalType":"int256","name":"minInitialMarginRatio","type":"int256"},{"internalType":"int256","name":"minMaintenanceMarginRatio","type":"int256"},{"internalType":"int256","name":"minLiquidationReward","type":"int256"},{"internalType":"int256","name":"maxLiquidationReward","type":"int256"},{"internalType":"int256","name":"liquidationCutRatio","type":"int256"},{"internalType":"int256","name":"protocolFeeCollectRatio","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProtocolFeeAccrued","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"symbolId","type":"uint256"}],"name":"getSymbol","outputs":[{"components":[{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"oracleAddress","type":"address"},{"internalType":"int256","name":"multiplier","type":"int256"},{"internalType":"int256","name":"feeRatio","type":"int256"},{"internalType":"int256","name":"fundingRateCoefficient","type":"int256"},{"internalType":"int256","name":"price","type":"int256"},{"internalType":"int256","name":"cumulativeFundingRate","type":"int256"},{"internalType":"int256","name":"tradersNetVolume","type":"int256"},{"internalType":"int256","name":"tradersNetCost","type":"int256"}],"internalType":"struct IPerpetualPool.SymbolInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"symbolId","type":"uint256"}],"name":"getSymbolOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"liquidator","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"blength","type":"uint256"},{"internalType":"uint256","name":"slength","type":"uint256"}],"name":"liquidate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"bTokenId","type":"uint256"},{"internalType":"uint256","name":"bAmount","type":"uint256"},{"internalType":"uint256","name":"blength","type":"uint256"},{"internalType":"uint256","name":"slength","type":"uint256"}],"name":"removeLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"bTokenId","type":"uint256"},{"internalType":"uint256","name":"bAmount","type":"uint256"},{"internalType":"uint256","name":"blength","type":"uint256"},{"internalType":"uint256","name":"slength","type":"uint256"}],"name":"removeMargin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"bTokenId","type":"uint256"},{"internalType":"address","name":"swapperAddress","type":"address"},{"internalType":"address","name":"oracleAddress","type":"address"},{"internalType":"uint256","name":"discount","type":"uint256"}],"name":"setBTokenParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"symbolId","type":"uint256"},{"internalType":"address","name":"oracleAddress","type":"address"},{"internalType":"uint256","name":"feeRatio","type":"uint256"},{"internalType":"uint256","name":"fundingRateCoefficient","type":"uint256"}],"name":"setSymbolParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"symbolId","type":"uint256"},{"internalType":"int256","name":"tradeVolume","type":"int256"},{"internalType":"uint256","name":"blength","type":"uint256"},{"internalType":"uint256","name":"slength","type":"uint256"}],"name":"trade","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6102206040523480156200001257600080fd5b5060405162005ef838038062005ef88339810160408190526200003591620000c3565b8151608090815260208084015160a090815260408086015160c090815260608088015160e0908152958801516101009081529388015161012052908701516101405293860151610160529401516101805282516001600160601b031990831b81166101a05290830151821b81166101c05292820151811b83166101e05290810151901b16610200526200020e565b6000806101a0808486031215620000d8578283fd5b84601f850112620000e7578283fd5b620000f1620001a5565b808561012087018881111562000105578687fd5b865b60098110156200012857825185526020948501949092019160010162000107565b508296508861013f8901126200013c578586fd5b62000146620001dd565b935083925090508684018810156200015c578485fd5b8493505b6004841015620001975780516001600160a01b038116811462000181578586fd5b8352600193909301926020928301920162000160565b508093505050509250929050565b60405161012081016001600160401b0381118282101715620001d757634e487b7160e01b600052604160045260246000fd5b60405290565b604051608081016001600160401b0381118282101715620001d757634e487b7160e01b600052604160045260246000fd5b60805160a05160c05160e05161010051610120516101405161016051610180516101a05160601c6101c05160601c6101e05160601c6102005160601c615ac762000431600039600081816102d9015281816130ff015261312e0152600081816102af0152818161054201528181610c5501528181610ce6015281816111960152818161184701528181611cae01528181611e0701528181611f7401528181612462015281816125bf015281816131bb01526134f201526000818161028701528181610d6201528181611274015281816114d8015281816115da01528181611c3901528181611dcb01528181612563015281816126d20152818161324a01528181613c55015281816140b401526146b30152600081816102620152818161062801528181611bc501528181611d520152611ff001526000818161043e015261169e0152600081816104180152612c890152600081816103f20152612c1c0152600081816103cc0152612bfb0152600081816103a6015261264b01526000818161038001528181611784015261342001526000818161035801528181610b69015261171d015260008181610332015261239601526000818161030f0152818161071001528181610747015281816107e4015281816109e501528181611984015281816122260152818161227f01528181612c5e01528181612d6501528181612f86015281816130b30152818161317501528181613362015261480d0152615ac76000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c80638ed1fc8f116100b8578063c13425741161007c578063c13425741461047f578063c41e575f14610492578063caa4b46a146104b2578063cfb3e041146104ba578063d608c07d146104cd578063e7f2ee6e146104de57600080fd5b80638ed1fc8f1461022e5780639144b6da14610241578063a39fac1214610254578063a5ea11da14610309578063b50ac1cb1461046c57600080fd5b80636418413c116100ff5780636418413c146101ba57806367d4dcd0146101da57806373186e31146101ed5780637b7acb2314610200578063800bd5c81461021357600080fd5b80630888b15f1461013c578063139280821461016c57806341746d631461018157806341df76021461019457806345103f74146101a7575b600080fd5b61014f61014a3660046153a7565b6104f1565b6040516001600160a01b0390911681526020015b60405180910390f35b61017f61017a3660046150b1565b610537565b005b61017f61018f366004614fe3565b610c4a565b61014f6101a23660046153a7565b610c95565b61017f6101b536600461507f565b610cdb565b6101cd6101c83660046153a7565b611005565b6040516101639190615627565b61017f6101e836600461503e565b61118b565b61017f6101fb366004615251565b61183c565b61017f61020e366004614fe3565b611ca3565b60025460035460408051928352602083019190915201610163565b61017f61023c3660046153bf565b611dfc565b61017f61024f3660046150b1565b611f69565b604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811682527f0000000000000000000000000000000000000000000000000000000000000000811660208301527f00000000000000000000000000000000000000000000000000000000000000008116928201929092527f0000000000000000000000000000000000000000000000000000000000000000919091166060820152608001610163565b604080517f000000000000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201527f000000000000000000000000000000000000000000000000000000000000000060808201527f000000000000000000000000000000000000000000000000000000000000000060a08201527f000000000000000000000000000000000000000000000000000000000000000060c08201527f000000000000000000000000000000000000000000000000000000000000000060e08201527f000000000000000000000000000000000000000000000000000000000000000061010082015261012001610163565b61017f61047a3660046152e0565b612457565b61017f61048d366004614ffd565b6125b4565b6104a56104a03660046153a7565b612e23565b604051610163919061559a565b61017f612f39565b61017f6104c83660046150b1565b6131b0565b600154604051908152602001610163565b61017f6104ec366004615402565b6134e7565b60006002828154811061051457634e487b7160e01b600052603260045260246000fd5b60009182526020909120600260099092020101546001600160a01b031692915050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105885760405162461bcd60e51b815260040161057f90615554565b60405180910390fd5b60045460ff16156105ab5760405162461bcd60e51b815260040161057f90615579565b6004805460ff191660011790556105c184613597565b6105cb8282613659565b6000600285815481106105ee57634e487b7160e01b600052603260045260246000fd5b60009182526020822060405163dfd01ff360e01b81526001600160a01b038a81166004830152602482018a905260099390930290910193507f0000000000000000000000000000000000000000000000000000000000000000929183169063dfd01ff39060440160606040518083038186803b15801561066d57600080fd5b505afa158015610681573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a59190615236565b60038401549091506106b7878261369d565b600885015490975060006106ca896136ce565b90506000670de0b6b3a764000085600001518660400151856106ec9190615946565b6106f691906158a4565b6107009190615777565b90506000808c61079157610734837f0000000000000000000000000000000000000000000000000000000000000000613711565b915061073f83615a35565b905061076b837f0000000000000000000000000000000000000000000000000000000000000000613711565b6107759084615946565b600160008282546107869190615736565b90915550610a379050565b82876020018181516107a39190615736565b9052506020870151600013156108f9576000808a60010160009054906101000a90046001600160a01b03166001600160a01b031663d1e7f49b61081c6108177f00000000000000000000000000000000000000000000000000000000000000008d6020015161081190615a35565b90613732565b61378f565b8b516108279061378f565b6108348f6005015461378f565b6040516001600160e01b031960e086901b1681526004810193909352602483019190915260448201526064016040805180830381600087803b15801561087957600080fd5b505af115801561088d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b19190615427565b915091506108be816136ce565b6108c790615a35565b93506108d2826136ce565b92506108dd826136ce565b896020018181516108ee9190615736565b905250610a37915050565b6000876020015113801561090e575086518412155b15610a3757600189015460208801516000916001600160a01b03169063ce71bad5906109399061378f565b6109468d6005015461378f565b6040516001600160e01b031960e085901b168152600481019290925260248201526044016040805180830381600087803b15801561098357600080fd5b505af1158015610997573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bb9190615427565b9150506109c7816136ce565b925087602001516109d790615a35565b6020890151909250610a09907f0000000000000000000000000000000000000000000000000000000000000000613711565b8860200151610a189190615946565b60016000828254610a299190615736565b909155505060006020890152505b60408701859052865184121580610a5a57508651610a56908390615736565b8412155b15610a98578651610a7090610817908490615736565b9b508660000151896006016000828254610a8a9190615946565b909155505060008752610ad7565b610aa28483615946565b87518890610ab1908390615736565b905250610abe8483615946565b896006016000828254610ad19190615736565b90915550505b80896007016000828254610aeb9190615736565b92505081905550876001600160a01b0316637f3a67028f8f8a6040518463ffffffff1660e01b8152600401610b2293929190615509565b600060405180830381600087803b158015610b3c57600080fd5b505af1158015610b50573d6000803e3d6000fd5b5050505050505050506000610b64876137c7565b5090507f0000000000000000000000000000000000000000000000000000000000000000610b928288613930565b1215610bce5760405162461bcd60e51b815260206004820152600b60248201526a696e7375662774206c697160a81b604482015260640161057f565b610bf08a610bde8a601286613a4d565b87546001600160a01b03169190613a91565b888a6001600160a01b03167f0fbf06c058b90cb038a618f8c2acbf6145f8b3570fd1fa56abb8f0f3f05b36e88a604051610c2c91815260200190565b60405180910390a350506004805460ff191690555050505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c925760405162461bcd60e51b815260040161057f90615554565b50565b600060038281548110610cb857634e487b7160e01b600052603260045260246000fd5b60009182526020909120600160099092020101546001600160a01b031692915050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610d235760405162461bcd60e51b815260040161057f90615554565b60045460ff1615610d465760405162461bcd60e51b815260040161057f90615579565b6004805460ff19166001178155604051637b51e92760e11b81527f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0383169163f6a3d24e91610dae918891016001600160a01b0391909116815260200190565b60206040518083038186803b158015610dc657600080fd5b505afa158015610dda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfe91906151fe565b610e5e576040516335313c2160e11b81526001600160a01b038581166004830152821690636a62784290602401600060405180830381600087803b158015610e4557600080fd5b505af1158015610e59573d6000803e3d6000fd5b505050505b600060028481548110610e8157634e487b7160e01b600052603260045260246000fd5b6000918252602090912060099091020180546003820154919250610eb3916001600160a01b0390911690873087613af4565b92506000610ec0846136ce565b60405163b798de4760e01b81526001600160a01b0388811660048301526024820188905285169063b798de479060440160206040518083038186803b158015610f0857600080fd5b505afa158015610f1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f40919061521e565b610f4a9190615736565b60405163e65953e760e01b81529091506001600160a01b0384169063e65953e790610f7d908990899086906004016154e8565b600060405180830381600087803b158015610f9757600080fd5b505af1158015610fab573d6000803e3d6000fd5b5050505084866001600160a01b03167f9cc399fa404f91eac92b04a85d70fb4c74a04e6a0edb912c6f3abe228cb50c7886604051610feb91815260200190565b60405180910390a350506004805460ff1916905550505050565b61105d6040518061012001604052806060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6003828154811061107e57634e487b7160e01b600052603260045260246000fd5b9060005260206000209060090201604051806101200160405290816000820180546110a8906159df565b80601f01602080910402602001604051908101604052809291908181526020018280546110d4906159df565b80156111215780601f106110f657610100808354040283529160200191611121565b820191906000526020600020905b81548152906001019060200180831161110457829003601f168201915b505050918352505060018201546001600160a01b03166020820152600282015460408201526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e08201526008909101546101009091015292915050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146111d35760405162461bcd60e51b815260040161057f90615554565b60045460ff16156111f65760405162461bcd60e51b815260040161057f90615579565b6004805460ff1916600117905561120d8282613659565b6112178582613c36565b60006003858154811061123a57634e487b7160e01b600052603260045260246000fd5b600091825260208220604051633adbb5af60e01b81526001600160a01b038a81166004830152602482018a905260099390930290910193507f000000000000000000000000000000000000000000000000000000000000000090911690633adbb5af9060440160606040518083038186803b1580156112b857600080fd5b505afa1580156112cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f09190615236565b905061131d6040518060800160405280600081526020016000815260200160008152602001600081525090565b611328866000613711565b9550670de0b6b3a76400008360020154670de0b6b3a764000085600501548961135191906158a4565b61135b9190615777565b61136591906158a4565b61136f9190615777565b8082526003840154670de0b6b3a76400009161138a90613f14565b61139491906158a4565b61139e9190615777565b602082015281516000138015906113b6575060008612155b1580156113d3575081516000128015906113d1575060008613155b155b156114605760006113e78360000151613f14565b905060006113f488613f14565b905080821361142f576020840151835182906114119085906158a4565b61141b9190615777565b6114259190615736565b604084015261145d565b8251602085015183906114439084906158a4565b61144d9190615777565b6114579190615736565b60408401525b50505b85826000018181516114729190615736565b905250604081015181516114869190615946565b826020018181516114979190615736565b9052506006830154604083810191909152818101516020830151915163b798de4760e01b81526001600160a01b038b811660048301526000602483018190527f00000000000000000000000000000000000000000000000000000000000000009091169363e65953e7938d93909190869063b798de479060440160206040518083038186803b15801561152957600080fd5b505afa15801561153d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611561919061521e565b61156b9190615946565b6115759190615946565b6040518463ffffffff1660e01b8152600401611593939291906154e8565b600060405180830381600087803b1580156115ad57600080fd5b505af11580156115c1573d6000803e3d6000fd5b505060405163f733fed760e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016925063f733fed79150611615908b908b908790600401615509565b600060405180830381600087803b15801561162f57600080fd5b505af1158015611643573d6000803e3d6000fd5b505050508583600701600082825461165b9190615736565b9091555050604081015181516116719190615946565b8360080160008282546116849190615736565b90915550506020810151670de0b6b3a7640000906116c3907f0000000000000000000000000000000000000000000000000000000000000000906158a4565b6116cd9190615777565b60608201819052600180546000906116e6908490615736565b9091555060009050806116f8876137c7565b9150915061171b836060015184602001516117139190615946565b83838a613f61565b7f00000000000000000000000000000000000000000000000000000000000000006117468388613930565b12156117825760405162461bcd60e51b815260206004820152600b60248201526a696e7375662774206c697160a81b604482015260640161057f565b7f00000000000000000000000000000000000000000000000000000000000000006117ae8b8989614092565b12156117ed5760405162461bcd60e51b815260206004820152600e60248201526d34b739bab313ba1036b0b933b4b760911b604482015260640161057f565b888a6001600160a01b03167fafa6e0e09d86154337d4461488269397cc1ca7b75db98a37ec57735846064f478a611827896005015461378f565b60408051928352602083019190915201610c2c565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146118845760405162461bcd60e51b815260040161057f90615554565b60025415611982576118da816020015160001960026000815481106118b957634e487b7160e01b600052603260045260246000fd5b60009182526020909120600990910201546001600160a01b03169190614498565b602081015181516118f9916001600160a01b0390911690600019614498565b61197881604001516001600160a01b03166398d5fdca6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561193b57600080fd5b505af115801561194f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611973919061521e565b6136ce565b60a08201526119f0565b7f00000000000000000000000000000000000000000000000000000000000000008160600151146119e15760405162461bcd60e51b815260206004820152600960248201526877726f6e672064656360b81b604482015260640161057f565b670de0b6b3a764000060a08201525b600280546001810182556000829052825160099091027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace810180546001600160a01b039384166001600160a01b03199182161790915560208501517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf830180549185169183169190911790556040808601517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad084018054918616919093161790915560608501517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad183015560808501517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad283015560a08501517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad383015560c08501517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad483015560e08501517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad58301556101008501517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad690920191909155915491516352c13d1760e01b815260048101929092527f000000000000000000000000000000000000000000000000000000000000000016906352c13d1790602401600060405180830381600087803b158015611c0957600080fd5b505af1158015611c1d573d6000803e3d6000fd5b50506002546040516352c13d1760e01b815260048101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692506352c13d1791506024015b600060405180830381600087803b158015611c8857600080fd5b505af1158015611c9c573d6000803e3d6000fd5b5050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611ceb5760405162461bcd60e51b815260040161057f90615554565b60005b600254811015611d3257611d2082600019600284815481106118b957634e487b7160e01b600052603260045260246000fd5b80611d2a81615a1a565b915050611cee565b5060405163221b8a9560e11b81526001600160a01b0382811660048301527f00000000000000000000000000000000000000000000000000000000000000001690634437152a90602401600060405180830381600087803b158015611d9657600080fd5b505af1158015611daa573d6000803e3d6000fd5b505060405163221b8a9560e11b81526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169250634437152a9150602401611c6e565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611e445760405162461bcd60e51b815260040161057f90615554565b600060028581548110611e6757634e487b7160e01b600052603260045260246000fd5b600091825260209091206009909102016001810180546001600160a01b0319166001600160a01b03871617905590508415611f3c57611ec484600060026000815481106118b957634e487b7160e01b600052603260045260246000fd5b611eeb846000600288815481106118b957634e487b7160e01b600052603260045260246000fd5b611f148460001960026000815481106118b957634e487b7160e01b600052603260045260246000fd5b611f3c84600019600288815481106118b957634e487b7160e01b600052603260045260246000fd5b6002810180546001600160a01b0319166001600160a01b0394909416939093179092556004909101555050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611fb15760405162461bcd60e51b815260040161057f90615554565b60045460ff1615611fd45760405162461bcd60e51b815260040161057f90615579565b6004805460ff19166001178155604051637b51e92760e11b81527f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0383169163f6a3d24e9161203c918a91016001600160a01b0391909116815260200190565b60206040518083038186803b15801561205457600080fd5b505afa158015612068573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061208c91906151fe565b6120ec576040516335313c2160e11b81526001600160a01b038781166004830152821690636a62784290602401600060405180830381600087803b1580156120d357600080fd5b505af11580156120e7573d6000803e3d6000fd5b505050505b6120f585613597565b6120ff8383613659565b60006002868154811061212257634e487b7160e01b600052603260045260246000fd5b6000918252602090912060099091020180546003820154919250612154916001600160a01b0390911690893089613af4565b600882015460405163dfd01ff360e01b81526001600160a01b038a81166004830152602482018a905292975090916000919085169063dfd01ff39060440160606040518083038186803b1580156121aa57600080fd5b505afa1580156121be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e29190615236565b9050600080670de0b6b3a764000083600001518460400151866122059190615946565b61220f91906158a4565b6122199190615777565b9050896122c95761224a817f0000000000000000000000000000000000000000000000000000000000000000613711565b6122538a6136ce565b61225d9190615736565b9150808560070160008282546122739190615946565b909155506122a39050817f0000000000000000000000000000000000000000000000000000000000000000613711565b6122ad9082615946565b600160008282546122be9190615736565b909155506122ea9050565b6122d2896136ce565b915080836020018181516122e69190615736565b9052505b81836000018181516122fc9190615736565b9052506040830184905260068501805483919060009061231d908490615736565b9091555050604051633f9d338160e11b81526001600160a01b03871690637f3a670290612352908e908e908890600401615509565b600060405180830381600087803b15801561236c57600080fd5b505af1158015612380573d6000803e3d6000fd5b505050506000806123908a6137c7565b915091507f00000000000000000000000000000000000000000000000000000000000000006123bf83836145bc565b12156123fa5760405162461bcd60e51b815260206004820152600a6024820152690696e73756627742062360b41b604482015260640161057f565b8b8d6001600160a01b03167f06239653922ac7bea6aa2b19dc486b9361821d37712eb796adfd38d81de278ca8d60405161243691815260200190565b60405180910390a350506004805460ff191690555050505050505050505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461249f5760405162461bcd60e51b815260040161057f90615554565b600380546001810182556000919091528151805183926009027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01916124ea91839160200190614e71565b5060208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070155610100820151816008015550507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a3a090396003805490506040518263ffffffff1660e01b8152600401611c6e91815260200190565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146125fc5760405162461bcd60e51b815260040161057f90615554565b60045460ff161561261f5760405162461bcd60e51b815260040161057f90615579565b6004805460ff191660011790556126358261461a565b61263f8282613659565b6126498382613c36565b7f0000000000000000000000000000000000000000000000000000000000000000612675848484614092565b126126b35760405162461bcd60e51b815260206004820152600e60248201526d63616e74206c697175696461746560901b604482015260640161057f565b604051631f75a98760e11b81526001600160a01b0384811660048301527f000000000000000000000000000000000000000000000000000000000000000091600091831690633eeb530e9060240160006040518083038186803b15801561271957600080fd5b505afa15801561272d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526127559190810190615160565b90506000805b8481101561299f5782818151811061278357634e487b7160e01b600052603260045260246000fd5b60200260200101516000015160001461298d578281815181106127b657634e487b7160e01b600052603260045260246000fd5b602002602001015160000151600382815481106127e357634e487b7160e01b600052603260045260246000fd5b906000526020600020906009020160070160008282546128039190615946565b9250508190555082818151811061282a57634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516003828154811061285757634e487b7160e01b600052603260045260246000fd5b906000526020600020906009020160080160008282546128779190615946565b9250508190555082818151811061289e57634e487b7160e01b600052603260045260246000fd5b602002602001015160200151670de0b6b3a7640000600383815481106128d457634e487b7160e01b600052603260045260246000fd5b906000526020600020906009020160020154670de0b6b3a76400006003858154811061291057634e487b7160e01b600052603260045260246000fd5b90600052602060002090600902016005015487868151811061294257634e487b7160e01b600052603260045260246000fd5b60200260200101516000015161295891906158a4565b6129629190615777565b61296c91906158a4565b6129769190615777565b6129809190615946565b61298a9083615736565b91505b8061299781615a1a565b91505061275b565b50604051638691123560e01b81526001600160a01b0387811660048301526000919085169063869112359060240160006040518083038186803b1580156129e557600080fd5b505afa1580156129f9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612a2191908101906150c8565b905080600081518110612a4457634e487b7160e01b600052603260045260246000fd5b602002602001015182612a579190615736565b915060015b86811015612bf6576000828281518110612a8657634e487b7160e01b600052603260045260246000fd5b60200260200101511315612be457600060028281548110612ab757634e487b7160e01b600052603260045260246000fd5b906000526020600020906009020160010160009054906101000a90046001600160a01b03166001600160a01b03166366019fdb612b1a858581518110612b0d57634e487b7160e01b600052603260045260246000fd5b602002602001015161378f565b612b5560028681548110612b3e57634e487b7160e01b600052603260045260246000fd5b90600052602060002090600902016005015461378f565b6040516001600160e01b031960e085901b168152600481019290925260248201526044016040805180830381600087803b158015612b9257600080fd5b505af1158015612ba6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bca9190615427565b509050612bd6816136ce565b612be09085615736565b9350505b80612bee81615a1a565b915050612a5c565b5060007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000818513612c4a57819250612cd9565b808512612c5957809250612cd9565b612cd67f000000000000000000000000000000000000000000000000000000000000000083670de0b6b3a76400007f0000000000000000000000000000000000000000000000000000000000000000612cb2838b615946565b612cbc91906158a4565b612cc69190615777565b612cd09190615736565b90613711565b92505b600080612ce58b6137c7565b9092509050612cff612cf78689615946565b83838e613f61565b60405163226bf2d160e21b81526001600160a01b038d811660048301528a16906389afcb4490602401600060405180830381600087803b158015612d4257600080fd5b505af1158015612d56573d6000803e3d6000fd5b50505050612dd78d612d9460127f0000000000000000000000000000000000000000000000000000000000000000612d8d8a61378f565b9190613a4d565b6002600081548110612db657634e487b7160e01b600052603260045260246000fd5b60009182526020909120600990910201546001600160a01b03169190613a91565b8c6001600160a01b03168c6001600160a01b03167faef3faf684172084346f7dc2cc3bb1328d1cc23caec12dd9a82d4a4e56c00b17612e158861378f565b604051908152602001612436565b612e8d60405180610120016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60028281548110612eae57634e487b7160e01b600052603260045260246000fd5b60009182526020918290206040805161012081018252600990930290910180546001600160a01b03908116845260018201548116948401949094526002810154909316908201526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e082015260089091015461010082015292915050565b60006002600081548110612f5d57634e487b7160e01b600052603260045260246000fd5b600091825260208220600990910201546001546001600160a01b039091169250612faf906012907f000000000000000000000000000000000000000000000000000000000000000090612d8d9061378f565b6040516370a0823160e01b81523060048201529091506001600160a01b038316906370a082319060240160206040518083038186803b158015612ff157600080fd5b505afa158015613005573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613029919061521e565b8111156130aa576040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b15801561306f57600080fd5b505afa158015613083573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a7919061521e565b90505b6130d9611973827f00000000000000000000000000000000000000000000000000000000000000006012613a4d565b600160008282546130ea9190615946565b9091555061312490506001600160a01b0383167f000000000000000000000000000000000000000000000000000000000000000083613a91565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167fdc9b9c7c232fac9d635ce55b58e41cca2c16aa6ad39a73973ce276d479ad6f2d61319b837f00000000000000000000000000000000000000000000000000000000000000006012613a4d565b60405190815260200160405180910390a25050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146131f85760405162461bcd60e51b815260040161057f90615554565b60045460ff161561321b5760405162461bcd60e51b815260040161057f90615579565b6004805460ff191660011790556132328282613659565b61323c8582613c36565b6132468583614694565b60007f0000000000000000000000000000000000000000000000000000000000000000905060006002868154811061328e57634e487b7160e01b600052603260045260246000fd5b6000918252602090912060099091020160038101549091506132b0868261369d565b955060006132bd876136ce565b60405163b798de4760e01b81526001600160a01b038b81166004830152602482018b905291925060009186169063b798de479060440160206040518083038186803b15801561330b57600080fd5b505afa15801561331f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613343919061521e565b90508082126133af576133558161378f565b9750886133a757613386817f0000000000000000000000000000000000000000000000000000000000000000613711565b6133909082615946565b600160008282546133a19190615736565b90915550505b5060006133bc565b6133b98282615946565b90505b60405163e65953e760e01b81526001600160a01b0386169063e65953e7906133ec908d908d9086906004016154e8565b600060405180830381600087803b15801561340657600080fd5b505af115801561341a573d6000803e3d6000fd5b505050507f000000000000000000000000000000000000000000000000000000000000000061344a8b8989614092565b12156134895760405162461bcd60e51b815260206004820152600e60248201526d34b739bab313ba1036b0b933b4b760911b604482015260640161057f565b6134ab8a6134998a601287613a4d565b86546001600160a01b03169190613a91565b888a6001600160a01b03167f5883bf37724d9d75e363505c95386798f01ca0c584be707f977ddff58f1fe4308a604051610c2c91815260200190565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461352f5760405162461bcd60e51b815260040161057f90615554565b60006003858154811061355257634e487b7160e01b600052603260045260246000fd5b600091825260209091206009909102016001810180546001600160a01b0319166001600160a01b03969096169590951790945550600383019190915560049091015550565b8015610c9257613620600282815481106135c157634e487b7160e01b600052603260045260246000fd5b906000526020600020906009020160020160009054906101000a90046001600160a01b03166001600160a01b03166398d5fdca6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561193b57600080fd5b6002828154811061364157634e487b7160e01b600052603260045260246000fd5b90600052602060002090600902016005018190555050565b600054439081111561369857600080613671856137c7565b9150915060006136818386614a1f565b905061368f81848489613f61565b50505060008190555b505050565b6000816012146136c3576136be6136b684601285613a4d565b836012613a4d565b6136c5565b825b90505b92915050565b60006001600160ff1b0382111561370d5760405162461bcd60e51b815260206004820152600360248201526255494f60e81b604482015260640161057f565b5090565b6000816012146136c3576136be61372a84601285614c23565b836012614c23565b60008261373f8484613711565b141561374c5750816136c8565b600061375a84601285614c23565b90506000841361376c5760001961376f565b60015b6137799082615736565b905061378781846012614c23565b9150506136c8565b60008082121561370d5760405162461bcd60e51b815260206004820152600360248201526249554f60e81b604482015260640161057f565b600060606000808467ffffffffffffffff8111156137f557634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561381e578160200160208202803683370190505b50905060005b858110156139255760006002828154811061384f57634e487b7160e01b600052603260045260246000fd5b9060005260206000209060090201905060008160060154905060008260070154670de0b6b3a76400008460040154670de0b6b3a764000086600501548661389691906158a4565b6138a09190615777565b6138aa91906158a4565b6138b49190615777565b6138be9190615736565b90506000821380156138d05750600081135b1561390f576138df8187615736565b95508085858151811061390257634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b505050808061391d90615a1a565b915050613824565b509094909350915050565b60008060005b83811015613a135760006003828154811061396157634e487b7160e01b600052603260045260246000fd5b90600052602060002090600902019050600081600701549050806000146139fe576000670de0b6b3a76400008360020154670de0b6b3a76400008560050154856139ab91906158a4565b6139b59190615777565b6139bf91906158a4565b6139c99190615777565b90508260080154816139db9190615946565b6139e59089615946565b97506139f081613f14565b6139fa9086615736565b9450505b50508080613a0b90615a1a565b915050613936565b508015613a3c5780613a2d670de0b6b3a7640000866158a4565b613a379190615777565b613a45565b6001600160ff1b035b949350505050565b6000818314613a8557613a6183600a6157fc565b613a6c83600a6157fc565b613a769086615927565b613a8091906157a5565b613a87565b835b90505b9392505050565b6040516001600160a01b03831660248201526044810182905261369890849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614c5c565b6040516370a0823160e01b81526001600160a01b03838116600483015260009187918391908316906370a082319060240160206040518083038186803b158015613b3d57600080fd5b505afa158015613b51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b75919061521e565b9050613b9a8686613b888760128c613a4d565b6001600160a01b038616929190614d2e565b6040516370a0823160e01b81526001600160a01b038681166004830152600091908416906370a082319060240160206040518083038186803b158015613bdf57600080fd5b505afa158015613bf3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c17919061521e565b9050613c29886012612d8d8585615985565b9998505050505050505050565b604051631f75a98760e11b81526001600160a01b0383811660048301527f000000000000000000000000000000000000000000000000000000000000000091600091829190841690633eeb530e9060240160006040518083038186803b158015613c9f57600080fd5b505afa158015613cb3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613cdb9190810190615160565b905060005b84811015613e10576000828281518110613d0a57634e487b7160e01b600052603260045260246000fd5b602002602001015190508060000151600014613dfd57600060038381548110613d4357634e487b7160e01b600052603260045260246000fd5b90600052602060002090600902016006015490506000826040015182039050670de0b6b3a7640000818460000151613d7b91906158a4565b613d859190615777565b613d8f9087615736565b60408085018490525163f733fed760e01b81529096506001600160a01b0388169063f733fed790613dc8908c9088908890600401615509565b600060405180830381600087803b158015613de257600080fd5b505af1158015613df6573d6000803e3d6000fd5b5050505050505b5080613e0881615a1a565b915050613ce0565b508115611c9c5760405163b798de4760e01b81526001600160a01b03868116600483015260006024830181905291849186169063b798de479060440160206040518083038186803b158015613e6457600080fd5b505afa158015613e78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e9c919061521e565b613ea69190615946565b60405163e65953e760e01b81529091506001600160a01b0385169063e65953e790613eda90899060009086906004016154e8565b600060405180830381600087803b158015613ef457600080fd5b505af1158015613f08573d6000803e3d6000fd5b50505050505050505050565b6000600160ff1b821415613f4f5760405162461bcd60e51b8152602060048201526002602482015261414f60f01b604482015260640161057f565b600082121561370d576136c882615a35565b600083138015613f7057508315155b1561408c5760005b81811015611c9c576000838281518110613fa257634e487b7160e01b600052603260045260246000fd5b6020026020010151131561407a57600060028281548110613fd357634e487b7160e01b600052603260045260246000fd5b9060005260206000209060090201905060008585848151811061400657634e487b7160e01b600052603260045260246000fd5b60200260200101518861401991906158a4565b6140239190615777565b9050808260070160008282546140399190615736565b90915550506006820154614055670de0b6b3a7640000836158a4565b61405f9190615777565b8260080160008282546140729190615736565b909155505050505b8061408481615a1a565b915050613f78565b50505050565b604051638691123560e01b81526001600160a01b0384811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009183919083169063869112359060240160006040518083038186803b1580156140fb57600080fd5b505afa15801561410f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261413791908101906150c8565b905060008160008151811061415c57634e487b7160e01b600052603260045260246000fd5b60200260200101519050600080600190505b8781101561425c57670de0b6b3a7640000600282815481106141a057634e487b7160e01b600052603260045260246000fd5b906000526020600020906009020160040154670de0b6b3a7640000600284815481106141dc57634e487b7160e01b600052603260045260246000fd5b90600052602060002090600902016005015487858151811061420e57634e487b7160e01b600052603260045260246000fd5b602002602001015161422091906158a4565b61422a9190615777565b61423491906158a4565b61423e9190615777565b6142489084615736565b92508061425481615a1a565b91505061416e565b50604051631f75a98760e11b81526001600160a01b03898116600483015260009190861690633eeb530e9060240160006040518083038186803b1580156142a257600080fd5b505afa1580156142b6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526142de9190810190615160565b905060005b8781101561445a5781818151811061430b57634e487b7160e01b600052603260045260246000fd5b602002602001015160000151600014614448576000670de0b6b3a76400006003838154811061434a57634e487b7160e01b600052603260045260246000fd5b906000526020600020906009020160020154670de0b6b3a76400006003858154811061438657634e487b7160e01b600052603260045260246000fd5b9060005260206000209060090201600501548686815181106143b857634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516143ce91906158a4565b6143d89190615777565b6143e291906158a4565b6143ec9190615777565b905082828151811061440e57634e487b7160e01b600052603260045260246000fd5b602002602001015160200151816144259190615946565b61442f9086615736565b945061443a81613f14565b6144449085615736565b9350505b8061445281615a1a565b9150506142e3565b5081156144835781614474670de0b6b3a7640000856158a4565b61447e9190615777565b613c29565b6001600160ff1b039998505050505050505050565b8015806145215750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156144e757600080fd5b505afa1580156144fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061451f919061521e565b155b61458c5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840161057f565b6040516001600160a01b03831660248201526044810182905261369890849063095ea7b360e01b90606401613abd565b6000821561460b5782670de0b6b3a7640000836000815181106145ef57634e487b7160e01b600052603260045260246000fd5b602002602001015161460191906158a4565b6136be9190615777565b506001600160ff1b0392915050565b60015b8181101561469057614649600282815481106135c157634e487b7160e01b600052603260045260246000fd5b6002828154811061466a57634e487b7160e01b600052603260045260246000fd5b60009182526020909120600560099092020101558061468881615a1a565b91505061461d565b5050565b604051638691123560e01b81526001600160a01b0383811660048301527f00000000000000000000000000000000000000000000000000000000000000009160009183169063869112359060240160006040518083038186803b1580156146fa57600080fd5b505afa15801561470e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261473691908101906150c8565b905060008160008151811061475b57634e487b7160e01b600052603260045260246000fd5b6020026020010151121561408c5760008080614778600187615985565b90505b80156149f05760008482815181106147a357634e487b7160e01b600052603260045260246000fd5b602002602001015113156149a957600281815481106147d257634e487b7160e01b600052603260045260246000fd5b906000526020600020906009020160010160009054906101000a90046001600160a01b03166001600160a01b031663d1e7f49b61485e6108177f00000000000000000000000000000000000000000000000000000000000000008860008151811061484d57634e487b7160e01b600052603260045260246000fd5b602002602001015161081190615a35565b614881878581518110612b0d57634e487b7160e01b600052603260045260246000fd5b6148a560028681548110612b3e57634e487b7160e01b600052603260045260246000fd5b6040516001600160e01b031960e086901b1681526004810193909352602483019190915260448201526064016040805180830381600087803b1580156148ea57600080fd5b505af11580156148fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149229190615427565b9093509150614930836136ce565b8460008151811061495157634e487b7160e01b600052603260045260246000fd5b602002602001018181516149659190615736565b905250614971826136ce565b84828151811061499157634e487b7160e01b600052603260045260246000fd5b602002602001018181516149a59190615946565b9052505b6000846000815181106149cc57634e487b7160e01b600052603260045260246000fd5b6020026020010151126149de576149f0565b806149e8816159c8565b91505061477b565b50604051635e7d66d760e01b81526001600160a01b03851690635e7d66d790613eda9089908790600401615492565b6000808313614a30575060006136c8565b6000805b83811015614c1b57600060038281548110614a5f57634e487b7160e01b600052603260045260246000fd5b906000526020600020906009020190506000614ac68260010160009054906101000a90046001600160a01b03166001600160a01b03166398d5fdca6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561193b57600080fd5b60078301549091508015614c0257600283015460048401546000908a90670de0b6b3a7640000848181818a81614afc828d6158a4565b614b069190615777565b614b1091906158a4565b614b1a9190615777565b614b2491906158a4565b614b2e9190615777565b614b3891906158a4565b614b429190615777565b614b4c91906158a4565b614b569190615777565b90506000805443614b679190615985565b614b7190836158a4565b9050670de0b6b3a7640000614b8682866158a4565b614b909190615777565b614b9a9089615736565b9750670de0b6b3a764000083670de0b6b3a7640000886005015488614bbf9190615946565b614bc990886158a4565b614bd39190615777565b614bdd91906158a4565b614be79190615777565b614bf19089615946565b600687018054909201909155965050505b5060059091015580614c1381615a1a565b915050614a34565b509392505050565b6000818314613a8557614c3a61197384600a6157fc565b614c4861197384600a6157fc565b614c5290866158a4565b613a809190615777565b6000614cb1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614d669092919063ffffffff16565b8051909150156136985780806020019051810190614ccf91906151fe565b6136985760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161057f565b6040516001600160a01b038085166024830152831660448201526064810182905261408c9085906323b872dd60e01b90608401613abd565b6060613a87848460008585843b614dbf5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161057f565b600080866001600160a01b03168587604051614ddb9190615476565b60006040518083038185875af1925050503d8060008114614e18576040519150601f19603f3d011682016040523d82523d6000602084013e614e1d565b606091505b5091509150614e2d828286614e38565b979650505050505050565b60608315614e47575081613a8a565b825115614e575782518084602001fd5b8160405162461bcd60e51b815260040161057f9190615541565b828054614e7d906159df565b90600052602060002090601f016020900481019282614e9f5760008555614ee5565b82601f10614eb857805160ff1916838001178555614ee5565b82800160010185558215614ee5579182015b82811115614ee5578251825591602001919060010190614eca565b5061370d9291505b8082111561370d5760008155600101614eed565b80356001600160a01b0381168114614f1857600080fd5b919050565b600082601f830112614f2d578081fd5b813567ffffffffffffffff811115614f4757614f47615a7b565b614f5a601f8201601f19166020016156e1565b818152846020838601011115614f6e578283fd5b816020850160208301379081016020019190915292915050565b600060608284031215614f99578081fd5b6040516060810181811067ffffffffffffffff82111715614fbc57614fbc615a7b565b80604052508091508251815260208301516020820152604083015160408201525092915050565b600060208284031215614ff4578081fd5b6136c582614f01565b60008060008060808587031215615012578283fd5b61501b85614f01565b935061502960208601614f01565b93969395505050506040820135916060013590565b600080600080600060a08688031215615055578081fd5b61505e86614f01565b97602087013597506040870135966060810135965060800135945092505050565b600080600060608486031215615093578081fd5b61509c84614f01565b95602085013595506040909401359392505050565b600080600080600060a08688031215615055578283fd5b600060208083850312156150da578182fd5b825167ffffffffffffffff8111156150f0578283fd5b8301601f81018513615100578283fd5b805161511361510e82615712565b6156e1565b80828252848201915084840188868560051b8701011115615132578687fd5b8694505b83851015615154578051835260019490940193918501918501615136565b50979650505050505050565b60006020808385031215615172578182fd5b825167ffffffffffffffff811115615188578283fd5b8301601f81018513615198578283fd5b80516151a661510e82615712565b818152838101908385016060808502860187018a10156151c4578788fd5b8795505b848610156151f0576151da8a83614f88565b84526001959095019492860192908101906151c8565b509098975050505050505050565b60006020828403121561520f578081fd5b81518015158114613a8a578182fd5b60006020828403121561522f578081fd5b5051919050565b600060608284031215615247578081fd5b6136c58383614f88565b60006101208284031215615263578081fd5b61526b6156b7565b61527483614f01565b815261528260208401614f01565b602082015261529360408401614f01565b6040820152606083013560608201526080830135608082015260a083013560a082015260c083013560c082015260e083013560e08201526101008084013581830152508091505092915050565b6000602082840312156152f1578081fd5b813567ffffffffffffffff80821115615308578283fd5b90830190610120828603121561531c578283fd5b6153246156b7565b823582811115615332578485fd5b61533e87828601614f1d565b82525061534d60208401614f01565b602082015260408301356040820152606083013560608201526080830135608082015260a083013560a082015260c083013560c082015260e083013560e08201526101009150818301358282015280935050505092915050565b6000602082840312156153b8578081fd5b5035919050565b600080600080608085870312156153d4578182fd5b843593506153e460208601614f01565b92506153f260408601614f01565b9396929550929360600135925050565b60008060008060808587031215615417578182fd5b8435935061502960208601614f01565b60008060408385031215615439578182fd5b505080516020909101519092909150565b6000815180845261546281602086016020860161599c565b601f01601f19169290920160200192915050565b6000825161548881846020870161599c565b9190910192915050565b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b818110156154db578451835293830193918301916001016154bf565b5090979650505050505050565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b03841681526020810183905260a08101613a4560408301848051825260208082015190830152604090810151910152565b6020815260006136c5602083018461544a565b6020808252600b908201526a726f75746572206f6e6c7960a81b604082015260600190565b6020808252600790820152667265656e74727960c81b604082015260600190565b81516001600160a01b031681526020808301516101208301916155c7908401826001600160a01b03169052565b5060408301516155e260408401826001600160a01b03169052565b50606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525092915050565b602081526000825161012080602085015261564661014085018361544a565b9150602085015161566260408601826001600160a01b03169052565b506040850151606085015260608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151838701525050508091505092915050565b604051610120810167ffffffffffffffff811182821017156156db576156db615a7b565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561570a5761570a615a7b565b604052919050565b600067ffffffffffffffff82111561572c5761572c615a7b565b5060051b60200190565b600080821280156001600160ff1b038490038513161561575857615758615a4f565b600160ff1b839003841281161561577157615771615a4f565b50500190565b60008261578657615786615a65565b600160ff1b8214600019841416156157a0576157a0615a4f565b500590565b6000826157b4576157b4615a65565b500490565b600181815b808511156157f45781600019048211156157da576157da615a4f565b808516156157e757918102915b93841c93908002906157be565b509250929050565b60006136c58383600082615812575060016136c8565b8161581f575060006136c8565b8160018114615835576002811461583f5761585b565b60019150506136c8565b60ff84111561585057615850615a4f565b50506001821b6136c8565b5060208310610133831016604e8410600b841016171561587e575081810a6136c8565b61588883836157b9565b806000190482111561589c5761589c615a4f565b029392505050565b60006001600160ff1b03818413828413808216868404861116156158ca576158ca615a4f565b600160ff1b848712828116878305891216156158e8576158e8615a4f565b85871292508782058712848416161561590357615903615a4f565b8785058712818416161561591957615919615a4f565b505050929093029392505050565b600081600019048311821515161561594157615941615a4f565b500290565b60008083128015600160ff1b85018412161561596457615964615a4f565b6001600160ff1b038401831381161561597f5761597f615a4f565b50500390565b60008282101561599757615997615a4f565b500390565b60005b838110156159b757818101518382015260200161599f565b8381111561408c5750506000910152565b6000816159d7576159d7615a4f565b506000190190565b600181811c908216806159f357607f821691505b60208210811415615a1457634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415615a2e57615a2e615a4f565b5060010190565b6000600160ff1b821415615a4b57615a4b615a4f565b0390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea26469706673582212203d7d74dc3ac43bc6c5707cca8e098e42fac5aa8b7ba6e2cb303ea95401c3aa3664736f6c63430008040033000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000002c68af0bb1400000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000b1a2bc2ec50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000002c68af0bb140000000000000000000000000000adea18da0af0ab14900a5634eddf5a83513cdce00000000000000000000000000757bc621a32b1134ecf2843955b0bbc8ca13ba10000000000000000000000007e412350a64bd454c800d1273cea59c78d708eab000000000000000000000000dcca8b2810888e6ad79821bf2e3efacda874da29

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

000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000002c68af0bb1400000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000b1a2bc2ec50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000002c68af0bb140000000000000000000000000000adea18da0af0ab14900a5634eddf5a83513cdce00000000000000000000000000757bc621a32b1134ecf2843955b0bbc8ca13ba10000000000000000000000007e412350a64bd454c800d1273cea59c78d708eab000000000000000000000000dcca8b2810888e6ad79821bf2e3efacda874da29

-----Decoded View---------------
Arg [0] : parameters (uint256[9]): 6,200000000000000000,1000000000000000000,100000000000000000,50000000000000000,0,1000000000000000000000,500000000000000000,200000000000000000
Arg [1] : addresses (address[4]): 0xadea18da0af0ab14900a5634eddf5a83513cdce0,0x0757bc621a32b1134ecf2843955b0bbc8ca13ba1,0x7e412350a64bd454c800d1273cea59c78d708eab,0xdcca8b2810888e6ad79821bf2e3efacda874da29

-----Encoded View---------------
13 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [1] : 00000000000000000000000000000000000000000000000002c68af0bb140000
Arg [2] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [3] : 000000000000000000000000000000000000000000000000016345785d8a0000
Arg [4] : 00000000000000000000000000000000000000000000000000b1a2bc2ec50000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [6] : 00000000000000000000000000000000000000000000003635c9adc5dea00000
Arg [7] : 00000000000000000000000000000000000000000000000006f05b59d3b20000
Arg [8] : 00000000000000000000000000000000000000000000000002c68af0bb140000
Arg [9] : 000000000000000000000000adea18da0af0ab14900a5634eddf5a83513cdce0
Arg [10] : 0000000000000000000000000757bc621a32b1134ecf2843955b0bbc8ca13ba1
Arg [11] : 0000000000000000000000007e412350a64bd454c800d1273cea59c78d708eab
Arg [12] : 000000000000000000000000dcca8b2810888e6ad79821bf2e3efacda874da29


Deployed ByteCode Sourcemap

619:27753:9:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4349:142;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;10691:32:12;;;10673:51;;10661:2;10646:18;4349:142:9;;;;;;;;10429:2753;;;;;;:::i;:::-;;:::i;:::-;;7829:710;;;;;;:::i;:::-;;:::i;4499:142::-;;;;;;:::i;:::-;;:::i;13190:576::-;;;;;;:::i;:::-;;:::i;4209:132::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;15181:2242::-;;;;;;:::i;:::-;;:::i;5294:713::-;;;;;;:::i;:::-;;:::i;7383:352::-;;;;;;:::i;:::-;;:::i;3929:132::-;4020:8;:15;4037:8;:15;3929:132;;;15081:25:12;;;15137:2;15122:18;;15115:34;;;;15054:18;3929:132:9;15036:119:12;6196:728:9;;;;;;:::i;:::-;;:::i;8747:1674::-;;;;;;:::i;:::-;;:::i;3537:384::-;;;;-1:-1:-1;;;;;3762:14:9;11331:15:12;;11313:34;;3803:14:9;11383:15:12;;11378:2;11363:18;;11356:43;3844:14:9;11435:15:12;;11415:18;;;11408:43;;;;3892:21:9;11487:15:12;;;;11482:2;11467:18;;11460:43;11262:3;11247:19;3537:384:9;11229:280:12;2641:888:9;;;;3069:10;22776:25:12;;3108:16:9;22832:2:12;22817:18;;22810:34;3156:19:9;22860:18:12;;;22853:34;;;;3210:22:9;22918:2:12;22903:18;;22896:34;3271:26:9;22961:3:12;22946:19;;22939:35;3331:21:9;23005:3:12;22990:19;;22983:35;3386:21:9;23049:3:12;23034:19;;23027:35;3440:20:9;23093:3:12;23078:19;;23071:35;3497:24:9;23137:3:12;23122:19;;23115:35;22763:3;22748:19;2641:888:9;22730:426:12;6015:173:9;;;;;;:::i;:::-;;:::i;17431:2161::-;;;;;;:::i;:::-;;:::i;4069:132::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;4775:511::-;;;:::i;13774:1180::-;;;;;;:::i;:::-;;:::i;4649:118::-;4740:19;;4649:118;;14873:25:12;;;14861:2;14846:18;4649:118:9;14828:76:12;6932:357:9;;;;;;:::i;:::-;;:::i;4349:142::-;4424:7;4451:8;4460;4451:18;;;;;;-1:-1:-1;;;4451:18:9;;;;;;;;;;;;;;;;;:32;:18;;;;;:32;;-1:-1:-1;;;;;4451:32:9;;4349:142;-1:-1:-1;;4349:142:9:o;10429:2753::-;1826:10;-1:-1:-1;;;;;1840:14:9;1826:28;;1818:52;;;;-1:-1:-1;;;1818:52:9;;;;;;;:::i;:::-;;;;;;;;;1692:6:::1;::::0;::::1;;1691:7;1683:27;;;;-1:-1:-1::0;;;1683:27:9::1;;;;;;;:::i;:::-;1721:6;:13:::0;;-1:-1:-1;;1721:13:9::1;1730:4;1721:13;::::0;;10583:28:::2;10602:8:::0;10583:18:::2;:28::i;:::-;10622:47;10652:7;10661;10622:29;:47::i;:::-;10682:20;10705:8;10714;10705:18;;;;;;-1:-1:-1::0;;;10705:18:9::2;;;;;;;;;;::::0;;;::::2;::::0;;10814:32:::2;::::0;-1:-1:-1;;;10814:32:9;;-1:-1:-1;;;;;12829:32:12;;;10814::9::2;::::0;::::2;12811:51:12::0;12878:18;;;12871:34;;;10705:18:9::2;::::0;;;::::2;::::0;;::::2;::::0;-1:-1:-1;10759:14:9::2;::::0;10705:18;10814:15;::::2;::::0;::::2;::::0;12784:18:12;;10814:32:9::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10876:10;::::0;::::2;::::0;10785:61;;-1:-1:-1;10907:26:9::2;:7:::0;10876:10;10907:16:::2;:26::i;:::-;10995:15;::::0;::::2;::::0;10897:36;;-1:-1:-1;10972:20:9::2;11037:14;10897:36:::0;11037:12:::2;:14::i;:::-;11021:30;;11062:10;792:6;11119:5;:15;;;11092:5;:23;;;11076:13;:39;;;;:::i;:::-;11075:59;;;;:::i;:::-;:65;;;;:::i;:::-;11062:78:::0;-1:-1:-1;11151:21:9::2;::::0;11213:13;11209:1108:::2;;11260:24;:3:::0;11273:10:::2;11260:12;:24::i;:::-;11243:41:::0;-1:-1:-1;11310:4:9::2;11311:3:::0;11310:4:::2;:::i;:::-;11299:15:::0;-1:-1:-1;11358:24:9::2;:3:::0;11371:10:::2;11358:12;:24::i;:::-;11352:30;::::0;:3;:30:::2;:::i;:::-;11329:19;;:53;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;11209:1108:9::2;::::0;-1:-1:-1;11209:1108:9::2;;11455:3;11442:5;:9;;:16;;;;;;;:::i;:::-;::::0;;-1:-1:-1;11477:9:9::2;::::0;::::2;::::0;11489:1:::2;-1:-1:-1::0;11473:833:9::2;;;11512:16;11530::::0;11565:1:::2;:16;;;;;;;;;;-1:-1:-1::0;;;;;11565:16:9::2;-1:-1:-1::0;;;;;11550:49:9::2;;11622:36;:29;11640:10;11624:5;:9;;;11623:10;;;:::i;:::-;11622:17:::0;::::2;:29::i;:::-;:34;:36::i;:::-;11660:15:::0;;:22:::2;::::0;:20:::2;:22::i;:::-;11684:14;:1;:7;;;:12;:14::i;:::-;11550:167;::::0;-1:-1:-1;;;;;;11550:167:9::2;::::0;;;;;;::::2;::::0;::::2;23616:25:12::0;;;;23657:18;;;23650:34;;;;23700:18;;;23693:34;23589:18;;11550:167:9::2;::::0;::::2;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11511:206;;;;11754:15;:8;:13;:15::i;:::-;11753:16;;;:::i;:::-;11736:33;;11799:15;:8;:13;:15::i;:::-;11788:26;;11846:15;:8;:13;:15::i;:::-;11833:5;:9;;:28;;;;;;;:::i;:::-;::::0;;-1:-1:-1;11473:833:9::2;::::0;-1:-1:-1;;11473:833:9::2;;11899:1;11887:5;:9;;;:13;:42;;;;-1:-1:-1::0;11914:15:9;;11904:25;::::2;;11887:42;11883:423;;;11988:16;::::0;::::2;::::0;12023:9:::2;::::0;::::2;::::0;11953:16:::2;::::0;-1:-1:-1;;;;;11988:16:9::2;::::0;11973:49:::2;::::0;12023:16:::2;::::0;:14:::2;:16::i;:::-;12041:14;:1;:7;;;:12;:14::i;:::-;11973:83;::::0;-1:-1:-1;;;;;;11973:83:9::2;::::0;;;;;;::::2;::::0;::::2;15081:25:12::0;;;;15122:18;;;15115:34;15054:18;;11973:83:9::2;::::0;::::2;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11950:106;;;12092:15;:8;:13;:15::i;:::-;12075:32;;12138:5;:9;;;12137:10;;;:::i;:::-;12201:9;::::0;::::2;::::0;12126:21;;-1:-1:-1;12201:30:9::2;::::0;12220:10:::2;12201:18;:30::i;:::-;12189:5;:9;;;:42;;;;:::i;:::-;12166:19;;:65;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;12289:1:9::2;12277:9;::::0;::::2;:13:::0;-1:-1:-1;11883:423:9::2;12327:23;::::0;::::2;:39:::0;;;12393:15;;12383:25;::::2;;::::0;:71:::2;;-1:-1:-1::0;12422:15:9;;:32:::2;::::0;12440:14;;12422:32:::2;:::i;:::-;12412:6;:42;;12383:71;12379:362;;;12482:15:::0;;12481:41:::2;::::0;12482:32:::2;::::0;12500:14;;12482:32:::2;:::i;12481:41::-;12471:51;;12552:5;:15;;;12537:1;:11;;;:30;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;12600:1:9::2;12582:19:::0;;12379:362:::2;;;12653:23;12670:6:::0;12653:14;:23:::2;:::i;:::-;12634:42:::0;;:5;;:42:::2;::::0;;;::::2;:::i;:::-;::::0;;-1:-1:-1;12706:23:9::2;12723:6:::0;12706:14;:23:::2;:::i;:::-;12691:1;:11;;;:38;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;12379:362:9::2;12760:8;12751:1;:5;;;:17;;;;;;;:::i;:::-;;;;;;;;12779:6;-1:-1:-1::0;;;;;12779:18:9::2;;12798:5;12805:8;12815:5;12779:42;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;1745:1;;;;;12859:25;12890:34;12916:7;12890:25;:34::i;:::-;12858:66;;;12995:19;12943:48;12963:18;12983:7;12943:19;:48::i;:::-;:71;;12935:95;;;::::0;-1:-1:-1;;;12935:95:9;;16269:2:12;12935:95:9::2;::::0;::::2;16251:21:12::0;16308:2;16288:18;;;16281:30;-1:-1:-1;;;16327:18:12;;;16320:41;16378:18;;12935:95:9::2;16241:161:12::0;12935:95:9::2;13043:74;13080:5:::0;13087:29:::2;:7:::0;13103:2:::2;13107:8:::0;13087:15:::2;:29::i;:::-;13050:15:::0;;-1:-1:-1;;;;;13050:15:9::2;::::0;13043:74;:36:::2;:74::i;:::-;13156:8;13149:5;-1:-1:-1::0;;;;;13133:41:9::2;;13166:7;13133:41;;;;14873:25:12::0;;14861:2;14846:18;;14828:76;13133:41:9::2;;;;;;;;-1:-1:-1::0;;1757:6:9::1;:14:::0;;-1:-1:-1;;1757:14:9::1;::::0;;-1:-1:-1;;;;;;;;10429:2753:9:o;7829:710::-;1826:10;-1:-1:-1;;;;;1840:14:9;1826:28;;1818:52;;;;-1:-1:-1;;;1818:52:9;;;;;;;:::i;:::-;7829:710;:::o;4499:142::-;4574:7;4601:8;4610;4601:18;;;;;;-1:-1:-1;;;4601:18:9;;;;;;;;;;;;;;;;;:32;:18;;;;;:32;;-1:-1:-1;;;;;4601:32:9;;4499:142;-1:-1:-1;;4499:142:9:o;13190:576::-;1826:10;-1:-1:-1;;;;;1840:14:9;1826:28;;1818:52;;;;-1:-1:-1;;;1818:52:9;;;;;;;:::i;:::-;1692:6:::1;::::0;::::1;;1691:7;1683:27;;;;-1:-1:-1::0;;;1683:27:9::1;;;;;;;:::i;:::-;1721:6;:13:::0;;-1:-1:-1;;1721:13:9::1;1730:4;1721:13;::::0;;13360:20:::2;::::0;-1:-1:-1;;;13360:20:9;;13329:14:::2;::::0;-1:-1:-1;;;;;13360:13:9;::::2;::::0;::::2;::::0;:20:::2;::::0;13374:5;;13360:20:::2;-1:-1:-1::0;;;;;10691:32:12;;;;10673:51;;10661:2;10646:18;;10628:102;13360:20:9::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13355:45;;13382:18;::::0;-1:-1:-1;;;13382:18:9;;-1:-1:-1;;;;;10691:32:12;;;13382:18:9::2;::::0;::::2;10673:51:12::0;13382:11:9;::::2;::::0;::::2;::::0;10646:18:12;;13382::9::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;13355:45;13413:20;13436:8;13445;13436:18;;;;;;-1:-1:-1::0;;;13436:18:9::2;;;;;;;;;;::::0;;;::::2;::::0;;;::::2;::::0;;::::2;;13512:15:::0;;13529:10:::2;::::0;::::2;::::0;13436:18;;-1:-1:-1;13475:96:9::2;::::0;-1:-1:-1;;;;;13512:15:9;;::::2;::::0;13541:5;13556:4:::2;13563:7:::0;13475:36:::2;:96::i;:::-;13465:106;;13584:13;13636:14;:7;:12;:14::i;:::-;13600:33;::::0;-1:-1:-1;;;13600:33:9;;-1:-1:-1;;;;;12829:32:12;;;13600:33:9::2;::::0;::::2;12811:51:12::0;12878:18;;;12871:34;;;13600:16:9;::::2;::::0;::::2;::::0;12784:18:12;;13600:33:9::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:50;;;;:::i;:::-;13663:44;::::0;-1:-1:-1;;;13663:44:9;;13584:66;;-1:-1:-1;;;;;;13663:19:9;::::2;::::0;::::2;::::0;:44:::2;::::0;13683:5;;13690:8;;13584:66;;13663:44:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;13740:8;13733:5;-1:-1:-1::0;;;;;13723:35:9::2;;13750:7;13723:35;;;;14873:25:12::0;;14861:2;14846:18;;14828:76;13723:35:9::2;;;;;;;;-1:-1:-1::0;;1757:6:9::1;:14:::0;;-1:-1:-1;;1757:14:9::1;::::0;;-1:-1:-1;;;;13190:576:9:o;4209:132::-;4278:17;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4278:17:9;4315:8;4324;4315:18;;;;;;-1:-1:-1;;;4315:18:9;;;;;;;;;;;;;;;;;;;4308:25;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;4308:25:9;;;-1:-1:-1;;4308:25:9;;;;-1:-1:-1;;;;;4308:25:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4209:132;-1:-1:-1;;4209:132:9:o;15181:2242::-;1826:10;-1:-1:-1;;;;;1840:14:9;1826:28;;1818:52;;;;-1:-1:-1;;;1818:52:9;;;;;;;:::i;:::-;1692:6:::1;::::0;::::1;;1691:7;1683:27;;;;-1:-1:-1::0;;;1683:27:9::1;;;;;;;:::i;:::-;1721:6;:13:::0;;-1:-1:-1;;1721:13:9::1;1730:4;1721:13;::::0;;15328:47:::2;15358:7:::0;15367;15328:29:::2;:47::i;:::-;15386:39;15410:5;15417:7;15386:23;:39::i;:::-;15438:20;15461:8;15470;15461:18;;;;;;-1:-1:-1::0;;;15461:18:9::2;;;;;;;;;;::::0;;;::::2;::::0;;15518:52:::2;::::0;-1:-1:-1;;;15518:52:9;;-1:-1:-1;;;;;12829:32:12;;;15518:52:9::2;::::0;::::2;12811:51:12::0;12878:18;;;12871:34;;;15461:18:9::2;::::0;;;::::2;::::0;;::::2;::::0;-1:-1:-1;15526:14:9::2;15518:35:::0;;::::2;::::0;::::2;::::0;12784:18:12;;15518:52:9::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15490:80;;15583:25;-1:-1:-1::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15583:25:9::2;15635:23;:11:::0;15656:1:::2;15635:20;:23::i;:::-;15621:37;;792:6;15716:1;:12;;;792:6;15700:1;:7;;;15686:11;:21;;;;:::i;:::-;:27;;;;:::i;:::-;:42;;;;:::i;:::-;:48;;;;:::i;:::-;15669:65:::0;;;15781:10:::2;::::0;::::2;::::0;792:6:::2;::::0;15758:20:::2;::::0;:18:::2;:20::i;:::-;:33;;;;:::i;:::-;:39;;;;:::i;:::-;15745:10;::::0;::::2;:52:::0;15816:8;;15828:1:::2;-1:-1:-1::0;15816:13:9;::::2;::::0;:33:::2;;;15848:1;15833:11;:16;;15816:33;15814:36;:76;;;;-1:-1:-1::0;15856:8:9;;15868:1:::2;-1:-1:-1::0;15856:13:9;::::2;::::0;:33:::2;;;15888:1;15873:11;:16;;15856:33;15854:36;15814:76;15810:469;;;15907:16;15926:14;:1;:8;;;:12;:14::i;:::-;15907:33;;15955:21;15979:17;:11;:15;:17::i;:::-;15955:41;;16028:14;16015:9;:27;16011:257;;16131:6;::::0;::::2;::::0;16085:14;;16114;;16085:26:::2;::::0;16102:9;;16085:26:::2;:::i;:::-;:43;;;;:::i;:::-;:52;;;;:::i;:::-;16063:19;::::0;::::2;:74:::0;16011:257:::2;;;16238:14:::0;;16200:6:::2;::::0;::::2;::::0;16226:9;;16200:23:::2;::::0;16209:14;;16200:23:::2;:::i;:::-;:35;;;;:::i;:::-;:52;;;;:::i;:::-;16178:19;::::0;::::2;:74:::0;16011:257:::2;15810:469;;;16303:11;16291:1;:8;;:23;;;;;;;:::i;:::-;::::0;;-1:-1:-1;16352:19:9::2;::::0;::::2;::::0;16335:14;;:36:::2;::::0;16352:19;16335:36:::2;:::i;:::-;16325:1;:6;;:46;;;;;;;:::i;:::-;::::0;;-1:-1:-1;16412:23:9::2;::::0;::::2;::::0;16382:27:::2;::::0;;::::2;:53:::0;;;;16566:19;;::::2;::::0;16553:10:::2;::::0;::::2;::::0;16507:43;;-1:-1:-1;;;16507:43:9;;-1:-1:-1;;;;;12829:32:12;;;16507:43:9::2;::::0;::::2;12811:51:12::0;16504:1:9::2;12878:18:12::0;;;12871:34;;;16454:14:9::2;16446:36:::0;;::::2;::::0;::::2;::::0;16497:5;;16566:19;;16553:10;16446:36;;16507:33:::2;::::0;12784:18:12;;16507:43:9::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:56;;;;:::i;:::-;:78;;;;:::i;:::-;16446:150;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;16607:58:9::2;::::0;-1:-1:-1;;;16607:58:9;;-1:-1:-1;;;;;16615:14:9::2;16607:38;::::0;-1:-1:-1;16607:38:9::2;::::0;-1:-1:-1;16607:58:9::2;::::0;16646:5;;16653:8;;16663:1;;16607:58:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;16700:11;16678:1;:18;;;:33;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;16759:19:9::2;::::0;::::2;::::0;16742:14;;:36:::2;::::0;16759:19;16742:36:::2;:::i;:::-;16722:1;:16;;;:56;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;16812:10:9::2;::::0;::::2;::::0;792:6:::2;::::0;16812:37:::2;::::0;16825:24:::2;::::0;16812:37:::2;:::i;:::-;:43;;;;:::i;:::-;16791:18;::::0;::::2;:64:::0;;;16866:19:::2;:41:::0;;:19:::2;::::0;:41:::2;::::0;16791:64;;16866:41:::2;:::i;:::-;::::0;;;-1:-1:-1;16921:25:9::2;::::0;-1:-1:-1;16921:25:9;16983:34:::2;17009:7:::0;16983:25:::2;:34::i;:::-;16920:97;;;;17028:102;17065:6;:18;;;17052:6;:10;;;:31;;;;:::i;:::-;17085:18;17105:15;17122:7;17028:23;:102::i;:::-;17201:19;17149:48;17169:18;17189:7;17149:19;:48::i;:::-;:71;;17141:95;;;::::0;-1:-1:-1;;;17141:95:9;;16269:2:12;17141:95:9::2;::::0;::::2;16251:21:12::0;16308:2;16288:18;;;16281:30;-1:-1:-1;;;16327:18:12;;;16320:41;16378:18;;17141:95:9::2;16241:161:12::0;17141:95:9::2;17305:22;17255:46;17277:5;17284:7;17293;17255:21;:46::i;:::-;:72;;17247:99;;;::::0;-1:-1:-1;;;17247:99:9;;15926:2:12;17247:99:9::2;::::0;::::2;15908:21:12::0;15965:2;15945:18;;;15938:30;-1:-1:-1;;;15984:18:12;;;15977:44;16038:18;;17247:99:9::2;15898:164:12::0;17247:99:9::2;17377:8;17370:5;-1:-1:-1::0;;;;;17364:51:9::2;;17387:11;17400:14;:1;:7;;;:12;:14::i;:::-;17364:51;::::0;;15081:25:12;;;15137:2;15122:18;;15115:34;;;;15054:18;17364:51:9::2;15036:119:12::0;5294:713:9;1826:10;-1:-1:-1;;;;;1840:14:9;1826:28;;1818:52;;;;-1:-1:-1;;;1818:52:9;;;;;;;:::i;:::-;5379:8:::1;:15:::0;:19;5375:465:::1;;5464:85;5510:4;:19;;;-1:-1:-1::0;;5471:8:9::1;5480:1;5471:11;;;;;;-1:-1:-1::0;;;5471:11:9::1;;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;:25:::0;-1:-1:-1;;;;;5471:25:9::1;::::0;5464:85;:45:::1;:85::i;:::-;5603:19;::::0;::::1;::::0;5571:18;;5564:78:::1;::::0;-1:-1:-1;;;;;5564:38:9;;::::1;::::0;-1:-1:-1;;5564:38:9::1;:78::i;:::-;5670:45;5678:4;:18;;;-1:-1:-1::0;;;;;5670:36:9::1;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:43;:45::i;:::-;5657:10;::::0;::::1;:58:::0;5375:465:::1;;;5773:10;5756:4;:13;;;:27;5748:49;;;::::0;-1:-1:-1;;;5748:49:9;;17347:2:12;5748:49:9::1;::::0;::::1;17329:21:12::0;17386:1;17366:18;;;17359:29;-1:-1:-1;;;17404:18:12;;;17397:39;17453:18;;5748:49:9::1;17319:158:12::0;5748:49:9::1;792:6;5812:10;::::0;::::1;:16:::0;5375:465:::1;5850:8;:19:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;5850:19:9;;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;-1:-1:-1;;;;;5850:19:9;;::::1;-1:-1:-1::0;;;;;;5850:19:9;;::::1;;::::0;;;::::1;::::0;::::1;::::0;;;;;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;::::1;::::0;;;::::1;;::::0;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;;;;;5918:15;;5880:54;;-1:-1:-1;;;5880:54:9;;5850:19:::1;5880:54:::0;::::1;14873:25:12::0;;;;5888:14:9::1;5880:37;::::0;::::1;::::0;14846:18:12;;5880:54:9::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;5983:8:9::1;:15:::0;5945:54:::1;::::0;-1:-1:-1;;;5945:54:9;;::::1;::::0;::::1;14873:25:12::0;;;;5953:14:9::1;-1:-1:-1::0;;;;;5945:37:9::1;::::0;-1:-1:-1;5945:37:9::1;::::0;-1:-1:-1;14846:18:12;;5945:54:9::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;5294:713:::0;:::o;7383:352::-;1826:10;-1:-1:-1;;;;;1840:14:9;1826:28;;1818:52;;;;-1:-1:-1;;;1818:52:9;;;;;;;:::i;:::-;7476:9:::1;7471:149;7495:8;:15:::0;7491:19;::::1;7471:149;;;7532:76;7578:10;-1:-1:-1::0;;7539:8:9::1;7548:1;7539:11;;;;;;-1:-1:-1::0;;;7539:11:9::1;;;;;;;;7532:76;7512:3:::0;::::1;::::0;::::1;:::i;:::-;;;;7471:149;;;-1:-1:-1::0;7630:43:9::1;::::0;-1:-1:-1;;;7630:43:9;;-1:-1:-1;;;;;10691:32:12;;;7630:43:9::1;::::0;::::1;10673:51:12::0;7638:14:9::1;7630:31;::::0;::::1;::::0;10646:18:12;;7630:43:9::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;7684:43:9::1;::::0;-1:-1:-1;;;7684:43:9;;-1:-1:-1;;;;;10691:32:12;;;7684:43:9::1;::::0;::::1;10673:51:12::0;7692:14:9::1;7684:31;::::0;-1:-1:-1;7684:31:9::1;::::0;-1:-1:-1;10646:18:12;;7684:43:9::1;10628:102:12::0;6196:728:9;1826:10;-1:-1:-1;;;;;1840:14:9;1826:28;;1818:52;;;;-1:-1:-1;;;1818:52:9;;;;;;;:::i;:::-;6346:20:::1;6369:8;6378;6369:18;;;;;;-1:-1:-1::0;;;6369:18:9::1;;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;6398:16;::::0;::::1;:33:::0;;-1:-1:-1;;;;;;6398:33:9::1;-1:-1:-1::0;;;;;6398:33:9;::::1;;::::0;;6369:18;-1:-1:-1;6446:13:9;;6442:393:::1;;6476:64;6522:14;6538:1;6483:8;6492:1;6483:11;;;;;;-1:-1:-1::0;;;6483:11:9::1;;;;;;;;6476:64;6555:71;6608:14;6624:1;6562:8;6571;6562:18;;;;;;-1:-1:-1::0;;;6562:18:9::1;;;;;;;;6555:71;6641:80;6687:14;-1:-1:-1::0;;6648:8:9::1;6657:1;6648:11;;;;;;-1:-1:-1::0;;;6648:11:9::1;;;;;;;;6641:80;6736:87;6789:14;-1:-1:-1::0;;6743:8:9::1;6752;6743:18;;;;;;-1:-1:-1::0;;;6743:18:9::1;;;;;;;;6736:87;6845:15;::::0;::::1;:31:::0;;-1:-1:-1;;;;;;6845:31:9::1;-1:-1:-1::0;;;;;6845:31:9;;;::::1;::::0;;;::::1;::::0;;;6887:10:::1;::::0;;::::1;:29:::0;-1:-1:-1;;6196:728:9:o;8747:1674::-;1826:10;-1:-1:-1;;;;;1840:14:9;1826:28;;1818:52;;;;-1:-1:-1;;;1818:52:9;;;;;;;:::i;:::-;1692:6:::1;::::0;::::1;;1691:7;1683:27;;;;-1:-1:-1::0;;;1683:27:9::1;;;;;;;:::i;:::-;1721:6;:13:::0;;-1:-1:-1;;1721:13:9::1;1730:4;1721:13;::::0;;8953:20:::2;::::0;-1:-1:-1;;;8953:20:9;;8923:14:::2;::::0;-1:-1:-1;;;;;8953:13:9;::::2;::::0;::::2;::::0;:20:::2;::::0;8967:5;;8953:20:::2;-1:-1:-1::0;;;;;10691:32:12;;;;10673:51;;10661:2;10646:18;;10628:102;8953:20:9::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8949:44;;8975:18;::::0;-1:-1:-1;;;8975:18:9;;-1:-1:-1;;;;;10691:32:12;;;8975:18:9::2;::::0;::::2;10673:51:12::0;8975:11:9;::::2;::::0;::::2;::::0;10646:18:12;;8975::9::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;8949:44;9006:28;9025:8;9006:18;:28::i;:::-;9045:47;9075:7;9084;9045:29;:47::i;:::-;9105:20;9128:8;9137;9128:18;;;;;;-1:-1:-1::0;;;9128:18:9::2;;;;;;;;;;::::0;;;::::2;::::0;;;::::2;::::0;;::::2;;9204:15:::0;;9221:10:::2;::::0;::::2;::::0;9128:18;;-1:-1:-1;9167:96:9::2;::::0;-1:-1:-1;;;;;9204:15:9;;::::2;::::0;9233:5;9248:4:::2;9255:7:::0;9167:36:::2;:96::i;:::-;9299:15;::::0;::::2;::::0;9354:32:::2;::::0;-1:-1:-1;;;9354:32:9;;-1:-1:-1;;;;;12829:32:12;;;9354::9::2;::::0;::::2;12811:51:12::0;12878:18;;;12871:34;;;9157:106:9;;-1:-1:-1;9299:15:9;;9276:20:::2;::::0;9354:15;;::::2;::::0;::::2;::::0;12784:18:12;;9354:32:9::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9325:61;;9399:12;9470:10:::0;792:6:::2;9527:5;:15;;;9500:5;:23;;;9484:13;:39;;;;:::i;:::-;9483:59;;;;:::i;:::-;:65;;;;:::i;:::-;9470:78:::0;-1:-1:-1;9606:13:9;9602:368:::2;;9661:24;:3:::0;9674:10:::2;9661:12;:24::i;:::-;9644:14;:7;:12;:14::i;:::-;:41;;;;:::i;:::-;9636:49;;9709:3;9700:1;:5;;;:12;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;9821:24:9::2;::::0;-1:-1:-1;9821:3:9;9834:10:::2;9821:12;:24::i;:::-;9815:30;::::0;:3;:30:::2;:::i;:::-;9792:19;;:53;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;9602:368:9::2;::::0;-1:-1:-1;9602:368:9::2;;9913:14;:7;:12;:14::i;:::-;9905:22;;9955:3;9942:5;:9;;:16;;;;;;;:::i;:::-;::::0;;-1:-1:-1;9602:368:9::2;9999:5;9980;:15;;:24;;;;;;;:::i;:::-;::::0;;-1:-1:-1;10015:23:9::2;::::0;::::2;:39:::0;;;10065:11:::2;::::0;::::2;:20:::0;;10080:5;;10065:11;::::2;::::0;:20:::2;::::0;10080:5;;10065:20:::2;:::i;:::-;::::0;;;-1:-1:-1;;10098:42:9::2;::::0;-1:-1:-1;;;10098:42:9;;-1:-1:-1;;;;;10098:18:9;::::2;::::0;::::2;::::0;:42:::2;::::0;10117:5;;10124:8;;10134:5;;10098:42:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;10154:25;10181:31:::0;10216:34:::2;10242:7;10216:25;:34::i;:::-;10153:97;;;;10326:16;10269:53;10286:18;10306:15;10269:16;:53::i;:::-;:73;;10261:96;;;::::0;-1:-1:-1;;;10261:96:9;;15587:2:12;10261:96:9::2;::::0;::::2;15569:21:12::0;15626:2;15606:18;;;15599:30;-1:-1:-1;;;15645:18:12;;;15638:40;15695:18;;10261:96:9::2;15559:160:12::0;10261:96:9::2;10395:8;10388:5;-1:-1:-1::0;;;;;10375:38:9::2;;10405:7;10375:38;;;;14873:25:12::0;;14861:2;14846:18;;14828:76;10375:38:9::2;;;;;;;;-1:-1:-1::0;;1757:6:9::1;:14:::0;;-1:-1:-1;;1757:14:9::1;::::0;;-1:-1:-1;;;;;;;;;;;8747:1674:9:o;6015:173::-;1826:10;-1:-1:-1;;;;;1840:14:9;1826:28;;1818:52;;;;-1:-1:-1;;;1818:52:9;;;;;;;:::i;:::-;6096:8:::1;:19:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;6096:19:9;;;;;;;;6110:4;;6096:19:::1;;::::0;::::1;::::0;::::1;::::0;;;::::1;;::::0;::::1;:::i;:::-;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;6096:19:9::1;;;;;-1:-1:-1::0;;;;;6096:19:9::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6134:14;-1:-1:-1::0;;;;;6126:37:9::1;;6164:8;:15;;;;6126:54;;;;;;;;;;;;;14873:25:12::0;;14861:2;14846:18;;14828:76;17431:2161:9;1826:10;-1:-1:-1;;;;;1840:14:9;1826:28;;1818:52;;;;-1:-1:-1;;;1818:52:9;;;;;;;:::i;:::-;1692:6:::1;::::0;::::1;;1691:7;1683:27;;;;-1:-1:-1::0;;;1683:27:9::1;;;;;;;:::i;:::-;1721:6;:13:::0;;-1:-1:-1;;1721:13:9::1;1730:4;1721:13;::::0;;17564:31:::2;17587:7:::0;17564:22:::2;:31::i;:::-;17606:47;17636:7;17645;17606:29;:47::i;:::-;17664:39;17688:5;17695:7;17664:23;:39::i;:::-;17771:26;17722:46;17744:5;17751:7;17760;17722:21;:46::i;:::-;:75;17714:102;;;::::0;-1:-1:-1;;;17714:102:9;;18372:2:12;17714:102:9::2;::::0;::::2;18354:21:12::0;18411:2;18391:18;;;18384:30;-1:-1:-1;;;18430:18:12;;;18423:44;18484:18;;17714:102:9::2;18344:164:12::0;17714:102:9::2;17918:26;::::0;-1:-1:-1;;;17918:26:9;;-1:-1:-1;;;;;10691:32:12;;;17918:26:9::2;::::0;::::2;10673:51:12::0;17854:14:9::2;::::0;17829::::2;::::0;17918:19;::::2;::::0;::::2;::::0;10646:18:12;;17918:26:9::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;::::0;;::::2;-1:-1:-1::0;;17918:26:9::2;::::0;::::2;;::::0;::::2;::::0;;;::::2;::::0;::::2;:::i;:::-;17880:64:::0;-1:-1:-1;17955:16:9::2;::::0;17982:374:::2;18006:7;18002:1;:11;17982:374;;;18039:9;18049:1;18039:12;;;;;;-1:-1:-1::0;;;18039:12:9::2;;;;;;;;;;;;;;;:19;;;18062:1;18039:24;18035:310;;18116:9;18126:1;18116:12;;;;;;-1:-1:-1::0;;;18116:12:9::2;;;;;;;;;;;;;;;:19;;;18084:8;18093:1;18084:11;;;;;;-1:-1:-1::0;;;18084:11:9::2;;;;;;;;;;;;;;;;;;;:28;;;:51;;;;;;;:::i;:::-;;;;;;;;18184:9;18194:1;18184:12;;;;;;-1:-1:-1::0;;;18184:12:9::2;;;;;;;;;;;;;;;:17;;;18154:8;18163:1;18154:11;;;;;;-1:-1:-1::0;;;18154:11:9::2;;;;;;;;;;;;;;;;;;;:26;;;:47;;;;;;;:::i;:::-;;;;;;;;18312:9;18322:1;18312:12;;;;;;-1:-1:-1::0;;;18312:12:9::2;;;;;;;;;;;;;;;:17;;;792:6;18281:8;18290:1;18281:11;;;;;;-1:-1:-1::0;;;18281:11:9::2;;;;;;;;;;;;;;;;;;;:22;;;792:6;18255:8;18264:1;18255:11;;;;;;-1:-1:-1::0;;;18255:11:9::2;;;;;;;;;;;;;;;;;;;:17;;;18233:9;18243:1;18233:12;;;;;;-1:-1:-1::0;;;18233:12:9::2;;;;;;;;;;;;;;;:19;;;:39;;;;:::i;:::-;:45;;;;:::i;:::-;:70;;;;:::i;:::-;:76;;;;:::i;:::-;:96;;;;:::i;:::-;18220:109;::::0;;::::2;:::i;:::-;;;18035:310;18015:3:::0;::::2;::::0;::::2;:::i;:::-;;;;17982:374;;;-1:-1:-1::0;18394:24:9::2;::::0;-1:-1:-1;;;18394:24:9;;-1:-1:-1;;;;;10691:32:12;;;18394:24:9::2;::::0;::::2;10673:51:12::0;18368:23:9::2;::::0;18394:17;;::::2;::::0;::::2;::::0;10646:18:12;;18394:24:9::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;::::0;;::::2;-1:-1:-1::0;;18394:24:9::2;::::0;::::2;;::::0;::::2;::::0;;;::::2;::::0;::::2;:::i;:::-;18368:50;;18442:7;18450:1;18442:10;;;;;;-1:-1:-1::0;;;18442:10:9::2;;;;;;;;;;;;;;;18429:23;;;;;:::i;:::-;::::0;-1:-1:-1;18480:1:9::2;18463:293;18487:7;18483:1;:11;18463:293;;;18533:1;18520:7;18528:1;18520:10;;;;;;-1:-1:-1::0;;;18520:10:9::2;;;;;;;;;;;;;;;:14;18516:229;;;18556:16;18593:8;18602:1;18593:11;;;;;;-1:-1:-1::0;;;18593:11:9::2;;;;;;;;;;;;;;;;;;;:26;;;;;;;;;;-1:-1:-1::0;;;;;18593:26:9::2;-1:-1:-1::0;;;;;18578:59:9::2;;18638:17;:7;18646:1;18638:10;;;;;;-1:-1:-1::0;;;18638:10:9::2;;;;;;;;;;;;;;;:15;:17::i;:::-;18657:24;:8;18666:1;18657:11;;;;;;-1:-1:-1::0;;;18657:11:9::2;;;;;;;;;;;;;;;;;;;:17;;;:22;:24::i;:::-;18578:104;::::0;-1:-1:-1;;;;;;18578:104:9::2;::::0;;;;;;::::2;::::0;::::2;15081:25:12::0;;;;15122:18;;;15115:34;15054:18;;18578:104:9::2;::::0;::::2;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18555:127;;;18714:15;:8;:13;:15::i;:::-;18701:28;::::0;;::::2;:::i;:::-;;;18516:229;;18496:3:::0;::::2;::::0;::::2;:::i;:::-;;;;18463:293;;;-1:-1:-1::0;18768:13:9::2;18811:21;18862;18898:22:::0;;::::2;18894:281;;18946:9;18937:18;;18894:281;;;18990:9;18977;:22;18973:202;;19025:9;19016:18;;18973:202;;;19076:87;19152:10;19132:9:::0;792:6:::2;19103:20;19078:21;19132:9:::0;19078;:21:::2;:::i;:::-;19077:46;;;;:::i;:::-;:52;;;;:::i;:::-;:64;;;;:::i;:::-;19076:75:::0;::::2;:87::i;:::-;19067:96;;18973:202;19188:25;19215:31:::0;19250:34:::2;19276:7;19250:25;:34::i;:::-;19187:97:::0;;-1:-1:-1;19187:97:9;-1:-1:-1;19295:89:9::2;19319:18;19331:6:::0;19319:9;:18:::2;:::i;:::-;19339;19359:15;19376:7;19295:23;:89::i;:::-;19397:18;::::0;-1:-1:-1;;;19397:18:9;;-1:-1:-1;;;;;10691:32:12;;;19397:18:9::2;::::0;::::2;10673:51:12::0;19397:11:9;::::2;::::0;::::2;::::0;10646:18:12;;19397::9::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;19426:97;19473:10;19485:37;19507:2;19511:10;19485:13;:6;:11;:13::i;:::-;:21:::0;:37;:21:::2;:37::i;:::-;19433:8;19442:1;19433:11;;;;;;-1:-1:-1::0;;;19433:11:9::2;;;;;;;;;;::::0;;;::::2;::::0;;;::::2;::::0;;::::2;;:25:::0;-1:-1:-1;;;;;19433:25:9::2;::::0;19426:97;:46:::2;:97::i;:::-;19558:10;-1:-1:-1::0;;;;;19541:43:9::2;19551:5;-1:-1:-1::0;;;;;19541:43:9::2;;19570:13;:6;:11;:13::i;:::-;19541:43;::::0;14873:25:12;;;14861:2;14846:18;19541:43:9::2;14828:76:12::0;4069:132:9;4138:17;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4138:17:9;4175:8;4184;4175:18;;;;;;-1:-1:-1;;;4175:18:9;;;;;;;;;;;;;;;;;;4168:25;;;;;;;;4175:18;;;;;;;4168:25;;-1:-1:-1;;;;;4168:25:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4069:132;-1:-1:-1;;4069:132:9:o;4775:511::-;4834:12;4856:8;4865:1;4856:11;;;;;;-1:-1:-1;;;4856:11:9;;;;;;;;;;;;;;;;;;;;;:25;;4910:19;-1:-1:-1;;;;;4856:25:9;;;;-1:-1:-1;4910:50:9;;4945:2;;4949:10;;4910:26;;:24;:26::i;:50::-;4984:30;;-1:-1:-1;;;4984:30:9;;5008:4;4984:30;;;10673:51:12;4893:67:9;;-1:-1:-1;;;;;;4984:15:9;;;;;10646:18:12;;4984:30:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4975:6;:39;4971:84;;;5025:30;;-1:-1:-1;;;5025:30:9;;5049:4;5025:30;;;10673:51:12;-1:-1:-1;;;;;5025:15:9;;;;;10646:18:12;;5025:30:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5016:39;;4971:84;5089:37;:30;:6;5104:10;5116:2;5089:14;:30::i;:37::-;5066:19;;:60;;;;;;;:::i;:::-;;;;-1:-1:-1;5137:49:9;;-1:-1:-1;;;;;;5137:18:9;;5156:21;5179:6;5137:18;:49::i;:::-;-1:-1:-1;;;;;5224:21:9;5202:76;;5247:30;:6;5262:10;5274:2;5247:14;:30::i;:::-;5202:76;;14873:25:12;;;14861:2;14846:18;5202:76:9;;;;;;;4775:511;;:::o;13774:1180::-;1826:10;-1:-1:-1;;;;;1840:14:9;1826:28;;1818:52;;;;-1:-1:-1;;;1818:52:9;;;;;;;:::i;:::-;1692:6:::1;::::0;::::1;;1691:7;1683:27;;;;-1:-1:-1::0;;;1683:27:9::1;;;;;;;:::i;:::-;1721:6;:13:::0;;-1:-1:-1;;1721:13:9::1;1730:4;1721:13;::::0;;13925:47:::2;13955:7:::0;13964;13925:29:::2;:47::i;:::-;13983:39;14007:5;14014:7;13983:23;:39::i;:::-;14033:32;14050:5;14057:7;14033:16;:32::i;:::-;14078:14;14103;14078:40;;14129:20;14152:8;14161;14152:18;;;;;;-1:-1:-1::0;;;14152:18:9::2;;;;;;;;;;::::0;;;::::2;::::0;;;::::2;::::0;;::::2;;14200:10;::::0;::::2;::::0;14152:18;;-1:-1:-1;14231:26:9::2;:7:::0;14200:10;14231:16:::2;:26::i;:::-;14221:36;;14270:13;14286:14;:7;:12;:14::i;:::-;14327:33;::::0;-1:-1:-1;;;14327:33:9;;-1:-1:-1;;;;;12829:32:12;;;14327:33:9::2;::::0;::::2;12811:51:12::0;12878:18;;;12871:34;;;14270:30:9;;-1:-1:-1;14311:13:9::2;::::0;14327:16;::::2;::::0;::::2;::::0;12784:18:12;;14327:33:9::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14311:49;;14387:6;14377;:16;14373:266;;14420:13;:6;:11;:13::i;:::-;14410:23:::0;-1:-1:-1;14452:13:9;14448:78:::2;;14499:27;:6:::0;14515:10:::2;14499:15;:27::i;:::-;14490:36;::::0;:6;:36:::2;:::i;:::-;14467:19;;:59;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;14448:78:9::2;-1:-1:-1::0;14577:1:9::2;14373:266;;;14611:16;14621:6:::0;14611:16;::::2;:::i;:::-;;;14373:266;14649:44;::::0;-1:-1:-1;;;14649:44:9;;-1:-1:-1;;;;;14649:19:9;::::2;::::0;::::2;::::0;:44:::2;::::0;14669:5;;14676:8;;14686:6;;14649:44:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;14764:22;14714:46;14736:5;14743:7;14752;14714:21;:46::i;:::-;:72;;14706:99;;;::::0;-1:-1:-1;;;14706:99:9;;15926:2:12;14706:99:9::2;::::0;::::2;15908:21:12::0;15965:2;15945:18;;;15938:30;-1:-1:-1;;;15984:18:12;;;15977:44;16038:18;;14706:99:9::2;15898:164:12::0;14706:99:9::2;14818:74;14855:5:::0;14862:29:::2;:7:::0;14878:2:::2;14882:8:::0;14862:15:::2;:29::i;:::-;14825:15:::0;;-1:-1:-1;;;;;14825:15:9::2;::::0;14818:74;:36:::2;:74::i;:::-;14928:8;14921:5;-1:-1:-1::0;;;;;14908:38:9::2;;14938:7;14908:38;;;;14873:25:12::0;;14861:2;14846:18;;14828:76;6932:357:9;1826:10;-1:-1:-1;;;;;1840:14:9;1826:28;;1818:52;;;;-1:-1:-1;;;1818:52:9;;;;;;;:::i;:::-;7090:20:::1;7113:8;7122;7113:18;;;;;;-1:-1:-1::0;;;7113:18:9::1;;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;7142:15;::::0;::::1;:31:::0;;-1:-1:-1;;;;;;7142:31:9::1;-1:-1:-1::0;;;;;7142:31:9;;;::::1;::::0;;;::::1;::::0;;;-1:-1:-1;7184:10:9::1;::::0;::::1;:29:::0;;;;7224:24:::1;::::0;;::::1;:57:::0;-1:-1:-1;6932:357:9:o;20829:179::-;20899:13;;20895:105;;20941:59;20949:8;20958;20949:18;;;;;;-1:-1:-1;;;20949:18:9;;;;;;;;;;;;;;;;;;;:32;;;;;;;;;;-1:-1:-1;;;;;20949:32:9;-1:-1:-1;;;;;20941:50:9;;:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:59;20914:8;20923;20914:18;;;;;;-1:-1:-1;;;20914:18:9;;;;;;;;;;;;;;;;;;;:24;;:86;;;;20829:179;:::o;20059:541::-;20152:19;20215:16;20174:12;;20201:30;;20197:396;;;20249:25;20276:31;20311:34;20337:7;20311:25;:34::i;:::-;20248:97;;;;20360:23;20386:48;20406:18;20426:7;20386:19;:48::i;:::-;20360:74;;20449:87;20473:16;20491:18;20511:15;20528:7;20449:23;:87::i;:::-;-1:-1:-1;;;20551:16:9;:30;;;20197:396;20059:541;;;:::o;1349:173:11:-;1419:7;1446:8;1458:2;1446:14;:68;;1467:47;1475:24;1483:1;1486:2;1490:8;1475:7;:24::i;:::-;1501:8;1511:2;1467:7;:47::i;:::-;1446:68;;;1463:1;1446:68;1439:75;;1349:173;;;;;:::o;212:127::-;260:6;-1:-1:-1;;;;;287:1:11;:9;;279:25;;;;-1:-1:-1;;;279:25:11;;17016:2:12;279:25:11;;;16998:21:12;17055:1;17035:18;;;17028:29;-1:-1:-1;;;17073:18:12;;;17066:33;17116:18;;279:25:11;16988:152:12;279:25:11;-1:-1:-1;329:1:11;212:127::o;1650:171::-;1719:6;1745:8;1757:2;1745:14;:68;;1766:47;1774:24;1782:1;1785:2;1789:8;1774:7;:24::i;:::-;1800:8;1810:2;1766:7;:47::i;1934:322::-;1999:6;2047:1;2022:21;2031:1;2034:8;2022;:21::i;:::-;:26;2018:231;;;-1:-1:-1;2072:1:11;2065:8;;2018:231;2106:8;2117:24;2125:1;2128:2;2132:8;2117:7;:24::i;:::-;2106:35;;2165:1;2161;:5;:30;;-1:-1:-1;;2161:30:11;;;2176:1;2161:30;2156:35;;;;:::i;:::-;;;2213:24;2221:1;2224:8;2234:2;2213:7;:24::i;:::-;2206:31;;;;;382:125;429:7;462:1;457;:6;;449:22;;;;-1:-1:-1;;;449:22:11;;20224:2:12;449:22:11;;;20206:21:12;20263:1;20243:18;;;20236:29;-1:-1:-1;;;20281:18:12;;;20274:33;20324:18;;449:22:11;20196:152:12;21016:718:9;21091:6;21099:15;21127:25;21163:31;21210:7;21197:21;;;;;;-1:-1:-1;;;21197:21:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21197:21:9;;21163:55;;21234:9;21229:443;21253:7;21249:1;:11;21229:443;;;21282:20;21305:8;21314:1;21305:11;;;;;;-1:-1:-1;;;21305:11:9;;;;;;;;;;;;;;;;;;;21282:34;;21331:16;21350:1;:11;;;21331:30;;21436:13;21499:1;:5;;;792:6;21480:1;:10;;;792:6;21464:1;:7;;;21452:9;:19;;;;:::i;:::-;:25;;;;:::i;:::-;:38;;;;:::i;:::-;:44;;;;:::i;:::-;:52;;;;:::i;:::-;21436:68;;21535:1;21523:9;:13;:27;;;;;21549:1;21540:6;:10;21523:27;21519:142;;;21571:28;21593:6;21571:28;;:::i;:::-;;;21639:6;21618:15;21634:1;21618:18;;;;;;-1:-1:-1;;;21618:18:9;;;;;;;;;;;;;;:27;;;;;21519:142;21229:443;;;21262:3;;;;;:::i;:::-;;;;21229:443;;;-1:-1:-1;21690:18:9;;21710:15;;-1:-1:-1;21016:718:9;-1:-1:-1;;21016:718:9:o;24219:690::-;24315:6;24334:16;24366:9;24361:451;24385:7;24381:1;:11;24361:451;;;24414:20;24437:8;24446:1;24437:11;;;;;;-1:-1:-1;;;24437:11:9;;;;;;;;;;;;;;;;;;;24414:34;;24463:23;24489:1;:18;;;24463:44;;24526:16;24546:1;24526:21;24522:279;;24568:11;792:6;24617:1;:12;;;792:6;24601:1;:7;;;24582:16;:26;;;;:::i;:::-;:32;;;;:::i;:::-;:47;;;;:::i;:::-;:53;;;;:::i;:::-;24568:67;;24683:1;:16;;;24676:4;:23;;;;:::i;:::-;24654:45;;;;:::i;:::-;;;24731:10;:4;:8;:10::i;:::-;24718:23;;;;:::i;:::-;;;24522:279;;24361:451;;24394:3;;;;;:::i;:::-;;;;24361:451;;;-1:-1:-1;24829:14:9;;:72;;24892:9;24865:24;792:6;24865:18;:24;:::i;:::-;:36;;;;:::i;:::-;24829:72;;;-1:-1:-1;;;;;24829:72:9;24822:79;24219:690;-1:-1:-1;;;;24219:690:9:o;751:194:11:-;840:7;880:9;867;:22;:70;;921:15;927:9;921:2;:15;:::i;:::-;901;907:9;901:2;:15;:::i;:::-;896:21;;:1;:21;:::i;:::-;:41;;;;:::i;:::-;867:70;;;892:1;867:70;860:77;;751:194;;;;;;:::o;649:177:10:-;759:58;;-1:-1:-1;;;;;12829:32:12;;759:58:10;;;12811:51:12;12878:18;;;12871:34;;;732:86:10;;752:5;;-1:-1:-1;;;782:23:10;12784:18:12;;759:58:10;;;;-1:-1:-1;;759:58:10;;;;;;;;;;;;;;-1:-1:-1;;;;;759:58:10;-1:-1:-1;;;;;;759:58:10;;;;;;;;;;732:19;:86::i;27904:463:9:-;28154:19;;-1:-1:-1;;;28154:19:9;;-1:-1:-1;;;;;10691:32:12;;;28154:19:9;;;10673:51:12;28061:7:9;;28108:13;;28061:7;;28154:15;;;;;;10646:18:12;;28154:19:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28135:38;-1:-1:-1;28184:63:9;28207:4;28213:2;28217:29;:7;28233:2;28237:8;28217:15;:29::i;:::-;-1:-1:-1;;;;;28184:22:9;;;:63;;:22;:63::i;:::-;28277:19;;-1:-1:-1;;;28277:19:9;;-1:-1:-1;;;;;10691:32:12;;;28277:19:9;;;10673:51:12;28258:16:9;;28277:15;;;;;;10646:18:12;;28277:19:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28258:38;-1:-1:-1;28316:43:9;28346:8;28356:2;28317:19;28328:8;28258:38;28317:19;:::i;28316:43::-;28309:50;27904:463;-1:-1:-1;;;;;;;;;27904:463:9:o;25063:939::-;25262:26;;-1:-1:-1;;;25262:26:9;;-1:-1:-1;;;;;10691:32:12;;;25262:26:9;;;10673:51:12;25173:14:9;;25148;;;;25262:19;;;;;;10646:18:12;;25262:26:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;25262:26:9;;;;;;;;;;;;:::i;:::-;25224:64;;25304:9;25299:537;25323:7;25319:1;:11;25299:537;;;25352:25;25380:9;25390:1;25380:12;;;;;;-1:-1:-1;;;25380:12:9;;;;;;;;;;;;;;;25352:40;;25411:1;:8;;;25423:1;25411:13;25407:418;;25445:28;25476:8;25485:1;25476:11;;;;;;-1:-1:-1;;;25476:11:9;;;;;;;;;;;;;;;;;;;:33;;;25445:64;;25528:12;25603:1;:27;;;25579:21;:51;25571:59;;792:6;25673:5;25662:1;:8;;;:16;;;;:::i;:::-;:22;;;;:::i;:::-;25651:33;;;;:::i;:::-;25705:27;;;;:51;;;25775:34;-1:-1:-1;;;25775:34:9;;25651:33;;-1:-1:-1;;;;;;25775:21:9;;;;;:34;;25797:5;;25804:1;;25705;;25775:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25407:418;;;-1:-1:-1;25332:3:9;;;;:::i;:::-;;;;25299:537;;;-1:-1:-1;25850:12:9;;25846:149;;25895:26;;-1:-1:-1;;;25895:26:9;;-1:-1:-1;;;;;12829:32:12;;;25895:26:9;;;12811:51:12;25879:13:9;12878:18:12;;;12871:34;;;25879:13:9;25924:7;;25895:16;;;;;12784:18:12;;25895:26:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:36;;;;:::i;:::-;25946:37;;-1:-1:-1;;;25946:37:9;;25879:52;;-1:-1:-1;;;;;;25946:19:9;;;;;:37;;25966:5;;25973:1;;25879:52;;25946:37;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25846:149;25063:939;;;;;:::o;543:130:11:-;589:6;-1:-1:-1;;;616:1:11;:9;;608:24;;;;-1:-1:-1;;;608:24:11;;17684:2:12;608:24:11;;;17666:21:12;17723:1;17703:18;;;17696:29;-1:-1:-1;;;17741:18:12;;;17734:32;17783:18;;608:24:11;17656:151:12;608:24:11;655:1;650;:6;;:15;;663:2;664:1;663:2;:::i;21742:700:9:-;21909:1;21888:18;:22;:34;;;;-1:-1:-1;21914:8:9;;;21888:34;21884:551;;;21944:9;21939:485;21963:7;21959:1;:11;21939:485;;;22021:1;22000:15;22016:1;22000:18;;;;;;-1:-1:-1;;;22000:18:9;;;;;;;;;;;;;;;:22;21996:413;;;22047:20;22070:8;22079:1;22070:11;;;;;;-1:-1:-1;;;22070:11:9;;;;;;;;;;;;;;;;;;;22047:34;;22104:21;22155:18;22134:15;22150:1;22134:18;;;;;;-1:-1:-1;;;22134:18:9;;;;;;;;;;;;;;;22128:3;:24;;;;:::i;:::-;:45;;;;:::i;:::-;22104:69;;22205:14;22196:1;:5;;;:23;;;;;;;:::i;:::-;;;;-1:-1:-1;;22378:11:9;;;;22355:20;792:6;22355:14;:20;:::i;:::-;:34;;;;:::i;:::-;22336:1;:15;;;:53;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;21996:413:9;21972:3;;;;:::i;:::-;;;;21939:485;;21884:551;21742:700;;;;:::o;26876:1020::-;27077:24;;-1:-1:-1;;;27077:24:9;;-1:-1:-1;;;;;10691:32:12;;;27077:24:9;;;10673:51:12;26979:6:9;;27023:14;;26979:6;;27077:17;;;;;;10646:18:12;;27077:24:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;27077:24:9;;;;;;;;;;;;:::i;:::-;27051:50;;27112:25;27140:7;27148:1;27140:10;;;;;;-1:-1:-1;;;27140:10:9;;;;;;;;;;;;;;;27112:38;;27161:16;27193:9;27205:1;27193:13;;27188:152;27212:7;27208:1;:11;27188:152;;;792:6;27302:8;27311:1;27302:11;;;;;;-1:-1:-1;;;27302:11:9;;;;;;;;;;;;;;;;;;;:20;;;792:6;27276:8;27285:1;27276:11;;;;;;-1:-1:-1;;;27276:11:9;;;;;;;;;;;;;;;;;;;:17;;;27263:7;27271:1;27263:10;;;;;;-1:-1:-1;;;27263:10:9;;;;;;;;;;;;;;;:30;;;;:::i;:::-;:36;;;;:::i;:::-;:59;;;;:::i;:::-;:65;;;;:::i;:::-;27241:87;;;;:::i;:::-;;-1:-1:-1;27221:3:9;;;;:::i;:::-;;;;27188:152;;;-1:-1:-1;27390:26:9;;-1:-1:-1;;;27390:26:9;;-1:-1:-1;;;;;10691:32:12;;;27390:26:9;;;10673:51:12;27352:35:9;;27390:19;;;;;;10646:18:12;;27390:26:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;27390:26:9;;;;;;;;;;;;:::i;:::-;27352:64;;27432:9;27427:370;27451:7;27447:1;:11;27427:370;;;27484:9;27494:1;27484:12;;;;;;-1:-1:-1;;;27484:12:9;;;;;;;;;;;;;;;:19;;;27507:1;27484:24;27480:306;;27529:11;792:6;27591:8;27600:1;27591:11;;;;;;-1:-1:-1;;;27591:11:9;;;;;;;;;;;;;;;;;;;:22;;;792:6;27565:8;27574:1;27565:11;;;;;;-1:-1:-1;;;27565:11:9;;;;;;;;;;;;;;;;;;;:17;;;27543:9;27553:1;27543:12;;;;;;-1:-1:-1;;;27543:12:9;;;;;;;;;;;;;;;:19;;;:39;;;;:::i;:::-;:45;;;;:::i;:::-;:70;;;;:::i;:::-;:76;;;;:::i;:::-;27529:90;;27667:9;27677:1;27667:12;;;;;;-1:-1:-1;;;27667:12:9;;;;;;;;;;;;;;;:17;;;27660:4;:24;;;;:::i;:::-;27638:46;;;;:::i;:::-;;;27716:10;:4;:8;:10::i;:::-;27703:23;;;;:::i;:::-;;;27480:306;;27460:3;;;;:::i;:::-;;;;27427:370;;;-1:-1:-1;27816:14:9;;:72;;27879:9;27852:24;792:6;27852:18;:24;:::i;:::-;:36;;;;:::i;:::-;27816:72;;;-1:-1:-1;;;;;27809:79:9;26876:1020;-1:-1:-1;;;;;;;;;26876:1020:9:o;1308:622:10:-;1678:10;;;1677:62;;-1:-1:-1;1694:39:10;;-1:-1:-1;;;1694:39:10;;1718:4;1694:39;;;10947:34:12;-1:-1:-1;;;;;11017:15:12;;;10997:18;;;10990:43;1694:15:10;;;;;10882:18:12;;1694:39:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;1677:62;1669:152;;;;-1:-1:-1;;;1669:152:10;;19466:2:12;1669:152:10;;;19448:21:12;19505:2;19485:18;;;19478:30;19544:34;19524:18;;;19517:62;-1:-1:-1;;;19595:18:12;;;19588:52;19657:19;;1669:152:10;19438:244:12;1669:152:10;1859:62;;-1:-1:-1;;;;;12829:32:12;;1859:62:10;;;12811:51:12;12878:18;;;12871:34;;;1832:90:10;;1852:5;;-1:-1:-1;;;1882:22:10;12784:18:12;;1859:62:10;12766:145:12;23978:233:9;24087:6;24113:23;;:90;;24185:18;792:6;24158:15;24174:1;24158:18;;;;;;-1:-1:-1;;;24158:18:9;;;;;;;;;;;;;;;:24;;;;:::i;:::-;:45;;;;:::i;24113:90::-;-1:-1:-1;;;;;;24139:16:9;23978:233;-1:-1:-1;;23978:233:9:o;20608:213::-;20694:1;20677:137;20701:7;20697:1;:11;20677:137;;;20750:52;20758:8;20767:1;20758:11;;;;;;-1:-1:-1;;;20758:11:9;;;;;;;;20750:52;20730:8;20739:1;20730:11;;;;;;-1:-1:-1;;;20730:11:9;;;;;;;;;;;;;;;;;:17;:11;;;;;:17;:72;20710:3;;;;:::i;:::-;;;;20677:137;;;;20608:213;:::o;26010:858::-;26165:24;;-1:-1:-1;;;26165:24:9;;-1:-1:-1;;;;;10691:32:12;;;26165:24:9;;;10673:51:12;26113:14:9;;26088;;26165:17;;;;;10646:18:12;;26165:24:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;26165:24:9;;;;;;;;;;;;:::i;:::-;26139:50;;26217:1;26204:7;26212:1;26204:10;;;;;;-1:-1:-1;;;26204:10:9;;;;;;;;;;;;;;;:14;26200:661;;;26235:16;;;26314:11;26324:1;26314:7;:11;:::i;:::-;26302:23;;26297:502;26327:5;;26297:502;;26375:1;26362:7;26370:1;26362:10;;;;;;-1:-1:-1;;;26362:10:9;;;;;;;;;;;;;;;:14;26358:381;;;26439:8;26448:1;26439:11;;;;;;-1:-1:-1;;;26439:11:9;;;;;;;;;;;;;;;;;;;:26;;;;;;;;;;-1:-1:-1;;;;;26439:26:9;-1:-1:-1;;;;;26424:59:9;;26510:37;:30;26529:10;26512:7;26520:1;26512:10;;;;;;-1:-1:-1;;;26512:10:9;;;;;;;;;;;;;;;26511:11;;;:::i;26510:37::-;26549:17;:7;26557:1;26549:10;;;;;;-1:-1:-1;;;26549:10:9;;;;;;;;:17;26568:24;:8;26577:1;26568:11;;;;;;-1:-1:-1;;;26568:11:9;;;;;;;;:24;26424:191;;-1:-1:-1;;;;;;26424:191:9;;;;;;;;;;23616:25:12;;;;23657:18;;;23650:34;;;;23700:18;;;23693:34;23589:18;;26424:191:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;26401:214;;-1:-1:-1;26401:214:9;-1:-1:-1;26652:15:9;26401:214;26652:13;:15::i;:::-;26638:7;26646:1;26638:10;;;;;;-1:-1:-1;;;26638:10:9;;;;;;;;;;;;;;:29;;;;;;;:::i;:::-;;;-1:-1:-1;26704:15:9;:8;:13;:15::i;:::-;26690:7;26698:1;26690:10;;;;;;-1:-1:-1;;;26690:10:9;;;;;;;;;;;;;;:29;;;;;;;:::i;:::-;;;-1:-1:-1;26358:381:9;26775:1;26761:7;26769:1;26761:10;;;;;;-1:-1:-1;;;26761:10:9;;;;;;;;;;;;;;;:15;26757:26;;26778:5;;26757:26;26334:3;;;;:::i;:::-;;;;26297:502;;;-1:-1:-1;26813:36:9;;-1:-1:-1;;;26813:36:9;;-1:-1:-1;;;;;26813:20:9;;;;;:36;;26834:5;;26841:7;;26813:36;;;:::i;22872:1098::-;22963:6;23008:1;22986:18;:23;22982:37;;-1:-1:-1;23018:1:9;23011:8;;22982:37;23030:23;;23064:865;23088:7;23084:1;:11;23064:865;;;23117:20;23140:8;23149:1;23140:11;;;;;;-1:-1:-1;;;23140:11:9;;;;;;;;;;;;;;;;;;;23117:34;;23166:12;23181:42;23189:1;:15;;;;;;;;;;-1:-1:-1;;;;;23189:15:9;-1:-1:-1;;;;;23181:33:9;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:42;23264:18;;;;23166:57;;-1:-1:-1;23301:21:9;;23297:591;;23363:12;;;;23501:24;;;;23343:17;;23528:18;;792:6;23363:12;792:6;23363:12;792:6;23449:5;792:6;23416:24;23449:5;23416:16;:24;:::i;:::-;:30;;;;:::i;:::-;:38;;;;:::i;:::-;:44;;;;:::i;:::-;:57;;;;:::i;:::-;:63;;;;:::i;:::-;:76;;;;:::i;:::-;:82;;;;:::i;:::-;:109;;;;:::i;:::-;:130;;;;:::i;:::-;23394:152;;23565:12;23617:16;;23602:12;:31;;;;:::i;:::-;23580:54;;:12;:54;:::i;:::-;23565:69;-1:-1:-1;792:6:9;23675:24;23565:69;23675:16;:24;:::i;:::-;:30;;;;:::i;:::-;23655:50;;;;:::i;:::-;;;792:6;23789:10;792:6;23772:1;:7;;;23764:5;:15;;;;:::i;:::-;23744:36;;:16;:36;:::i;:::-;:42;;;;:::i;:::-;:55;;;;:::i;:::-;:61;;;;:::i;:::-;23724:81;;;;:::i;:::-;23838:23;;;:32;;;;;;;;23724:81;-1:-1:-1;;;23297:591:9;-1:-1:-1;23902:7:9;;;;:15;23097:3;;;;:::i;:::-;;;;23064:865;;;-1:-1:-1;23946:16:9;22872:1098;-1:-1:-1;;;22872:1098:9:o;1020:200:11:-;1108:6;1147:9;1134;:22;:78;;1191:21;1196:15;1202:9;1196:2;:15;:::i;1191:21::-;1167;1172:15;1178:9;1172:2;:15;:::i;1167:21::-;1163:25;;:1;:25;:::i;:::-;:49;;;;:::i;2903:761:10:-;3327:23;3353:69;3381:4;3353:69;;;;;;;;;;;;;;;;;3361:5;-1:-1:-1;;;;;3353:27:10;;;:69;;;;;:::i;:::-;3437:17;;3327:95;;-1:-1:-1;3437:21:10;3433:224;;3579:10;3568:30;;;;;;;;;;;;:::i;:::-;3560:85;;;;-1:-1:-1;;;3560:85:10;;18715:2:12;3560:85:10;;;18697:21:12;18754:2;18734:18;;;18727:30;18793:34;18773:18;;;18766:62;-1:-1:-1;;;18844:18:12;;;18837:40;18894:19;;3560:85:10;18687:232:12;834:205:10;962:68;;-1:-1:-1;;;;;11772:15:12;;;962:68:10;;;11754:34:12;11824:15;;11804:18;;;11797:43;11856:18;;;11849:34;;;935:96:10;;955:5;;-1:-1:-1;;;985:27:10;11689:18:12;;962:68:10;11671:218:12;3669:195:0;3772:12;3804:52;3826:6;3834:4;3840:1;3843:12;3772;1118:20;;4965:60;;;;-1:-1:-1;;;4965:60:0;;18014:2:12;4965:60:0;;;17996:21:12;18053:2;18033:18;;;18026:30;18092:31;18072:18;;;18065:59;18141:18;;4965:60:0;17986:179:12;4965:60:0;5099:12;5113:23;5140:6;-1:-1:-1;;;;;5140:11:0;5160:5;5168:4;5140:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5098:75;;;;5191:52;5209:7;5218:10;5230:12;5191:17;:52::i;:::-;5184:59;4721:530;-1:-1:-1;;;;;;;4721:530:0:o;6257:742::-;6372:12;6401:7;6397:595;;;-1:-1:-1;6432:10:0;6425:17;;6397:595;6546:17;;:21;6542:439;;6809:10;6803:17;6870:15;6857:10;6853:2;6849:19;6842:44;6757:148;6952:12;6945:20;;-1:-1:-1;;;6945:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:173:12;82:20;;-1:-1:-1;;;;;131:31:12;;121:42;;111:2;;177:1;174;167:12;111:2;63:124;;;:::o;192:551::-;235:5;288:3;281:4;273:6;269:17;265:27;255:2;;310:5;303;296:20;255:2;350:6;337:20;376:18;372:2;369:26;366:2;;;398:18;;:::i;:::-;442:55;485:2;466:13;;-1:-1:-1;;462:27:12;491:4;458:38;442:55;:::i;:::-;522:2;513:7;506:19;568:3;561:4;556:2;548:6;544:15;540:26;537:35;534:2;;;589:5;582;575:20;534:2;658;651:4;643:6;639:17;632:4;623:7;619:18;606:55;681:16;;;699:4;677:27;670:42;;;;685:7;245:498;-1:-1:-1;;245:498:12:o;748:534::-;811:5;859:4;847:9;842:3;838:19;834:30;831:2;;;881:5;874;867:20;831:2;918;912:9;960:4;952:6;948:17;1031:6;1019:10;1016:22;995:18;983:10;980:34;977:62;974:2;;;1042:18;;:::i;:::-;1082:10;1078:2;1071:22;;1111:6;1102:15;;1147:9;1141:16;1133:6;1126:32;1212:2;1201:9;1197:18;1191:25;1186:2;1178:6;1174:15;1167:50;1271:2;1260:9;1256:18;1250:25;1245:2;1237:6;1233:15;1226:50;;821:461;;;;:::o;1287:196::-;1346:6;1399:2;1387:9;1378:7;1374:23;1370:32;1367:2;;;1420:6;1412;1405:22;1367:2;1448:29;1467:9;1448:29;:::i;1488:407::-;1574:6;1582;1590;1598;1651:3;1639:9;1630:7;1626:23;1622:33;1619:2;;;1673:6;1665;1658:22;1619:2;1701:29;1720:9;1701:29;:::i;:::-;1691:39;;1749:38;1783:2;1772:9;1768:18;1749:38;:::i;:::-;1609:286;;1739:48;;-1:-1:-1;;;;1834:2:12;1819:18;;1806:32;;1885:2;1870:18;1857:32;;1609:286::o;1900:469::-;1994:6;2002;2010;2018;2026;2079:3;2067:9;2058:7;2054:23;2050:33;2047:2;;;2101:6;2093;2086:22;2047:2;2129:29;2148:9;2129:29;:::i;:::-;2119:39;2205:2;2190:18;;2177:32;;-1:-1:-1;2256:2:12;2241:18;;2228:32;;2307:2;2292:18;;2279:32;;-1:-1:-1;2358:3:12;2343:19;2330:33;;-1:-1:-1;2037:332:12;-1:-1:-1;;;2037:332:12:o;2374:::-;2451:6;2459;2467;2520:2;2508:9;2499:7;2495:23;2491:32;2488:2;;;2541:6;2533;2526:22;2488:2;2569:29;2588:9;2569:29;:::i;:::-;2559:39;2645:2;2630:18;;2617:32;;-1:-1:-1;2696:2:12;2681:18;;;2668:32;;2478:228;-1:-1:-1;;;2478:228:12:o;2711:470::-;2806:6;2814;2822;2830;2838;2891:3;2879:9;2870:7;2866:23;2862:33;2859:2;;;2913:6;2905;2898:22;3186:935;3280:6;3311:2;3354;3342:9;3333:7;3329:23;3325:32;3322:2;;;3375:6;3367;3360:22;3322:2;3413:9;3407:16;3446:18;3438:6;3435:30;3432:2;;;3483:6;3475;3468:22;3432:2;3511:22;;3564:4;3556:13;;3552:27;-1:-1:-1;3542:2:12;;3598:6;3590;3583:22;3542:2;3632;3626:9;3655:59;3671:42;3710:2;3671:42;:::i;:::-;3655:59;:::i;:::-;3736:3;3760:2;3755:3;3748:15;3788:2;3783:3;3779:12;3772:19;;3819:2;3815;3811:11;3867:7;3862:2;3856;3853:1;3849:10;3845:2;3841:19;3837:28;3834:41;3831:2;;;3893:6;3885;3878:22;3831:2;3920:6;3911:15;;3935:156;3949:2;3946:1;3943:9;3935:156;;;4006:10;;3994:23;;3967:1;3960:9;;;;;4037:12;;;;4069;;3935:156;;;-1:-1:-1;4110:5:12;3291:830;-1:-1:-1;;;;;;;3291:830:12:o;4126:1023::-;4246:6;4277:2;4320;4308:9;4299:7;4295:23;4291:32;4288:2;;;4341:6;4333;4326:22;4288:2;4379:9;4373:16;4412:18;4404:6;4401:30;4398:2;;;4449:6;4441;4434:22;4398:2;4477:22;;4530:4;4522:13;;4518:27;-1:-1:-1;4508:2:12;;4564:6;4556;4549:22;4508:2;4598;4592:9;4621:59;4637:42;4676:2;4637:42;:::i;4621:59::-;4714:15;;;4745:12;;;;4777:11;;;4807:4;4838:11;;;4830:20;;4826:29;;4823:42;-1:-1:-1;4820:2:12;;;4883:6;4875;4868:22;4820:2;4910:6;4901:15;;4925:194;4939:2;4936:1;4933:9;4925:194;;;4996:48;5036:7;5031:3;4996:48;:::i;:::-;4984:61;;4957:1;4950:9;;;;;5065:12;;;;5097;;;;4925:194;;;-1:-1:-1;5138:5:12;;4257:892;-1:-1:-1;;;;;;;;4257:892:12:o;5154:297::-;5221:6;5274:2;5262:9;5253:7;5249:23;5245:32;5242:2;;;5295:6;5287;5280:22;5242:2;5332:9;5326:16;5385:5;5378:13;5371:21;5364:5;5361:32;5351:2;;5412:6;5404;5397:22;5456:193;5525:6;5578:2;5566:9;5557:7;5553:23;5549:32;5546:2;;;5599:6;5591;5584:22;5546:2;-1:-1:-1;5627:16:12;;5536:113;-1:-1:-1;5536:113:12:o;5654:254::-;5746:6;5799:2;5787:9;5778:7;5774:23;5770:32;5767:2;;;5820:6;5812;5805:22;5767:2;5848:54;5894:7;5883:9;5848:54;:::i;5913:859::-;5999:6;6052:3;6040:9;6031:7;6027:23;6023:33;6020:2;;;6074:6;6066;6059:22;6020:2;6105:22;;:::i;:::-;6150:29;6169:9;6150:29;:::i;:::-;6143:5;6136:44;6212:38;6246:2;6235:9;6231:18;6212:38;:::i;:::-;6207:2;6200:5;6196:14;6189:62;6283:38;6317:2;6306:9;6302:18;6283:38;:::i;:::-;6278:2;6271:5;6267:14;6260:62;6382:2;6371:9;6367:18;6354:32;6349:2;6342:5;6338:14;6331:56;6448:3;6437:9;6433:19;6420:33;6414:3;6407:5;6403:15;6396:58;6515:3;6504:9;6500:19;6487:33;6481:3;6474:5;6470:15;6463:58;6582:3;6571:9;6567:19;6554:33;6548:3;6541:5;6537:15;6530:58;6649:3;6638:9;6634:19;6621:33;6615:3;6608:5;6604:15;6597:58;6674:3;6737:2;6726:9;6722:18;6709:32;6704:2;6697:5;6693:14;6686:56;;6761:5;6751:15;;;6010:762;;;;:::o;7039:1153::-;7125:6;7178:2;7166:9;7157:7;7153:23;7149:32;7146:2;;;7199:6;7191;7184:22;7146:2;7244:9;7231:23;7273:18;7314:2;7306:6;7303:14;7300:2;;;7335:6;7327;7320:22;7300:2;7363:22;;;;7419:6;7401:16;;;7397:29;7394:2;;;7444:6;7436;7429:22;7394:2;7475:22;;:::i;:::-;7535:2;7522:16;7563:2;7553:8;7550:16;7547:2;;;7584:6;7576;7569:22;7547:2;7616:45;7653:7;7642:8;7638:2;7634:17;7616:45;:::i;:::-;7609:5;7602:60;;7694:31;7721:2;7717;7713:11;7694:31;:::i;:::-;7689:2;7682:5;7678:14;7671:55;7779:2;7775;7771:11;7758:25;7753:2;7746:5;7742:14;7735:49;7837:2;7833;7829:11;7816:25;7811:2;7804:5;7800:14;7793:49;7896:3;7892:2;7888:12;7875:26;7869:3;7862:5;7858:15;7851:51;7956:3;7952:2;7948:12;7935:26;7929:3;7922:5;7918:15;7911:51;8016:3;8012:2;8008:12;7995:26;7989:3;7982:5;7978:15;7971:51;8076:3;8072:2;8068:12;8055:26;8049:3;8042:5;8038:15;8031:51;8101:3;8091:13;;8157:2;8153;8149:11;8136:25;8131:2;8124:5;8120:14;8113:49;8181:5;8171:15;;;;;7136:1056;;;;:::o;8197:190::-;8256:6;8309:2;8297:9;8288:7;8284:23;8280:32;8277:2;;;8330:6;8322;8315:22;8277:2;-1:-1:-1;8358:23:12;;8267:120;-1:-1:-1;8267:120:12:o;8591:407::-;8677:6;8685;8693;8701;8754:3;8742:9;8733:7;8729:23;8725:33;8722:2;;;8776:6;8768;8761:22;8722:2;8817:9;8804:23;8794:33;;8846:38;8880:2;8869:9;8865:18;8846:38;:::i;:::-;8836:48;;8903:38;8937:2;8926:9;8922:18;8903:38;:::i;:::-;8712:286;;;;-1:-1:-1;8893:48:12;;8988:2;8973:18;8960:32;;-1:-1:-1;;8712:286:12:o;9003:401::-;9089:6;9097;9105;9113;9166:3;9154:9;9145:7;9141:23;9137:33;9134:2;;;9188:6;9180;9173:22;9134:2;9229:9;9216:23;9206:33;;9258:38;9292:2;9281:9;9277:18;9258:38;:::i;9409:255::-;9488:6;9496;9549:2;9537:9;9528:7;9524:23;9520:32;9517:2;;;9570:6;9562;9555:22;9517:2;-1:-1:-1;;9598:16:12;;9654:2;9639:18;;;9633:25;9598:16;;9633:25;;-1:-1:-1;9507:157:12:o;9778:258::-;9820:3;9858:5;9852:12;9885:6;9880:3;9873:19;9901:63;9957:6;9950:4;9945:3;9941:14;9934:4;9927:5;9923:16;9901:63;:::i;:::-;10018:2;9997:15;-1:-1:-1;;9993:29:12;9984:39;;;;10025:4;9980:50;;9828:208;-1:-1:-1;;9828:208:12:o;10248:274::-;10377:3;10415:6;10409:13;10431:53;10477:6;10472:3;10465:4;10457:6;10453:17;10431:53;:::i;:::-;10500:16;;;;;10385:137;-1:-1:-1;;10385:137:12:o;11894:730::-;-1:-1:-1;;;;;12140:32:12;;12122:51;;12110:2;12192;12210:18;;;12203:30;;;12282:13;;12095:18;;;12304:22;;;12062:4;;12383:15;;;;12192:2;12357;12342:18;;;12062:4;12429:169;12443:6;12440:1;12437:13;12429:169;;;12504:13;;12492:26;;12573:15;;;;12538:12;;;;12465:1;12458:9;12429:169;;;-1:-1:-1;12615:3:12;;12071:553;-1:-1:-1;;;;;;;12071:553:12:o;12916:351::-;-1:-1:-1;;;;;13142:32:12;;;;13124:51;;13206:2;13191:18;;13184:34;;;;13249:2;13234:18;;13227:34;13112:2;13097:18;;13079:188::o;13899:407::-;-1:-1:-1;;;;;14164:32:12;;14146:51;;14228:2;14213:18;;14206:34;;;14133:3;14118:19;;14249:51;14296:2;14281:18;;14273:6;10112:12;;10100:25;;10174:4;10163:16;;;10157:23;10141:14;;;10134:47;10230:4;10219:16;;;10213:23;10197:14;;10190:47;10090:153;15160:220;15309:2;15298:9;15291:21;15272:4;15329:45;15370:2;15359:9;15355:18;15347:6;15329:45;:::i;18924:335::-;19126:2;19108:21;;;19165:2;19145:18;;;19138:30;-1:-1:-1;;;19199:2:12;19184:18;;19177:41;19250:2;19235:18;;19098:161::o;19687:330::-;19889:2;19871:21;;;19928:1;19908:18;;;19901:29;-1:-1:-1;;;19961:2:12;19946:18;;19939:37;20008:2;19993:18;;19861:156::o;20353:900::-;20576:13;;-1:-1:-1;;;;;20572:39:12;20554:58;;20659:4;20647:17;;;20641:24;20541:3;20526:19;;;20674:54;;20707:20;;20641:24;-1:-1:-1;;;;;9735:31:12;9723:44;;9713:60;20674:54;;20777:4;20769:6;20765:17;20759:24;20792:56;20842:4;20831:9;20827:20;20811:14;-1:-1:-1;;;;;9735:31:12;9723:44;;9713:60;20792:56;;20904:4;20896:6;20892:17;20886:24;20879:4;20868:9;20864:20;20857:54;20967:4;20959:6;20955:17;20949:24;20942:4;20931:9;20927:20;20920:54;21030:4;21022:6;21018:17;21012:24;21005:4;20994:9;20990:20;20983:54;21093:4;21085:6;21081:17;21075:24;21068:4;21057:9;21053:20;21046:54;21156:4;21148:6;21144:17;21138:24;21131:4;21120:9;21116:20;21109:54;21182:6;21242:2;21234:6;21230:15;21224:22;21219:2;21208:9;21204:18;21197:50;;20508:745;;;;:::o;21258:976::-;21441:2;21430:9;21423:21;21404:4;21479:6;21473:13;21505:6;21547:2;21542;21531:9;21527:18;21520:30;21573:52;21620:3;21609:9;21605:19;21591:12;21573:52;:::i;:::-;21559:66;;21674:2;21666:6;21662:15;21656:22;21687:54;21737:2;21726:9;21722:18;21706:14;-1:-1:-1;;;;;9735:31:12;9723:44;;9713:60;21687:54;;21795:2;21787:6;21783:15;21777:22;21772:2;21761:9;21757:18;21750:50;21855:2;21847:6;21843:15;21837:22;21831:3;21820:9;21816:19;21809:51;21915:3;21907:6;21903:16;21897:23;21891:3;21880:9;21876:19;21869:52;21976:3;21968:6;21964:16;21958:23;21952:3;21941:9;21937:19;21930:52;22037:3;22029:6;22025:16;22019:23;22013:3;22002:9;21998:19;21991:52;22080:3;22072:6;22068:16;22062:23;22104:3;22143:2;22138;22127:9;22123:18;22116:30;22200:2;22192:6;22188:15;22182:22;22177:2;22166:9;22162:18;22155:50;;;;22222:6;22214:14;;;21413:821;;;;:::o;23738:252::-;23810:2;23804:9;23852:3;23840:16;;23886:18;23871:34;;23907:22;;;23868:62;23865:2;;;23933:18;;:::i;:::-;23969:2;23962:22;23784:206;:::o;24255:275::-;24326:2;24320:9;24391:2;24372:13;;-1:-1:-1;;24368:27:12;24356:40;;24426:18;24411:34;;24447:22;;;24408:62;24405:2;;;24473:18;;:::i;:::-;24509:2;24502:22;24300:230;;-1:-1:-1;24300:230:12:o;24535:182::-;24594:4;24627:18;24619:6;24616:30;24613:2;;;24649:18;;:::i;:::-;-1:-1:-1;24694:1:12;24690:14;24706:4;24686:25;;24603:114::o;24722:267::-;24761:3;24789:11;;;24816:10;;-1:-1:-1;;;;;24835:27:12;;;24828:35;;24812:52;24809:2;;;24867:18;;:::i;:::-;-1:-1:-1;;;24914:19:12;;;24907:27;;24899:36;;24896:2;;;24938:18;;:::i;:::-;-1:-1:-1;;24974:9:12;;24769:220::o;24994:193::-;25033:1;25059;25049:2;;25064:18;;:::i;:::-;-1:-1:-1;;;25100:18:12;;-1:-1:-1;;25120:13:12;;25096:38;25093:2;;;25137:18;;:::i;:::-;-1:-1:-1;25171:10:12;;25039:148::o;25192:120::-;25232:1;25258;25248:2;;25263:18;;:::i;:::-;-1:-1:-1;25297:9:12;;25238:74::o;25317:422::-;25406:1;25449:5;25406:1;25463:270;25484:7;25474:8;25471:21;25463:270;;;25543:4;25539:1;25535:6;25531:17;25525:4;25522:27;25519:2;;;25552:18;;:::i;:::-;25602:7;25592:8;25588:22;25585:2;;;25622:16;;;;25585:2;25701:22;;;;25661:15;;;;25463:270;;;25467:3;25381:358;;;;;:::o;25744:131::-;25804:5;25833:36;25860:8;25854:4;25929:5;25959:8;25949:2;;-1:-1:-1;26000:1:12;26014:5;;25949:2;26048:4;26038:2;;-1:-1:-1;26085:1:12;26099:5;;26038:2;26130:4;26148:1;26143:59;;;;26216:1;26211:130;;;;26123:218;;26143:59;26173:1;26164:10;;26187:5;;;26211:130;26248:3;26238:8;26235:17;26232:2;;;26255:18;;:::i;:::-;-1:-1:-1;;26311:1:12;26297:16;;26326:5;;26123:218;;26425:2;26415:8;26412:16;26406:3;26400:4;26397:13;26393:36;26387:2;26377:8;26374:16;26369:2;26363:4;26360:12;26356:35;26353:77;26350:2;;;-1:-1:-1;26462:19:12;;;26494:5;;26350:2;26541:34;26566:8;26560:4;26541:34;:::i;:::-;26611:6;26607:1;26603:6;26599:19;26590:7;26587:32;26584:2;;;26622:18;;:::i;:::-;26660:20;;25939:747;-1:-1:-1;;;25939:747:12:o;26691:577::-;26730:7;-1:-1:-1;;;;;26800:15:12;;;26834;;;26865:11;;;26884:10;;;26878:17;;26861:35;26858:2;;;26899:18;;:::i;:::-;-1:-1:-1;;;26968:15:12;;;26999:11;;;27019;;;27012:19;;26995:37;26992:2;;;27035:18;;:::i;:::-;27081:7;27078:1;27074:15;27064:25;;27134:1;27130:2;27125:11;27122:1;27118:19;27113:2;27109;27105:11;27101:37;27098:2;;;27141:18;;:::i;:::-;27206:1;27202:2;27197:11;27194:1;27190:19;27185:2;27181;27177:11;27173:37;27170:2;;;27213:18;;:::i;:::-;-1:-1:-1;;;27253:9:12;;;;;26742:526;-1:-1:-1;;;26742:526:12:o;27273:168::-;27313:7;27379:1;27375;27371:6;27367:14;27364:1;27361:21;27356:1;27349:9;27342:17;27338:45;27335:2;;;27386:18;;:::i;:::-;-1:-1:-1;27426:9:12;;27325:116::o;27446:270::-;27485:4;27514:12;;;27542:10;;-1:-1:-1;;;27561:19:12;;27554:27;;27538:44;27535:2;;;27585:18;;:::i;:::-;-1:-1:-1;;;;;27632:27:12;;27625:35;;27617:44;;27614:2;;;27664:18;;:::i;:::-;-1:-1:-1;;27701:9:12;;27494:222::o;27721:125::-;27761:4;27789:1;27786;27783:8;27780:2;;;27794:18;;:::i;:::-;-1:-1:-1;27831:9:12;;27770:76::o;27851:258::-;27923:1;27933:113;27947:6;27944:1;27941:13;27933:113;;;28023:11;;;28017:18;28004:11;;;27997:39;27969:2;27962:10;27933:113;;;28064:6;28061:1;28058:13;28055:2;;;-1:-1:-1;;28099:1:12;28081:16;;28074:27;27904:205::o;28114:136::-;28153:3;28181:5;28171:2;;28190:18;;:::i;:::-;-1:-1:-1;;;28226:18:12;;28161:89::o;28255:380::-;28334:1;28330:12;;;;28377;;;28398:2;;28452:4;28444:6;28440:17;28430:27;;28398:2;28505;28497:6;28494:14;28474:18;28471:38;28468:2;;;28551:10;28546:3;28542:20;28539:1;28532:31;28586:4;28583:1;28576:15;28614:4;28611:1;28604:15;28468:2;;28310:325;;;:::o;28640:135::-;28679:3;-1:-1:-1;;28700:17:12;;28697:2;;;28720:18;;:::i;:::-;-1:-1:-1;28767:1:12;28756:13;;28687:88::o;28780:138::-;28815:3;-1:-1:-1;;;28836:22:12;;28833:2;;;28861:18;;:::i;:::-;28897:15;;28823:95::o;28923:127::-;28984:10;28979:3;28975:20;28972:1;28965:31;29015:4;29012:1;29005:15;29039:4;29036:1;29029:15;29055:127;29116:10;29111:3;29107:20;29104:1;29097:31;29147:4;29144:1;29137:15;29171:4;29168:1;29161:15;29187:127;29248:10;29243:3;29239:20;29236:1;29229:31;29279:4;29276:1;29269:15;29303:4;29300:1;29293:15

Swarm Source

ipfs://3d7d74dc3ac43bc6c5707cca8e098e42fac5aa8b7ba6e2cb303ea95401c3aa36
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.