ETH Price: $3,134.79 (+3.40%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Settle Share129946372021-08-10 2:10:501580 days ago1628561450IN
MCDEX: ETH AMM
0 ETH0.0070662966.00000156
Settle Share126588532021-06-18 14:12:211633 days ago1624025541IN
MCDEX: ETH AMM
0 ETH0.0022278923
Settle Share123434492021-04-30 18:30:241682 days ago1619807424IN
MCDEX: ETH AMM
0 ETH0.0078460681
Settle Share120383152021-03-14 18:27:371729 days ago1615746457IN
MCDEX: ETH AMM
0 ETH0.01086382105
Settle Share119582032021-03-02 10:11:291741 days ago1614679889IN
MCDEX: ETH AMM
0 ETH0.0087945285
Settle Share119581332021-03-02 9:52:151741 days ago1614678735IN
MCDEX: ETH AMM
0 ETH0.0093118590
Deposit And Buy119539282021-03-01 18:29:001742 days ago1614623340IN
MCDEX: ETH AMM
0 ETH0.0635594100
Deposit And Buy119522992021-03-01 12:21:051742 days ago1614601265IN
MCDEX: ETH AMM
0 ETH0.06694149105
Remove Liquidity119376032021-02-27 5:58:501744 days ago1614405530IN
MCDEX: ETH AMM
0 ETH0.0771069690
Sell119251372021-02-25 8:07:201746 days ago1614240440IN
MCDEX: ETH AMM
0 ETH0.13011438172
Buy119226842021-02-24 23:05:061746 days ago1614207906IN
MCDEX: ETH AMM
0 ETH0.15491005198
Sell119210642021-02-24 17:05:031747 days ago1614186303IN
MCDEX: ETH AMM
0 ETH0.25019709346
Sell119186462021-02-24 8:06:061747 days ago1614153966IN
MCDEX: ETH AMM
0 ETH0.11478909159
Sell119162422021-02-23 23:05:011747 days ago1614121501IN
MCDEX: ETH AMM
0 ETH0.1444316200
Buy119145882021-02-23 17:04:411748 days ago1614099881IN
MCDEX: ETH AMM
0 ETH0.32229894412
Buy119121412021-02-23 8:11:291748 days ago1614067889IN
MCDEX: ETH AMM
0 ETH0.34778919444
Buy119097292021-02-22 23:04:461748 days ago1614035086IN
MCDEX: ETH AMM
0 ETH0.17336779208
Deposit And Sell119095642021-02-22 22:31:131748 days ago1614033073IN
MCDEX: ETH AMM
0 ETH0.13315333156
Buy119081402021-02-22 17:15:471749 days ago1614014147IN
MCDEX: ETH AMM
0 ETH0.37492224480
Buy119056572021-02-22 8:04:191749 days ago1613981059IN
MCDEX: ETH AMM
0 ETH0.10725031137
Deposit And Sell119049452021-02-22 5:24:121749 days ago1613971452IN
MCDEX: ETH AMM
0.42 ETH0.12032487146
Deposit And Sell119049372021-02-22 5:21:151749 days ago1613971275IN
MCDEX: ETH AMM
0.457 ETH0.0251921792
Deposit And Sell119046202021-02-22 4:14:131749 days ago1613967253IN
MCDEX: ETH AMM
0.585 ETH0.13461907164
Deposit And Sell119043242021-02-22 3:08:531749 days ago1613963333IN
MCDEX: ETH AMM
0.133 ETH0.12789716155
Deposit And Sell119040482021-02-22 2:07:591749 days ago1613959679IN
MCDEX: ETH AMM
0.016 ETH0.10301512125
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
-119049452021-02-22 5:24:121749 days ago1613971452
MCDEX: ETH AMM
0.42 ETH
-119049372021-02-22 5:21:151749 days ago1613971275
MCDEX: ETH AMM
0.457 ETH
-119046202021-02-22 4:14:131749 days ago1613967253
MCDEX: ETH AMM
0.585 ETH
-119043242021-02-22 3:08:531749 days ago1613963333
MCDEX: ETH AMM
0.133 ETH
-119040482021-02-22 2:07:591749 days ago1613959679
MCDEX: ETH AMM
0.016 ETH
-119021352021-02-21 19:12:451750 days ago1613934765
MCDEX: ETH AMM
0.001 ETH
-118461562021-02-13 4:21:531758 days ago1613190113
MCDEX: ETH AMM
1 ETH
-118461472021-02-13 4:18:491758 days ago1613189929
MCDEX: ETH AMM
0.12523853 ETH
-117937952021-02-05 3:15:281766 days ago1612494928
MCDEX: ETH AMM
0.001 ETH
-117076292021-01-22 21:08:241779 days ago1611349704
MCDEX: ETH AMM
0.001 ETH
-116372412021-01-12 1:50:221790 days ago1610416222
MCDEX: ETH AMM
0.419 ETH
-116361622021-01-11 21:46:501790 days ago1610401610
MCDEX: ETH AMM
0.534 ETH
-116208662021-01-09 13:35:241793 days ago1610199324
MCDEX: ETH AMM
0.001 ETH
-116034472021-01-06 21:14:071795 days ago1609967647
MCDEX: ETH AMM
0.281 ETH
-115833282021-01-03 19:07:131799 days ago1609700833
MCDEX: ETH AMM
0.115 ETH
-115727692021-01-02 4:16:311800 days ago1609560991
MCDEX: ETH AMM
0.008 ETH
-114930612020-12-20 22:54:451812 days ago1608504885
MCDEX: ETH AMM
0.016 ETH
-113765322020-12-03 1:06:461830 days ago1606957606
MCDEX: ETH AMM
0.118 ETH
-113595322020-11-30 10:11:331833 days ago1606731093
MCDEX: ETH AMM
0.004 ETH
-113448232020-11-28 4:21:191835 days ago1606537279
MCDEX: ETH AMM
0.802 ETH
-113340442020-11-26 12:36:531837 days ago1606394213
MCDEX: ETH AMM
0.492 ETH
-113255322020-11-25 4:59:401838 days ago1606280380
MCDEX: ETH AMM
0.377 ETH
-113254232020-11-25 4:35:501838 days ago1606278950
MCDEX: ETH AMM
0.036 ETH
-113129522020-11-23 6:42:341840 days ago1606113754
MCDEX: ETH AMM
1.834 ETH
-112874492020-11-19 8:55:331844 days ago1605776133
MCDEX: ETH AMM
0.022 ETH
View All Internal Transactions
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

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

Contract Source Code Verified (Exact Match)

Contract Name:
AMM

Compiler Version
v0.5.15+commit.6a57276f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license
/**
 *Submitted for verification at Etherscan.io on 2020-06-23
*/

// The software and documentation available in this repository (the "Software") is protected by copyright law and accessible pursuant to the license set forth below. Copyright © 2020 MRTB Ltd. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person or organization obtaining the Software (the “Licensee”) to privately study, review, and analyze the Software. Licensee shall not use the Software for any other purpose. Licensee shall not modify, transfer, assign, share, or sub-license the Software or any derivative works of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE.

pragma solidity 0.5.15;
pragma experimental ABIEncoderV2;


library LibMathSigned {
    int256 private constant _WAD = 10 ** 18;
    int256 private constant _INT256_MIN = -2 ** 255;

    uint8 private constant FIXED_DIGITS = 18;
    int256 private constant FIXED_1 = 10 ** 18;
    int256 private constant FIXED_E = 2718281828459045235;
    uint8 private constant LONGER_DIGITS = 36;
    int256 private constant LONGER_FIXED_LOG_E_1_5 = 405465108108164381978013115464349137;
    int256 private constant LONGER_FIXED_1 = 10 ** 36;
    int256 private constant LONGER_FIXED_LOG_E_10 = 2302585092994045684017991454684364208;


    function WAD() internal pure returns (int256) {
        return _WAD;
    }

    // additive inverse
    function neg(int256 a) internal pure returns (int256) {
        return sub(int256(0), a);
    }

    /**
     * @dev Multiplies two signed integers, reverts on overflow
     * see https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.1/contracts/math/SignedSafeMath.sol#L13
     */
    function mul(int256 a, int256 b) internal pure returns (int256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }
        require(!(a == -1 && b == _INT256_MIN), "wmultiplication overflow");

        int256 c = a * b;
        require(c / a == b, "wmultiplication overflow");

        return c;
    }

    /**
     * @dev Integer division of two signed integers truncating the quotient, reverts on division by zero.
     * see https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.1/contracts/math/SignedSafeMath.sol#L32
     */
    function div(int256 a, int256 b) internal pure returns (int256) {
        require(b != 0, "wdivision by zero");
        require(!(b == -1 && a == _INT256_MIN), "wdivision overflow");

        int256 c = a / b;

        return c;
    }

    /**
     * @dev Subtracts two signed integers, reverts on overflow.
     * see https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.1/contracts/math/SignedSafeMath.sol#L44
     */
    function sub(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a - b;
        require((b >= 0 && c <= a) || (b < 0 && c > a), "subtraction overflow");

        return c;
    }

    /**
     * @dev Adds two signed integers, reverts on overflow.
     * see https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.1/contracts/math/SignedSafeMath.sol#L54
     */
    function add(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a + b;
        require((b >= 0 && c >= a) || (b < 0 && c < a), "addition overflow");

        return c;
    }

    function wmul(int256 x, int256 y) internal pure returns (int256 z) {
        z = roundHalfUp(mul(x, y), _WAD) / _WAD;
    }

    // solium-disable-next-line security/no-assign-params
    function wdiv(int256 x, int256 y) internal pure returns (int256 z) {
        if (y < 0) {
            y = -y;
            x = -x;
        }
        z = roundHalfUp(mul(x, _WAD), y) / y;
    }

    // solium-disable-next-line security/no-assign-params
    function wfrac(int256 x, int256 y, int256 z) internal pure returns (int256 r) {
        int256 t = mul(x, y);
        if (z < 0) {
            z = neg(z);
            t = neg(t);
        }
        r = roundHalfUp(t, z) / z;
    }

    function min(int256 x, int256 y) internal pure returns (int256) {
        return x <= y ? x : y;
    }

    function max(int256 x, int256 y) internal pure returns (int256) {
        return x >= y ? x : y;
    }

    // see https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.1/contracts/utils/SafeCast.sol#L103
    function toUint256(int256 x) internal pure returns (uint256) {
        require(x >= 0, "int overflow");
        return uint256(x);
    }

    // x ^ n
    // NOTE: n is a normal integer, do not shift 18 decimals
    // solium-disable-next-line security/no-assign-params
    function wpowi(int256 x, int256 n) internal pure returns (int256 z) {
        require(n >= 0, "wpowi only supports n >= 0");
        z = n % 2 != 0 ? x : _WAD;

        for (n /= 2; n != 0; n /= 2) {
            x = wmul(x, x);

            if (n % 2 != 0) {
                z = wmul(z, x);
            }
        }
    }

    // ROUND_HALF_UP rule helper. You have to call roundHalfUp(x, y) / y to finish the rounding operation
    // 0.5 ≈ 1, 0.4 ≈ 0, -0.5 ≈ -1, -0.4 ≈ 0
    function roundHalfUp(int256 x, int256 y) internal pure returns (int256) {
        require(y > 0, "roundHalfUp only supports y > 0");
        if (x >= 0) {
            return add(x, y / 2);
        }
        return sub(x, y / 2);
    }

    // solium-disable-next-line security/no-assign-params
    function wln(int256 x) internal pure returns (int256) {
        require(x > 0, "logE of negative number");
        require(x <= 10000000000000000000000000000000000000000, "logE only accepts v <= 1e22 * 1e18"); // in order to prevent using safe-math
        int256 r = 0;
        uint8 extraDigits = LONGER_DIGITS - FIXED_DIGITS;
        int256 t = int256(uint256(10)**uint256(extraDigits));

        while (x <= FIXED_1 / 10) {
            x = x * 10;
            r -= LONGER_FIXED_LOG_E_10;
        }
        while (x >= 10 * FIXED_1) {
            x = x / 10;
            r += LONGER_FIXED_LOG_E_10;
        }
        while (x < FIXED_1) {
            x = wmul(x, FIXED_E);
            r -= LONGER_FIXED_1;
        }
        while (x > FIXED_E) {
            x = wdiv(x, FIXED_E);
            r += LONGER_FIXED_1;
        }
        if (x == FIXED_1) {
            return roundHalfUp(r, t) / t;
        }
        if (x == FIXED_E) {
            return FIXED_1 + roundHalfUp(r, t) / t;
        }
        x *= t;

        //               x^2   x^3   x^4
        // Ln(1+x) = x - --- + --- - --- + ...
        //                2     3     4
        // when -1 < x < 1, O(x^n) < ε => when n = 36, 0 < x < 0.316
        //
        //                    2    x           2    x          2    x
        // Ln(a+x) = Ln(a) + ---(------)^1  + ---(------)^3 + ---(------)^5 + ...
        //                    1   2a+x         3   2a+x        5   2a+x
        //
        // Let x = v - a
        //                  2   v-a         2   v-a        2   v-a
        // Ln(v) = Ln(a) + ---(-----)^1  + ---(-----)^3 + ---(-----)^5 + ...
        //                  1   v+a         3   v+a        5   v+a
        // when n = 36, 1 < v < 3.423
        r = r + LONGER_FIXED_LOG_E_1_5;
        int256 a1_5 = (3 * LONGER_FIXED_1) / 2;
        int256 m = (LONGER_FIXED_1 * (x - a1_5)) / (x + a1_5);
        r = r + 2 * m;
        int256 m2 = (m * m) / LONGER_FIXED_1;
        uint8 i = 3;
        while (true) {
            m = (m * m2) / LONGER_FIXED_1;
            r = r + (2 * m) / int256(i);
            i += 2;
            if (i >= 3 + 2 * FIXED_DIGITS) {
                break;
            }
        }
        return roundHalfUp(r, t) / t;
    }

    // Log(b, x)
    function logBase(int256 base, int256 x) internal pure returns (int256) {
        return wdiv(wln(x), wln(base));
    }

    function ceil(int256 x, int256 m) internal pure returns (int256) {
        require(x >= 0, "ceil need x >= 0");
        require(m > 0, "ceil need m > 0");
        return (sub(add(x, m), 1) / m) * m;
    }
}

library LibMathUnsigned {
    uint256 private constant _WAD = 10**18;
    uint256 private constant _POSITIVE_INT256_MAX = 2**255 - 1;

    function WAD() internal pure returns (uint256) {
        return _WAD;
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on overflow.
     * see https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.1/contracts/math/SafeMath.sol#L26
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "Unaddition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     * see https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.1/contracts/math/SafeMath.sol#L55
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "Unsubtraction overflow");
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     * see https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.1/contracts/math/SafeMath.sol#L71
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "Unmultiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     * see https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.1/contracts/math/SafeMath.sol#L111
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, "Undivision by zero");
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    function wmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = add(mul(x, y), _WAD / 2) / _WAD;
    }

    function wdiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = add(mul(x, _WAD), y / 2) / y;
    }

    function wfrac(uint256 x, uint256 y, uint256 z) internal pure returns (uint256 r) {
        r = mul(x, y) / z;
    }

    function min(uint256 x, uint256 y) internal pure returns (uint256) {
        return x <= y ? x : y;
    }

    function max(uint256 x, uint256 y) internal pure returns (uint256) {
        return x >= y ? x : y;
    }

    function toInt256(uint256 x) internal pure returns (int256) {
        require(x <= _POSITIVE_INT256_MAX, "uint256 overflow");
        return int256(x);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     * see https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.1/contracts/math/SafeMath.sol#L146
     */
    function mod(uint256 x, uint256 m) internal pure returns (uint256) {
        require(m != 0, "mod by zero");
        return x % m;
    }

    function ceil(uint256 x, uint256 m) internal pure returns (uint256) {
        require(m > 0, "ceil need m > 0");
        return (sub(add(x, m), 1) / m) * m;
    }
}

library LibTypes {
    enum Side {FLAT, SHORT, LONG}

    enum Status {NORMAL, EMERGENCY, SETTLED}

    function counterSide(Side side) internal pure returns (Side) {
        if (side == Side.LONG) {
            return Side.SHORT;
        } else if (side == Side.SHORT) {
            return Side.LONG;
        }
        return side;
    }

    //////////////////////////////////////////////////////////////////////////
    // Perpetual
    //////////////////////////////////////////////////////////////////////////
    struct PerpGovernanceConfig {
        uint256 initialMarginRate;
        uint256 maintenanceMarginRate;
        uint256 liquidationPenaltyRate;
        uint256 penaltyFundRate;
        int256 takerDevFeeRate;
        int256 makerDevFeeRate;
        uint256 lotSize;
        uint256 tradingLotSize;
    }

    struct MarginAccount {
        LibTypes.Side side;
        uint256 size;
        uint256 entryValue;
        int256 entrySocialLoss;
        int256 entryFundingLoss;
        int256 cashBalance;
    }

    //////////////////////////////////////////////////////////////////////////
    // AMM
    //////////////////////////////////////////////////////////////////////////
    struct AMMGovernanceConfig {
        uint256 poolFeeRate;
        uint256 poolDevFeeRate;
        int256 emaAlpha;
        uint256 updatePremiumPrize;
        int256 markPremiumLimit;
        int256 fundingDampener;
    }

    struct FundingState {
        uint256 lastFundingTime;
        int256 lastPremium;
        int256 lastEMAPremium;
        uint256 lastIndexPrice;
        int256 accumulatedFundingPerContract;
    }
}

interface IPriceFeeder {
    function price() external view returns (uint256 lastPrice, uint256 lastTimestamp);
}

interface IAMM {
    function shareTokenAddress() external view returns (address);

    function indexPrice() external view returns (uint256 price, uint256 timestamp);

    function positionSize() external returns (uint256);

    function lastFundingState() external view returns (LibTypes.FundingState memory);

    function currentFundingRate() external returns (int256);

    function currentFundingState() external returns (LibTypes.FundingState memory);

    function lastFundingRate() external view returns (int256);

    function getGovernance() external view returns (LibTypes.AMMGovernanceConfig memory);

    function perpetualProxy() external view returns (IPerpetual);

    function currentMarkPrice() external returns (uint256);

    function currentAvailableMargin() external returns (uint256);

    function currentPremiumRate() external returns (int256);

    function currentFairPrice() external returns (uint256);

    function currentPremium() external returns (int256);

    function currentAccumulatedFundingPerContract() external returns (int256);

    function updateIndex() external;

    function createPool(uint256 amount) external;

    function settleShare(uint256 shareAmount) external;

    function buy(uint256 amount, uint256 limitPrice, uint256 deadline) external returns (uint256);

    function sell(uint256 amount, uint256 limitPrice, uint256 deadline) external returns (uint256);

    function buyFromWhitelisted(address trader, uint256 amount, uint256 limitPrice, uint256 deadline)
        external
        returns (uint256);

    function sellFromWhitelisted(address trader, uint256 amount, uint256 limitPrice, uint256 deadline)
        external
        returns (uint256);

    function buyFrom(address trader, uint256 amount, uint256 limitPrice, uint256 deadline) external returns (uint256);

    function sellFrom(address trader, uint256 amount, uint256 limitPrice, uint256 deadline) external returns (uint256);

    function depositAndBuy(
        uint256 depositAmount,
        uint256 tradeAmount,
        uint256 limitPrice,
        uint256 deadline
    ) external payable;

    function depositAndSell(
        uint256 depositAmount,
        uint256 tradeAmount,
        uint256 limitPrice,
        uint256 deadline
    ) external payable;

    function buyAndWithdraw(
        uint256 tradeAmount,
        uint256 limitPrice,
        uint256 deadline,
        uint256 withdrawAmount
    ) external;

    function sellAndWithdraw(
        uint256 tradeAmount,
        uint256 limitPrice,
        uint256 deadline,
        uint256 withdrawAmount
    ) external;

    function depositAndAddLiquidity(uint256 depositAmount, uint256 amount) external payable;
}

interface IPerpetual {
    function devAddress() external view returns (address);

    function getMarginAccount(address trader) external view returns (LibTypes.MarginAccount memory);

    function getGovernance() external view returns (LibTypes.PerpGovernanceConfig memory);

    function status() external view returns (LibTypes.Status);

    function paused() external view returns (bool);

    function withdrawDisabled() external view returns (bool);

    function settlementPrice() external view returns (uint256);

    function globalConfig() external view returns (address);

    function collateral() external view returns (address);

    function amm() external view returns (IAMM);

    function totalSize(LibTypes.Side side) external view returns (uint256);

    function markPrice() external returns (uint256);

    function socialLossPerContract(LibTypes.Side side) external view returns (int256);

    function availableMargin(address trader) external returns (int256);

    function positionMargin(address trader) external view returns (uint256);

    function maintenanceMargin(address trader) external view returns (uint256);

    function isSafe(address trader) external returns (bool);

    function isSafeWithPrice(address trader, uint256 currentMarkPrice) external returns (bool);

    function isIMSafe(address trader) external returns (bool);

    function isIMSafeWithPrice(address trader, uint256 currentMarkPrice) external returns (bool);

    function tradePosition(
        address taker,
        address maker,
        LibTypes.Side side,
        uint256 price,
        uint256 amount
    ) external returns (uint256, uint256);

    function transferCashBalance(
        address from,
        address to,
        uint256 amount
    ) external;

    function depositFor(address trader, uint256 amount) external payable;

    function withdrawFor(address payable trader, uint256 amount) external;

    function liquidate(address trader, uint256 amount) external returns (uint256, uint256);

    function insuranceFundBalance() external view returns (int256);

    function beginGlobalSettlement(uint256 price) external;

    function endGlobalSettlement() external;

    function isValidLotSize(uint256 amount) external view returns (bool);

    function isValidTradingLotSize(uint256 amount) external view returns (bool);
}

contract Context {
    // Empty internal constructor, to prevent people from mistakenly deploying
    // an instance of this contract, which should be used via inheritance.
    constructor () internal { }
    // solhint-disable-previous-line no-empty-blocks

    function _msgSender() internal view returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

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

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

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

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

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

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

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

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

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

        return c;
    }

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

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     *
     * _Available since v2.4.0._
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

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

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

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

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

contract ERC20 is Context, IERC20 {
    using SafeMath for uint256;

    mapping (address => uint256) private _balances;

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

    uint256 private _totalSupply;

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

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

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

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

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20};
     *
     * Requirements:
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for `sender`'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

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

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

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

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

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

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

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

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

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

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

    /**
     * @dev Destroys `amount` tokens from `account`.`amount` is then deducted
     * from the caller's allowance.
     *
     * See {_burn} and {_approve}.
     */
    function _burnFrom(address account, uint256 amount) internal {
        _burn(account, amount);
        _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance"));
    }
}

library Roles {
    struct Role {
        mapping (address => bool) bearer;
    }

    /**
     * @dev Give an account access to this role.
     */
    function add(Role storage role, address account) internal {
        require(!has(role, account), "Roles: account already has role");
        role.bearer[account] = true;
    }

    /**
     * @dev Remove an account's access to this role.
     */
    function remove(Role storage role, address account) internal {
        require(has(role, account), "Roles: account does not have role");
        role.bearer[account] = false;
    }

    /**
     * @dev Check if an account has this role.
     * @return bool
     */
    function has(Role storage role, address account) internal view returns (bool) {
        require(account != address(0), "Roles: account is the zero address");
        return role.bearer[account];
    }
}

contract MinterRole is Context {
    using Roles for Roles.Role;

    event MinterAdded(address indexed account);
    event MinterRemoved(address indexed account);

    Roles.Role private _minters;

    constructor () internal {
        _addMinter(_msgSender());
    }

    modifier onlyMinter() {
        require(isMinter(_msgSender()), "MinterRole: caller does not have the Minter role");
        _;
    }

    function isMinter(address account) public view returns (bool) {
        return _minters.has(account);
    }

    function addMinter(address account) public onlyMinter {
        _addMinter(account);
    }

    function renounceMinter() public {
        _removeMinter(_msgSender());
    }

    function _addMinter(address account) internal {
        _minters.add(account);
        emit MinterAdded(account);
    }

    function _removeMinter(address account) internal {
        _minters.remove(account);
        emit MinterRemoved(account);
    }
}

contract ERC20Mintable is ERC20, MinterRole {
    /**
     * @dev See {ERC20-_mint}.
     *
     * Requirements:
     *
     * - the caller must have the {MinterRole}.
     */
    function mint(address account, uint256 amount) public onlyMinter returns (bool) {
        _mint(account, amount);
        return true;
    }
}

contract ERC20Detailed is IERC20 {
    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of
     * these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name, string memory symbol, uint8 decimals) public {
        _name = name;
        _symbol = symbol;
        _decimals = decimals;
    }

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

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

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

contract ShareToken is ERC20Mintable, ERC20Detailed {

    constructor(string memory _name, string memory _symbol, uint8 _decimals)
        ERC20Detailed(_name, _symbol, _decimals)
        public
    {
    }

    function burn(address account, uint256 amount) public onlyMinter returns (bool) {
        _burn(account, amount);
        return true;
    }
}

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) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != accountHash && codehash != 0x0);
    }

    /**
     * @dev Converts an `address` into `address payable`. Note that this is
     * simply a type cast: the actual underlying value is not changed.
     *
     * _Available since v2.4.0._
     */
    function toPayable(address account) internal pure returns (address payable) {
        return address(uint160(account));
    }

    /**
     * @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].
     *
     * _Available since v2.4.0._
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

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

interface IGlobalConfig {

    function owner() external view returns (address);

    function isOwner() external view returns (bool);

    function renounceOwnership() external;

    function transferOwnership(address newOwner) external;

    function brokers(address broker) external view returns (bool);
    
    function pauseControllers(address broker) external view returns (bool);

    function withdrawControllers(address broker) external view returns (bool);

    function addBroker() external;

    function removeBroker() external;

    function isComponent(address component) external view returns (bool);

    function addComponent(address perpetual, address component) external;

    function removeComponent(address perpetual, address component) external;

    function addPauseController(address controller) external;

    function removePauseController(address controller) external;

    function addWithdrawController(address controller) external;

    function removeWithdrawControllers(address controller) external;
}

contract AMMGovernance {
    using LibMathSigned for int256;
    using LibMathUnsigned for uint256;

    LibTypes.AMMGovernanceConfig internal governance;
    LibTypes.FundingState internal fundingState;

    // auto-set when calling setGovernanceParameter
    int256 public emaAlpha2; // 1 - emaAlpha
    int256 public emaAlpha2Ln; // ln(emaAlpha2)

    IPerpetual public perpetualProxy;
    IPriceFeeder public priceFeeder;
    IGlobalConfig public globalConfig;

    event UpdateGovernanceParameter(bytes32 indexed key, int256 value);

    constructor(address _globalConfig) public {
        require(_globalConfig != address(0), "invalid global config");
        globalConfig = IGlobalConfig(_globalConfig);
    }

    modifier onlyOwner() {
        require(globalConfig.owner() == msg.sender, "not owner");
        _;
    }

    modifier onlyAuthorized() {
        require(globalConfig.isComponent(msg.sender), "unauthorized caller");
        _;
    }

    /**
     * @dev Set governance parameters.
     *
     * @param key   Name of parameter.
     * @param value Value of parameter.
     */
    function setGovernanceParameter(bytes32 key, int256 value) public onlyOwner {
        if (key == "poolFeeRate") {
            governance.poolFeeRate = value.toUint256();
        } else if (key == "poolDevFeeRate") {
            governance.poolDevFeeRate = value.toUint256();
        } else if (key == "emaAlpha") {
            require(value > 0, "alpha should be > 0");
            require(value <= 10**18, "alpha should be <= 1");
            governance.emaAlpha = value;
            emaAlpha2 = 10**18 - governance.emaAlpha;
            emaAlpha2Ln = emaAlpha2.wln();
        } else if (key == "updatePremiumPrize") {
            governance.updatePremiumPrize = value.toUint256();
        } else if (key == "markPremiumLimit") {
            governance.markPremiumLimit = value;
        } else if (key == "fundingDampener") {
            governance.fundingDampener = value;
        } else if (key == "accumulatedFundingPerContract") {
            require(perpetualProxy.status() == LibTypes.Status.EMERGENCY, "wrong perpetual status");
            fundingState.accumulatedFundingPerContract = value;
        } else if (key == "priceFeeder") {
            require(Address.isContract(address(value)), "wrong address");
            priceFeeder = IPriceFeeder(value);
        } else {
            revert("key not exists");
        }
        emit UpdateGovernanceParameter(key, value);
    }

    // get governance data structure.
    function getGovernance() public view returns (LibTypes.AMMGovernanceConfig memory) {
        return governance;
    }
}

contract AMM is AMMGovernance {
    using LibMathSigned for int256;
    using LibMathUnsigned for uint256;

    int256 private constant FUNDING_PERIOD = 28800; // 8 * 3600;

    // ERC20 token
    ShareToken private shareToken;

    event CreateAMM();
    event UpdateFundingRate(LibTypes.FundingState fundingState);

    constructor(
        address _globalConfig,
        address _perpetualProxy,
        address _priceFeeder,
        address _shareToken
    )
        public
        AMMGovernance(_globalConfig)
    {
        priceFeeder = IPriceFeeder(_priceFeeder);
        perpetualProxy = IPerpetual(_perpetualProxy);
        shareToken = ShareToken(_shareToken);

        emit CreateAMM();
    }

    /**
     * @notice Share token's ERC20 address.
     */
    function shareTokenAddress() public view returns (address) {
        return address(shareToken);
    }

    /**
     * @notice Index price.
     *
     * Re-read the oracle price instead of the cached value.
     */
    function indexPrice() public view returns (uint256 price, uint256 timestamp) {
        (price, timestamp) = priceFeeder.price();
        require(price != 0, "dangerous index price");
    }

    /**
     * @notice Pool's position size (y).
     */
    function positionSize() public view returns (uint256) {
        return perpetualProxy.getMarginAccount(tradingAccount()).size;
    }

    /**
     * @notice FundingState.
     *
     * Note: last* functions (lastFundingState, lastAvailableMargin, lastFairPrice, etc.) are calculated based on
     *       the on-chain fundingState. current* functions are calculated based on the current timestamp.
     */
    function lastFundingState() public view returns (LibTypes.FundingState memory) {
        return fundingState;
    }

    /**
     * @notice AvailableMargin (x).
     *
     * Note: last* functions (lastFundingState, lastAvailableMargin, lastFairPrice, etc.) are calculated based on
     *       the on-chain fundingState. current* functions are calculated based on the current timestamp.
     */
    function lastAvailableMargin() internal view returns (uint256) {
        LibTypes.MarginAccount memory account = perpetualProxy.getMarginAccount(tradingAccount());
        return availableMarginFromPoolAccount(account);
    }

    /**
     * @notice FairPrice.
     *
     * Note: last* functions (lastFundingState, lastAvailableMargin, lastFairPrice, etc.) are calculated based on
     *       the on-chain fundingState. current* functions are calculated based on the current timestamp.
     */
    function lastFairPrice() internal view returns (uint256) {
        LibTypes.MarginAccount memory account = perpetualProxy.getMarginAccount(tradingAccount());
        return fairPriceFromPoolAccount(account);
    }

    /**
     * @notice Premium.
     *
     * Note: last* functions (lastFundingState, lastAvailableMargin, lastFairPrice, etc.) are calculated based on
     *       the on-chain fundingState. current* functions are calculated based on the current timestamp.
     */
    function lastPremium() internal view returns (int256) {
        LibTypes.MarginAccount memory account = perpetualProxy.getMarginAccount(tradingAccount());
        return premiumFromPoolAccount(account);
    }

    /**
     * @notice EMAPremium.
     *
     * Note: last* functions (lastFundingState, lastAvailableMargin, lastFairPrice, etc.) are calculated based on
     *       on-chain fundingState. current* functions are calculated based on the current timestamp.
     */
    function lastEMAPremium() internal view returns (int256) {
        return fundingState.lastEMAPremium;
    }

    /**
     * @notice MarkPrice.
     *
     * Note: last* functions (lastFundingState, lastAvailableMargin, lastFairPrice, etc.) are calculated based on
     *       the on-chain fundingState. current* functions are calculated based on the current timestamp.
     */
    function lastMarkPrice() internal view returns (uint256) {
        int256 index = fundingState.lastIndexPrice.toInt256();
        int256 limit = index.wmul(governance.markPremiumLimit);
        int256 p = index.add(lastEMAPremium());
        p = p.min(index.add(limit));
        p = p.max(index.sub(limit));
        return p.max(0).toUint256();
    }

    /**
     * @notice PremiumRate.
     *
     * Note: last* functions (lastFundingState, lastAvailableMargin, lastFairPrice, etc.) are calculated based on
     *       the on-chain fundingState. current* functions are calculated based on the current timestamp.
     */
    function lastPremiumRate() internal view returns (int256) {
        int256 index = fundingState.lastIndexPrice.toInt256();
        int256 rate = lastMarkPrice().toInt256();
        rate = rate.sub(index).wdiv(index);
        return rate;
    }

    /**
     * @notice FundingRate.
     *
     * Note: last* functions (lastFundingState, lastAvailableMargin, lastFairPrice, etc.) are calculated based on
     *       the on-chain fundingState. current* functions are calculated based on the current timestamp.
     */
    function lastFundingRate() public view returns (int256) {
        int256 rate = lastPremiumRate();
        return rate.max(governance.fundingDampener).add(rate.min(-governance.fundingDampener));
    }

    // Public functions

    /**
     * @notice FundingState.
     *
     * Note: current* functions (currentFundingState, currentAvailableMargin, currentFairPrice, etc.) are calculated based on
     *       the current timestamp. current* functions are calculated based on the on-chain fundingState.
     */
    function currentFundingState() public returns (LibTypes.FundingState memory) {
        funding();
        return fundingState;
    }

    /**
     * @notice AvailableMargin (x).
     *
     * Note: current* functions (currentFundingState, currentAvailableMargin, currentFairPrice, etc.) are calculated based on
     *       the current timestamp. current* functions are calculated based on the on-chain fundingState.
     */
    function currentAvailableMargin() public returns (uint256) {
        funding();
        return lastAvailableMargin();
    }

    /**
     * @notice FairPrice.
     *
     * Note: current* functions (currentFundingState, currentAvailableMargin, currentFairPrice, etc.) are calculated based on
     *       the current timestamp. current* functions are calculated based on the on-chain fundingState.
     */
    function currentFairPrice() public returns (uint256) {
        funding();
        return lastFairPrice();
    }

    /**
     * @notice Premium.
     *
     * Note: current* functions (currentFundingState, currentAvailableMargin, currentFairPrice, etc.) are calculated based on
     *       the current timestamp. current* functions are calculated based on the on-chain fundingState.
     */
    function currentPremium() public returns (int256) {
        funding();
        return lastPremium();
    }

    /**
     * @notice MarkPrice.
     *
     * Note: current* functions (currentFundingState, currentAvailableMargin, currentFairPrice, etc.) are calculated based on
     *       the current timestamp. current* functions are calculated based on the on-chain fundingState.
     */
    function currentMarkPrice() public returns (uint256) {
        funding();
        return lastMarkPrice();
    }

    /**
     * @notice PremiumRate.
     *
     * Note: current* functions (currentFundingState, currentAvailableMargin, currentFairPrice, etc.) are calculated based on
     *       the current timestamp. current* functions are calculated based on the on-chain fundingState.
     */
    function currentPremiumRate() public returns (int256) {
        funding();
        return lastPremiumRate();
    }

    /**
     * @notice FundingRate.
     *
     * Note: current* functions (currentFundingState, currentAvailableMargin, currentFairPrice, etc.) are calculated based on
     *       the current timestamp. current* functions are calculated based on the on-chain fundingState.
     */
    function currentFundingRate() public returns (int256) {
        funding();
        return lastFundingRate();
    }

    /**
     * @notice AccumulatedFundingPerContract.
     *
     * Note: current* functions (currentFundingState, currentAvailableMargin, currentFairPrice, etc.) are calculated based on
     *       the current timestamp. current* functions are calculated based on the on-chain fundingState.
     */
    function currentAccumulatedFundingPerContract() public returns (int256) {
        funding();
        return fundingState.accumulatedFundingPerContract;
    }

    /**
     * @notice The pool's margin account.
     */
    function tradingAccount() internal view returns (address) {
        return address(perpetualProxy);
    }

    /**
     * @notice The 1st addLiquidity.
     *
     * The semantics of this function is almost identical to addLiquidity except that the trading price
     * is not determined by fairPrice, but by indexPrice.
     *
     * Note: buy() and sell() will fail before this function is called.
     * @param amount Sell amount. Must be a multiple of lotSize.
     */
    function createPool(uint256 amount) public {
        require(amount > 0, "amount must be greater than zero");
        require(perpetualProxy.status() == LibTypes.Status.NORMAL, "wrong perpetual status");
        require(positionSize() == 0, "pool not empty");

        address trader = msg.sender;
        uint256 blockTime = getBlockTimestamp();
        uint256 newIndexPrice;
        uint256 newIndexTimestamp;
        (newIndexPrice, newIndexTimestamp) = indexPrice();

        initFunding(newIndexPrice, blockTime);
        perpetualProxy.transferCashBalance(trader, tradingAccount(), newIndexPrice.wmul(amount).mul(2));
        (uint256 opened, ) = perpetualProxy.tradePosition(
            trader,
            tradingAccount(),
            LibTypes.Side.SHORT,
            newIndexPrice,
            amount
        );
        mintShareTokenTo(trader, amount);

        forceFunding(); // x, y changed, so fair price changed. we need funding now
        mustSafe(trader, opened);
    }

    /**
     * @notice Price of buy/long.
     *
     * @param amount Buy amount.
     */
    function getBuyPrice(uint256 amount) internal returns (uint256 price) {
        uint256 x;
        uint256 y;
        (x, y) = currentXY();
        require(y != 0 && x != 0, "empty pool");
        return x.wdiv(y.sub(amount));
    }

    /**
     * @notice Real implementation of buy/long.
     *
     * @param trader The trader.
     * @param amount Buy amount. Must be a multiple of lotSize.
     * @param limitPrice Assert the trading price <= limitPrice.
     * @param deadline Assert the trading time <= deadline.
     */
    function buyFrom(
        address trader,
        uint256 amount,
        uint256 limitPrice,
        uint256 deadline
    )
        private
        returns (uint256) {
        require(perpetualProxy.status() == LibTypes.Status.NORMAL, "wrong perpetual status");
        require(perpetualProxy.isValidTradingLotSize(amount), "amount must be divisible by tradingLotSize");

        uint256 price = getBuyPrice(amount);
        require(limitPrice >= price, "price limited");
        require(getBlockTimestamp() <= deadline, "deadline exceeded");
        (uint256 opened, ) = perpetualProxy.tradePosition(trader, tradingAccount(), LibTypes.Side.LONG, price, amount);

        uint256 value = price.wmul(amount);
        uint256 fee = value.wmul(governance.poolFeeRate);
        uint256 devFee = value.wmul(governance.poolDevFeeRate);
        address devAddress = perpetualProxy.devAddress();

        perpetualProxy.transferCashBalance(trader, tradingAccount(), fee);
        perpetualProxy.transferCashBalance(trader, devAddress, devFee);

        forceFunding(); // x, y changed, so fair price changed. we need funding now
        mustSafe(trader, opened);
        return opened;
    }

    /**
     * @notice Buy/long with AMM if the trader comes from the whitelist.
     *
     * @param trader The trader.
     * @param amount Buy amount. Must be a multiple of lotSize.
     * @param limitPrice Assert the trading price <= limitPrice.
     * @param deadline Assert the trading time <= deadline.
     */
    function buyFromWhitelisted(
        address trader,
        uint256 amount,
        uint256 limitPrice,
        uint256 deadline
    )
        public
        onlyAuthorized
        returns (uint256)
    {
        return buyFrom(trader, amount, limitPrice, deadline);
    }

    /**
     * @notice Buy/long with AMM.
     *
     * @param amount Buy amount. Must be a multiple of lotSize.
     * @param limitPrice Assert the trading price <= limitPrice.
     * @param deadline Assert the trading time <= deadline.
     */
    function buy(
        uint256 amount,
        uint256 limitPrice,
        uint256 deadline
    ) public returns (uint256) {
        return buyFrom(msg.sender, amount, limitPrice, deadline);
    }

    /**
     * @notice Price of sell/short.
     *
     * @param amount Sell amount.
     */
    function getSellPrice(uint256 amount) internal returns (uint256 price) {
        uint256 x;
        uint256 y;
        (x, y) = currentXY();
        require(y != 0 && x != 0, "empty pool");
        return x.wdiv(y.add(amount));
    }

    /**
     * @notice Real implementation of sell/short.
     *
     * @param trader The trader.
     * @param amount Sell amount. Must be a multiple of lotSize.
     * @param limitPrice Assert the trading price >= limitPrice.
     * @param deadline Assert the trading time <= deadline.
     */
    function sellFrom(
        address trader,
        uint256 amount,
        uint256 limitPrice,
        uint256 deadline
    ) private returns (uint256) {
        require(perpetualProxy.status() == LibTypes.Status.NORMAL, "wrong perpetual status");
        require(perpetualProxy.isValidTradingLotSize(amount), "amount must be divisible by tradingLotSize");

        uint256 price = getSellPrice(amount);
        require(limitPrice <= price, "price limited");
        require(getBlockTimestamp() <= deadline, "deadline exceeded");
        (uint256 opened, ) = perpetualProxy.tradePosition(trader, tradingAccount(), LibTypes.Side.SHORT, price, amount);

        uint256 value = price.wmul(amount);
        uint256 fee = value.wmul(governance.poolFeeRate);
        uint256 devFee = value.wmul(governance.poolDevFeeRate);
        address devAddress = perpetualProxy.devAddress();
        perpetualProxy.transferCashBalance(trader, tradingAccount(), fee);
        perpetualProxy.transferCashBalance(trader, devAddress, devFee);

        forceFunding(); // x, y changed, so fair price changed. we need funding now
        mustSafe(trader, opened);
        return opened;
    }

    /**
     * @notice Sell/short with AMM if the trader comes from the whitelist.
     *
     * @param trader The trader.
     * @param amount Sell amount. Must be a multiple of lotSize.
     * @param limitPrice Assert the trading price >= limitPrice.
     * @param deadline Assert the trading time <= deadline.
     */
    function sellFromWhitelisted(
        address trader,
        uint256 amount,
        uint256 limitPrice,
        uint256 deadline
    )
        public
        onlyAuthorized
        returns (uint256)
    {
        return sellFrom(trader, amount, limitPrice, deadline);
    }

    /**
     * @notice Sell/short with AMM.
     *
     * @param amount Sell amount. Must be a multiple of lotSize.
     * @param limitPrice Assert the trading price >= limitPrice.
     * @param deadline Assert the trading time <= deadline.
     */
    function sell(
        uint256 amount,
        uint256 limitPrice,
        uint256 deadline
    ) public returns (uint256) {
        return sellFrom(msg.sender, amount, limitPrice, deadline);
    }

    /**
     * @notice Move collateral from the current liquidity provider's margin account into AMM and mint the Share token.
     *
     * After addLiquidity, the liquidity provider will:
     * 1. Pay (2 * amount * price) collateral.
     * 2. Get Share tokens to prove that there're some Long positions and collaterals in AMM that belongs to current liquidity provider.
     * 3. Get some Short positions.
     *
     * The number of short positions obtained is obviously the same as the number of long positions obtained in the pool.
     *
     * @param amount Sell amount. Must be a multiple of lotSize.
     */
    function addLiquidity(uint256 amount) public {
        require(perpetualProxy.status() == LibTypes.Status.NORMAL, "wrong perpetual status");

        uint256 oldAvailableMargin;
        uint256 oldPoolPositionSize;
        (oldAvailableMargin, oldPoolPositionSize) = currentXY();
        require(oldPoolPositionSize != 0 && oldAvailableMargin != 0, "empty pool");

        address trader = msg.sender;
        uint256 price = oldAvailableMargin.wdiv(oldPoolPositionSize);

        uint256 collateralAmount = amount.wmul(price).mul(2);
        perpetualProxy.transferCashBalance(trader, tradingAccount(), collateralAmount);
        (uint256 opened, ) = perpetualProxy.tradePosition(trader, tradingAccount(), LibTypes.Side.SHORT, price, amount);

        mintShareTokenTo(trader, shareToken.totalSupply().wmul(amount).wdiv(oldPoolPositionSize));

        forceFunding(); // x, y changed, so fair price changed. we need funding now
        mustSafe(trader, opened);
    }

    /**
     * @notice Burn Share tokens to remove the collateral attributed to the current liquidity provider
     *         from AMM into the liquidity provider's margin account.
     *
     * @param shareAmount The number of share tokens about to burn. The real trading amount will be
     *        automatically aligned to lotSize.
     */
    function removeLiquidity(uint256 shareAmount) public {
        require(perpetualProxy.status() == LibTypes.Status.NORMAL, "wrong perpetual status");

        address trader = msg.sender;
        uint256 oldAvailableMargin;
        uint256 oldPoolPositionSize;
        (oldAvailableMargin, oldPoolPositionSize) = currentXY();
        require(oldPoolPositionSize != 0 && oldAvailableMargin != 0, "empty pool");
        require(shareToken.balanceOf(msg.sender) >= shareAmount, "shareBalance too low");
        uint256 price = oldAvailableMargin.wdiv(oldPoolPositionSize);
        uint256 amount = shareAmount.wmul(oldPoolPositionSize).wdiv(shareToken.totalSupply());
        // align to lotSize
        uint256 lotSize = perpetualProxy.getGovernance().lotSize;
        amount = amount.sub(amount.mod(lotSize));

        perpetualProxy.transferCashBalance(tradingAccount(), trader, price.wmul(amount).mul(2));
        burnShareTokenFrom(trader, shareAmount);
        (uint256 opened, ) = perpetualProxy.tradePosition(trader, tradingAccount(), LibTypes.Side.LONG, price, amount);

        forceFunding(); // x, y changed, so fair price changed. we need funding now
        mustSafe(trader, opened);
    }

    /**
     * @notice In SETTLED status, burn Share tokens to remove the collateral attributed to the current liquidity provider
     *         from AMM to the liquidity provider's margin account.
     *
     * Also call perpetual.settle() to finally withdraw all collaterals after calling this function.
     */
    function settleShare() public {
        require(perpetualProxy.status() == LibTypes.Status.SETTLED, "wrong perpetual status");

        address trader = msg.sender;
        LibTypes.MarginAccount memory account = perpetualProxy.getMarginAccount(tradingAccount());
        uint256 total = availableMarginFromPoolAccount(account);
        uint256 shareAmount = shareToken.balanceOf(trader);
        uint256 balance = shareAmount.wmul(total).wdiv(shareToken.totalSupply());
        perpetualProxy.transferCashBalance(tradingAccount(), trader, balance);
        burnShareTokenFrom(trader, shareAmount);
    }

    /**
     * @notice This is a composite function of perp.deposit + amm.buy.
     *
     * Composite functions accept amount = 0.
     *
     * @param depositAmount The collateral amount. Note: The actual token.decimals should be filled in and not necessarily 18.
     * @param tradeAmount Buy amount.
     * @param limitPrice Assert the trading price <= limitPrice.
     * @param deadline Assert the trading time <= deadline.
     */
    function depositAndBuy(
        uint256 depositAmount,
        uint256 tradeAmount,
        uint256 limitPrice,
        uint256 deadline
    )
        public
        payable
    {
        if (depositAmount > 0) {
            perpetualProxy.depositFor.value(msg.value)(msg.sender, depositAmount);
        }
        if (tradeAmount > 0) {
            buy(tradeAmount, limitPrice, deadline);
        }
    }

    /**
     * @notice This is a composite function of perp.deposit + amm.sell.
     *
     * Composite functions accept amount = 0.
     *
     * @param depositAmount The collateral amount. Note: The actual token.decimals should be filled in and not necessarily 18.
     * @param tradeAmount Sell amount.
     * @param limitPrice Assert the trading price >= limitPrice.
     * @param deadline Assert the trading time <= deadline.
     */
    function depositAndSell(
        uint256 depositAmount,
        uint256 tradeAmount,
        uint256 limitPrice,
        uint256 deadline
    )
        public
        payable
    {
        if (depositAmount > 0) {
            perpetualProxy.depositFor.value(msg.value)(msg.sender, depositAmount);
        }
        if (tradeAmount > 0) {
            sell(tradeAmount, limitPrice, deadline);
        }
    }

    /**
     * @notice This is a composite function of amm.buy + perp.withdraw.
     *
     * Composite functions accept amount = 0.
     *
     * @param tradeAmount Buy amount.
     * @param limitPrice Assert the trading price <= limitPrice.
     * @param deadline Assert the trading time <= deadline.
     * @param withdrawAmount The collateral amount. Note: The actual token.decimals should be filled in and not necessarily 18.
     */
    function buyAndWithdraw(
        uint256 tradeAmount,
        uint256 limitPrice,
        uint256 deadline,
        uint256 withdrawAmount
    ) public {
        if (tradeAmount > 0) {
            buy(tradeAmount, limitPrice, deadline);
        }
        if (withdrawAmount > 0) {
            perpetualProxy.withdrawFor(msg.sender, withdrawAmount);
        }
    }

    /**
     * @notice This is a composite function of amm.sell + perp.withdraw.
     *
     * Composite functions accept amount = 0.
     *
     * @param tradeAmount Sell amount.
     * @param limitPrice Assert the trading price >= limitPrice.
     * @param deadline Assert the trading time <= deadline.
     * @param withdrawAmount The collateral amount. Note: The actual token.decimals should be filled in and not necessarily 18.
     */
    function sellAndWithdraw(
        uint256 tradeAmount,
        uint256 limitPrice,
        uint256 deadline,
        uint256 withdrawAmount
    ) public {
        if (tradeAmount > 0) {
            sell(tradeAmount, limitPrice, deadline);
        }
        if (withdrawAmount > 0) {
            perpetualProxy.withdrawFor(msg.sender, withdrawAmount);
        }
    }

    /**
     * @notice This is a composite function of perp.deposit + amm.addLiquidity.
     *
     * Composite functions accept amount = 0.
     *
     * After depositAndAddLiquidity, the liquidity provider will:
     * 1. Deposit depositAmount collateral.
     * 2. Pay (2 * amount * price) collateral.
     * 3. Get Share tokens to prove that there're some Long positions and collaterals in AMM that belongs to current liquidity provider.
     * 4. Get some Short positions.
     *
     * The number of short positions obtained is obviously the same as the number of long positions obtained in the pool.
     *
     * @param depositAmount The collateral amount. Note: The actual token.decimals should be filled in and not necessarily 18.
     * @param amount Sell amount, pay (2 * amount * price) collateral.
     */
    function depositAndAddLiquidity(uint256 depositAmount, uint256 amount) public payable {
        if (depositAmount > 0) {
            perpetualProxy.depositFor.value(msg.value)(msg.sender, depositAmount);
        }
        if (amount > 0) {
            addLiquidity(amount);
        }
    }

    /**
     * @notice Any ETH address can call this function to update the index price of this AMM and get some prize.
     */
    function updateIndex() public {
        require(perpetualProxy.status() == LibTypes.Status.NORMAL, "wrong perpetual status");
        uint256 oldIndexPrice = fundingState.lastIndexPrice;
        forceFunding();
        address devAddress = perpetualProxy.devAddress();
        if (oldIndexPrice != fundingState.lastIndexPrice) {
            perpetualProxy.transferCashBalance(devAddress, msg.sender, governance.updatePremiumPrize);
            require(perpetualProxy.isSafe(devAddress), "dev unsafe");
        }
    }

    // Internal helpers

    /**
     * @notice In order to mock the block.timestamp
     */
    function getBlockTimestamp() internal view returns (uint256) {
        // solium-disable-next-line security/no-block-members
        return block.timestamp;
    }

    /**
     * @notice a gas-optimized version of currentAvailableMargin() + positionSize(). almost all formulas require these two
     */
    function currentXY() internal returns (uint256 x, uint256 y) {
        funding();
        LibTypes.MarginAccount memory account = perpetualProxy.getMarginAccount(tradingAccount());
        x = availableMarginFromPoolAccount(account);
        y = account.size;
    }

    /**
     * @notice a gas-optimized version of lastAvailableMargin()
     */
    function availableMarginFromPoolAccount(LibTypes.MarginAccount memory account) internal view returns (uint256) {
        int256 available = account.cashBalance;
        int256 socialLossPerContract = perpetualProxy.socialLossPerContract(account.side);
        available = available.sub(account.entryValue.toInt256());
        available = available.sub(socialLossPerContract.wmul(account.size.toInt256()).sub(account.entrySocialLoss));
        available = available.sub(
            fundingState.accumulatedFundingPerContract.wmul(account.size.toInt256()).sub(account.entryFundingLoss)
        );
        return available.max(0).toUint256();
    }

    /**
     * @notice a gas-optimized version of lastFairPrice
     */
    function fairPriceFromPoolAccount(LibTypes.MarginAccount memory account) internal view returns (uint256) {
        uint256 y = account.size;
        require(y > 0, "funding initialization required");
        uint256 x = availableMarginFromPoolAccount(account);
        return x.wdiv(y);
    }

    /**
     * @notice a gas-optimized version of lastPremium
     */
    function premiumFromPoolAccount(LibTypes.MarginAccount memory account) internal view returns (int256) {
        int256 p = fairPriceFromPoolAccount(account).toInt256();
        p = p.sub(fundingState.lastIndexPrice.toInt256());
        return p;
    }

    /**
     * @notice Assert that the given trader is safe.
     *
     * A trader must at least MM-safe. If the trader is opening positions, it also needs to be IM-safe.
     *
     * @param trader The trader.
     * @param opened Non zero if the trader is opening positions.
     */
    function mustSafe(address trader, uint256 opened) internal {
        // perpetual.markPrice is a little different from ours
        uint256 perpetualMarkPrice = perpetualProxy.markPrice();
        if (opened > 0) {
            require(perpetualProxy.isIMSafeWithPrice(trader, perpetualMarkPrice), "im unsafe");
        }
        require(perpetualProxy.isSafeWithPrice(trader, perpetualMarkPrice), "sender unsafe");
        require(perpetualProxy.isSafeWithPrice(tradingAccount(), perpetualMarkPrice), "amm unsafe");
    }

    /**
     * @notice Mint Share token to a given trader.
     *
     * @param trader The trader.
     * @param amount Tokens.
     */
    function mintShareTokenTo(address trader, uint256 amount) internal {
        require(shareToken.mint(trader, amount), "mint failed");
    }

    /**
     * @notice Burn Share token from a given trader.
     * @param trader The trader.
     * @param amount Tokens.
     */
    function burnShareTokenFrom(address trader, uint256 amount) internal {
        require(shareToken.burn(trader, amount), "burn failed");
    }

    /**
     * @notice Init the fundingState. This function should be called before a funding().
     *
     * @param newIndexPrice Index price.
     * @param blockTime Use this timestamp instead of the time that the index price is generated, because this is the first initialization.
     */
    function initFunding(uint256 newIndexPrice, uint256 blockTime) private {
        require(fundingState.lastFundingTime == 0, "already initialized");
        fundingState.lastFundingTime = blockTime;
        fundingState.lastIndexPrice = newIndexPrice;
        fundingState.lastPremium = 0;
        fundingState.lastEMAPremium = 0;
    }

    /**
     * @notice current* functions need a funding() before return our states.
     *
     * Note: Will skip funding() other than NORMAL
     *
     * There are serveral conditions for change the funding state:
     * Condition 1: time.
     * Condition 2: indexPrice.
     * Condition 3: fairPrice. This condition is not covered in this function. We hand over to forceFunding.
     */
    function funding() internal {
        if (perpetualProxy.status() != LibTypes.Status.NORMAL) {
            return;
        }
        uint256 blockTime = getBlockTimestamp();
        uint256 newIndexPrice;
        uint256 newIndexTimestamp;
        (newIndexPrice, newIndexTimestamp) = indexPrice();
        if (
            blockTime != fundingState.lastFundingTime || // condition 1
            newIndexPrice != fundingState.lastIndexPrice || // condition 2, especially when updateIndex and buy/sell are in the same block
            newIndexTimestamp > fundingState.lastFundingTime // condition 2
        ) {
            forceFunding(blockTime, newIndexPrice, newIndexTimestamp);
        }
    }

    /**
     * @notice Update fundingState without checking whether the funding condition changes.
     *
     * This function also splits the funding process into 2 parts:
     * 1. funding from [lastFundingTime, lastIndexTimestamp)
     * 2. funding from [lastIndexTimestamp, blockTime)
     *
     */
    function forceFunding() internal {
        require(perpetualProxy.status() == LibTypes.Status.NORMAL, "wrong perpetual status");
        uint256 blockTime = getBlockTimestamp();
        uint256 newIndexPrice;
        uint256 newIndexTimestamp;
        (newIndexPrice, newIndexTimestamp) = indexPrice();
        forceFunding(blockTime, newIndexPrice, newIndexTimestamp);
    }

    /**
     * @notice Update fundingState without checking whether the funding condition changes.
     *
     * This function also splits the funding process into 2 parts:
     * 1. funding from [lastFundingTime, lastIndexTimestamp)
     * 2. funding from [lastIndexTimestamp, blockTime)
     *
     * @param blockTime The real end time.
     * @param newIndexPrice The latest index price.
     * @param newIndexTimestamp The timestamp of the latest index.
     */
    function forceFunding(uint256 blockTime, uint256 newIndexPrice, uint256 newIndexTimestamp) private {
        if (fundingState.lastFundingTime == 0) {
            // funding initialization required. but in this case, it's safe to just do nothing and return
            return;
        }
        LibTypes.MarginAccount memory account = perpetualProxy.getMarginAccount(tradingAccount());
        if (account.size == 0) {
            // empty pool. it's safe to just do nothing and return
            return;
        }

        if (newIndexTimestamp > fundingState.lastFundingTime) {
            // the 1st update
            nextStateWithTimespan(account, newIndexPrice, newIndexTimestamp);
        }
        // the 2nd update;
        nextStateWithTimespan(account, newIndexPrice, blockTime);

        emit UpdateFundingRate(fundingState);
    }

    /**
     * @notice Update fundingState from the lastFundingTime to the given time.
     *
     * This function also adds Acc / (8*3600) into accumulatedFundingPerContract, where Acc is accumulated
     * funding payment per position since lastFundingTime
     *
     * @param account The pool account.
     * @param newIndexPrice New index price.
     * @param endTimestamp The given end time.
     */
    function nextStateWithTimespan(
        LibTypes.MarginAccount memory account,
        uint256 newIndexPrice,
        uint256 endTimestamp
    ) private {
        require(fundingState.lastFundingTime != 0, "funding initialization required");
        require(endTimestamp >= fundingState.lastFundingTime, "time steps (n) must be positive");

        // update ema
        if (fundingState.lastFundingTime != endTimestamp) {
            int256 timeDelta = endTimestamp.sub(fundingState.lastFundingTime).toInt256();
            int256 acc;
            (fundingState.lastEMAPremium, acc) = getAccumulatedFunding(
                timeDelta,
                fundingState.lastEMAPremium,
                fundingState.lastPremium,
                fundingState.lastIndexPrice.toInt256() // ema is according to the old index
            );
            fundingState.accumulatedFundingPerContract = fundingState.accumulatedFundingPerContract.add(
                acc.div(FUNDING_PERIOD)
            );
            fundingState.lastFundingTime = endTimestamp;
        }

        // always update
        fundingState.lastIndexPrice = newIndexPrice; // should update before premium()
        fundingState.lastPremium = premiumFromPoolAccount(account);
    }

    /**
     * @notice Solve t in emaPremium == y equation
     *
     * @param y Required function output.
     * @param v0 LastEMAPremium.
     * @param _lastPremium LastPremium.
     */
    function timeOnFundingCurve(
        int256 y,
        int256 v0,
        int256 _lastPremium
    )
        internal
        view
        returns (
            int256 t // normal int, not WAD
        )
    {
        require(y != _lastPremium, "no solution 1 on funding curve");
        t = y.sub(_lastPremium);
        t = t.wdiv(v0.sub(_lastPremium));
        require(t > 0, "no solution 2 on funding curve");
        require(t < LibMathSigned.WAD(), "no solution 3 on funding curve");
        t = t.wln();
        t = t.wdiv(emaAlpha2Ln);
        t = t.ceil(LibMathSigned.WAD()) / LibMathSigned.WAD();
    }

    /**
     * @notice Sum emaPremium curve between [x, y)
     *
     * @param x Begin time. normal int, not WAD.
     * @param y End time. normal int, not WAD.
     * @param v0 LastEMAPremium.
     * @param _lastPremium LastPremium.
     */
    function integrateOnFundingCurve(
        int256 x,
        int256 y,
        int256 v0,
        int256 _lastPremium
    ) internal view returns (int256 r) {
        require(x <= y, "integrate reversed");
        r = v0.sub(_lastPremium);
        r = r.wmul(emaAlpha2.wpowi(x).sub(emaAlpha2.wpowi(y)));
        r = r.wdiv(governance.emaAlpha);
        r = r.add(_lastPremium.mul(y.sub(x)));
    }

   /**
     * @notice The intermediate variables required by getAccumulatedFunding. This is only used to move stack
     *         variables to storage variables.
     */
    struct AccumulatedFundingCalculator {
        int256 vLimit;
        int256 vDampener;
        int256 t1; // normal int, not WAD
        int256 t2; // normal int, not WAD
        int256 t3; // normal int, not WAD
        int256 t4; // normal int, not WAD
    }

    /**
     * @notice Calculate the `Acc`. Sigma the funding rate curve while considering the limit and dampener. There are
     *         4 boundary points on the curve (-GovMarkPremiumLimit, -GovFundingDampener, +GovFundingDampener, +GovMarkPremiumLimit)
     *         which segment the curve into 5 parts, so that the calculation can be arranged into 5 * 5 = 25 cases.
     *         In order to reduce the amount of calculation, the code is expanded into 25 branches.
     *
     * @param n Time span. normal int, not WAD.
     * @param v0 LastEMAPremium.
     * @param _lastPremium LastPremium.
     * @param _lastIndexPrice LastIndexPrice.
     */
    function getAccumulatedFunding(
        int256 n,
        int256 v0,
        int256 _lastPremium,
        int256 _lastIndexPrice
    )
        internal
        view
        returns (
            int256 vt, // new LastEMAPremium
            int256 acc
        )
    {
        require(n > 0, "we can't go back in time");
        AccumulatedFundingCalculator memory ctx;
        vt = v0.sub(_lastPremium);
        vt = vt.wmul(emaAlpha2.wpowi(n));
        vt = vt.add(_lastPremium);
        ctx.vLimit = governance.markPremiumLimit.wmul(_lastIndexPrice);
        ctx.vDampener = governance.fundingDampener.wmul(_lastIndexPrice);
        if (v0 <= -ctx.vLimit) {
            // part A
            if (vt <= -ctx.vLimit) {
                acc = (-ctx.vLimit).add(ctx.vDampener).mul(n);
            } else if (vt <= -ctx.vDampener) {
                ctx.t1 = timeOnFundingCurve(-ctx.vLimit, v0, _lastPremium);
                acc = (-ctx.vLimit).mul(ctx.t1);
                acc = acc.add(integrateOnFundingCurve(ctx.t1, n, v0, _lastPremium));
                acc = acc.add(ctx.vDampener.mul(n));
            } else if (vt <= ctx.vDampener) {
                ctx.t1 = timeOnFundingCurve(-ctx.vLimit, v0, _lastPremium);
                ctx.t2 = timeOnFundingCurve(-ctx.vDampener, v0, _lastPremium);
                acc = (-ctx.vLimit).mul(ctx.t1);
                acc = acc.add(integrateOnFundingCurve(ctx.t1, ctx.t2, v0, _lastPremium));
                acc = acc.add(ctx.vDampener.mul(ctx.t2));
            } else if (vt <= ctx.vLimit) {
                ctx.t1 = timeOnFundingCurve(-ctx.vLimit, v0, _lastPremium);
                ctx.t2 = timeOnFundingCurve(-ctx.vDampener, v0, _lastPremium);
                ctx.t3 = timeOnFundingCurve(ctx.vDampener, v0, _lastPremium);
                acc = (-ctx.vLimit).mul(ctx.t1);
                acc = acc.add(integrateOnFundingCurve(ctx.t1, ctx.t2, v0, _lastPremium));
                acc = acc.add(integrateOnFundingCurve(ctx.t3, n, v0, _lastPremium));
                acc = acc.add(ctx.vDampener.mul(ctx.t2.sub(n).add(ctx.t3)));
            } else {
                ctx.t1 = timeOnFundingCurve(-ctx.vLimit, v0, _lastPremium);
                ctx.t2 = timeOnFundingCurve(-ctx.vDampener, v0, _lastPremium);
                ctx.t3 = timeOnFundingCurve(ctx.vDampener, v0, _lastPremium);
                ctx.t4 = timeOnFundingCurve(ctx.vLimit, v0, _lastPremium);
                acc = (-ctx.vLimit).mul(ctx.t1);
                acc = acc.add(integrateOnFundingCurve(ctx.t1, ctx.t2, v0, _lastPremium));
                acc = acc.add(integrateOnFundingCurve(ctx.t3, ctx.t4, v0, _lastPremium));
                acc = acc.add(ctx.vLimit.mul(n.sub(ctx.t4)));
                acc = acc.add(ctx.vDampener.mul(ctx.t2.sub(n).add(ctx.t3)));
            }
        } else if (v0 <= -ctx.vDampener) {
            // part B
            if (vt <= -ctx.vLimit) {
                ctx.t4 = timeOnFundingCurve(-ctx.vLimit, v0, _lastPremium);
                acc = integrateOnFundingCurve(0, ctx.t4, v0, _lastPremium);
                acc = acc.add((-ctx.vLimit).mul(n.sub(ctx.t4)));
                acc = acc.add(ctx.vDampener.mul(n));
            } else if (vt <= -ctx.vDampener) {
                acc = integrateOnFundingCurve(0, n, v0, _lastPremium);
                acc = acc.add(ctx.vDampener.mul(n));
            } else if (vt <= ctx.vDampener) {
                ctx.t2 = timeOnFundingCurve(-ctx.vDampener, v0, _lastPremium);
                acc = integrateOnFundingCurve(0, ctx.t2, v0, _lastPremium);
                acc = acc.add(ctx.vDampener.mul(ctx.t2));
            } else if (vt <= ctx.vLimit) {
                ctx.t2 = timeOnFundingCurve(-ctx.vDampener, v0, _lastPremium);
                ctx.t3 = timeOnFundingCurve(ctx.vDampener, v0, _lastPremium);
                acc = integrateOnFundingCurve(0, ctx.t2, v0, _lastPremium);
                acc = acc.add(integrateOnFundingCurve(ctx.t3, n, v0, _lastPremium));
                acc = acc.add(ctx.vDampener.mul(ctx.t2.sub(n).add(ctx.t3)));
            } else {
                ctx.t2 = timeOnFundingCurve(-ctx.vDampener, v0, _lastPremium);
                ctx.t3 = timeOnFundingCurve(ctx.vDampener, v0, _lastPremium);
                ctx.t4 = timeOnFundingCurve(ctx.vLimit, v0, _lastPremium);
                acc = integrateOnFundingCurve(0, ctx.t2, v0, _lastPremium);
                acc = acc.add(integrateOnFundingCurve(ctx.t3, ctx.t4, v0, _lastPremium));
                acc = acc.add(ctx.vLimit.mul(n.sub(ctx.t4)));
                acc = acc.add(ctx.vDampener.mul(ctx.t2.sub(n).add(ctx.t3)));
            }
        } else if (v0 <= ctx.vDampener) {
            // part C
            if (vt <= -ctx.vLimit) {
                ctx.t3 = timeOnFundingCurve(-ctx.vDampener, v0, _lastPremium);
                ctx.t4 = timeOnFundingCurve(-ctx.vLimit, v0, _lastPremium);
                acc = integrateOnFundingCurve(ctx.t3, ctx.t4, v0, _lastPremium);
                acc = acc.add((-ctx.vLimit).mul(n.sub(ctx.t4)));
                acc = acc.add(ctx.vDampener.mul(n.sub(ctx.t3)));
            } else if (vt <= -ctx.vDampener) {
                ctx.t3 = timeOnFundingCurve(-ctx.vDampener, v0, _lastPremium);
                acc = integrateOnFundingCurve(ctx.t3, n, v0, _lastPremium);
                acc = acc.add(ctx.vDampener.mul(n.sub(ctx.t3)));
            } else if (vt <= ctx.vDampener) {
                acc = 0;
            } else if (vt <= ctx.vLimit) {
                ctx.t3 = timeOnFundingCurve(ctx.vDampener, v0, _lastPremium);
                acc = integrateOnFundingCurve(ctx.t3, n, v0, _lastPremium);
                acc = acc.sub(ctx.vDampener.mul(n.sub(ctx.t3)));
            } else {
                ctx.t3 = timeOnFundingCurve(ctx.vDampener, v0, _lastPremium);
                ctx.t4 = timeOnFundingCurve(ctx.vLimit, v0, _lastPremium);
                acc = integrateOnFundingCurve(ctx.t3, ctx.t4, v0, _lastPremium);
                acc = acc.add(ctx.vLimit.mul(n.sub(ctx.t4)));
                acc = acc.sub(ctx.vDampener.mul(n.sub(ctx.t3)));
            }
        } else if (v0 <= ctx.vLimit) {
            // part D
            if (vt <= -ctx.vLimit) {
                ctx.t2 = timeOnFundingCurve(ctx.vDampener, v0, _lastPremium);
                ctx.t3 = timeOnFundingCurve(-ctx.vDampener, v0, _lastPremium);
                ctx.t4 = timeOnFundingCurve(-ctx.vLimit, v0, _lastPremium);
                acc = integrateOnFundingCurve(0, ctx.t2, v0, _lastPremium);
                acc = acc.add(integrateOnFundingCurve(ctx.t3, ctx.t4, v0, _lastPremium));
                acc = acc.add((-ctx.vLimit).mul(n.sub(ctx.t4)));
                acc = acc.add(ctx.vDampener.mul(n.sub(ctx.t3).sub(ctx.t2)));
            } else if (vt <= -ctx.vDampener) {
                ctx.t2 = timeOnFundingCurve(ctx.vDampener, v0, _lastPremium);
                ctx.t3 = timeOnFundingCurve(-ctx.vDampener, v0, _lastPremium);
                acc = integrateOnFundingCurve(0, ctx.t2, v0, _lastPremium);
                acc = acc.add(integrateOnFundingCurve(ctx.t3, n, v0, _lastPremium));
                acc = acc.add(ctx.vDampener.mul(n.sub(ctx.t3).sub(ctx.t2)));
            } else if (vt <= ctx.vDampener) {
                ctx.t2 = timeOnFundingCurve(ctx.vDampener, v0, _lastPremium);
                acc = integrateOnFundingCurve(0, ctx.t2, v0, _lastPremium);
                acc = acc.sub(ctx.vDampener.mul(ctx.t2));
            } else if (vt <= ctx.vLimit) {
                acc = integrateOnFundingCurve(0, n, v0, _lastPremium);
                acc = acc.sub(ctx.vDampener.mul(n));
            } else {
                ctx.t4 = timeOnFundingCurve(ctx.vLimit, v0, _lastPremium);
                acc = integrateOnFundingCurve(0, ctx.t4, v0, _lastPremium);
                acc = acc.add(ctx.vLimit.mul(n.sub(ctx.t4)));
                acc = acc.sub(ctx.vDampener.mul(n));
            }
        } else {
            // part E
            if (vt <= -ctx.vLimit) {
                ctx.t1 = timeOnFundingCurve(ctx.vLimit, v0, _lastPremium);
                ctx.t2 = timeOnFundingCurve(ctx.vDampener, v0, _lastPremium);
                ctx.t3 = timeOnFundingCurve(-ctx.vDampener, v0, _lastPremium);
                ctx.t4 = timeOnFundingCurve(-ctx.vLimit, v0, _lastPremium);
                acc = ctx.vLimit.mul(ctx.t1);
                acc = acc.add(integrateOnFundingCurve(ctx.t1, ctx.t2, v0, _lastPremium));
                acc = acc.add(integrateOnFundingCurve(ctx.t3, ctx.t4, v0, _lastPremium));
                acc = acc.add((-ctx.vLimit).mul(n.sub(ctx.t4)));
                acc = acc.add(ctx.vDampener.mul(n.sub(ctx.t3).sub(ctx.t2)));
            } else if (vt <= -ctx.vDampener) {
                ctx.t1 = timeOnFundingCurve(ctx.vLimit, v0, _lastPremium);
                ctx.t2 = timeOnFundingCurve(ctx.vDampener, v0, _lastPremium);
                ctx.t3 = timeOnFundingCurve(-ctx.vDampener, v0, _lastPremium);
                acc = ctx.vLimit.mul(ctx.t1);
                acc = acc.add(integrateOnFundingCurve(ctx.t1, ctx.t2, v0, _lastPremium));
                acc = acc.add(integrateOnFundingCurve(ctx.t3, n, v0, _lastPremium));
                acc = acc.add(ctx.vDampener.mul(n.sub(ctx.t3).sub(ctx.t2)));
            } else if (vt <= ctx.vDampener) {
                ctx.t1 = timeOnFundingCurve(ctx.vLimit, v0, _lastPremium);
                ctx.t2 = timeOnFundingCurve(ctx.vDampener, v0, _lastPremium);
                acc = ctx.vLimit.mul(ctx.t1);
                acc = acc.add(integrateOnFundingCurve(ctx.t1, ctx.t2, v0, _lastPremium));
                acc = acc.add(ctx.vDampener.mul(-ctx.t2));
            } else if (vt <= ctx.vLimit) {
                ctx.t1 = timeOnFundingCurve(ctx.vLimit, v0, _lastPremium);
                acc = ctx.vLimit.mul(ctx.t1);
                acc = acc.add(integrateOnFundingCurve(ctx.t1, n, v0, _lastPremium));
                acc = acc.sub(ctx.vDampener.mul(n));
            } else {
                acc = ctx.vLimit.sub(ctx.vDampener).mul(n);
            }
        }
    } // getAccumulatedFunding
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_globalConfig","type":"address"},{"internalType":"address","name":"_perpetualProxy","type":"address"},{"internalType":"address","name":"_priceFeeder","type":"address"},{"internalType":"address","name":"_shareToken","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[],"name":"CreateAMM","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"lastFundingTime","type":"uint256"},{"internalType":"int256","name":"lastPremium","type":"int256"},{"internalType":"int256","name":"lastEMAPremium","type":"int256"},{"internalType":"uint256","name":"lastIndexPrice","type":"uint256"},{"internalType":"int256","name":"accumulatedFundingPerContract","type":"int256"}],"indexed":false,"internalType":"struct LibTypes.FundingState","name":"fundingState","type":"tuple"}],"name":"UpdateFundingRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"},{"indexed":false,"internalType":"int256","name":"value","type":"int256"}],"name":"UpdateGovernanceParameter","type":"event"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"addLiquidity","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"limitPrice","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"buy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"tradeAmount","type":"uint256"},{"internalType":"uint256","name":"limitPrice","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"withdrawAmount","type":"uint256"}],"name":"buyAndWithdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"trader","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"limitPrice","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"buyFromWhitelisted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"createPool","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"currentAccumulatedFundingPerContract","outputs":[{"internalType":"int256","name":"","type":"int256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"currentAvailableMargin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"currentFairPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"currentFundingRate","outputs":[{"internalType":"int256","name":"","type":"int256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"currentFundingState","outputs":[{"components":[{"internalType":"uint256","name":"lastFundingTime","type":"uint256"},{"internalType":"int256","name":"lastPremium","type":"int256"},{"internalType":"int256","name":"lastEMAPremium","type":"int256"},{"internalType":"uint256","name":"lastIndexPrice","type":"uint256"},{"internalType":"int256","name":"accumulatedFundingPerContract","type":"int256"}],"internalType":"struct LibTypes.FundingState","name":"","type":"tuple"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"currentMarkPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"currentPremium","outputs":[{"internalType":"int256","name":"","type":"int256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"currentPremiumRate","outputs":[{"internalType":"int256","name":"","type":"int256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositAndAddLiquidity","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"uint256","name":"tradeAmount","type":"uint256"},{"internalType":"uint256","name":"limitPrice","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"depositAndBuy","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"uint256","name":"tradeAmount","type":"uint256"},{"internalType":"uint256","name":"limitPrice","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"depositAndSell","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"emaAlpha2","outputs":[{"internalType":"int256","name":"","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"emaAlpha2Ln","outputs":[{"internalType":"int256","name":"","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getGovernance","outputs":[{"components":[{"internalType":"uint256","name":"poolFeeRate","type":"uint256"},{"internalType":"uint256","name":"poolDevFeeRate","type":"uint256"},{"internalType":"int256","name":"emaAlpha","type":"int256"},{"internalType":"uint256","name":"updatePremiumPrize","type":"uint256"},{"internalType":"int256","name":"markPremiumLimit","type":"int256"},{"internalType":"int256","name":"fundingDampener","type":"int256"}],"internalType":"struct LibTypes.AMMGovernanceConfig","name":"","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"globalConfig","outputs":[{"internalType":"contract IGlobalConfig","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"indexPrice","outputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastFundingRate","outputs":[{"internalType":"int256","name":"","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastFundingState","outputs":[{"components":[{"internalType":"uint256","name":"lastFundingTime","type":"uint256"},{"internalType":"int256","name":"lastPremium","type":"int256"},{"internalType":"int256","name":"lastEMAPremium","type":"int256"},{"internalType":"uint256","name":"lastIndexPrice","type":"uint256"},{"internalType":"int256","name":"accumulatedFundingPerContract","type":"int256"}],"internalType":"struct LibTypes.FundingState","name":"","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"perpetualProxy","outputs":[{"internalType":"contract IPerpetual","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"positionSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"priceFeeder","outputs":[{"internalType":"contract IPriceFeeder","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"shareAmount","type":"uint256"}],"name":"removeLiquidity","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"limitPrice","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"sell","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"tradeAmount","type":"uint256"},{"internalType":"uint256","name":"limitPrice","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"withdrawAmount","type":"uint256"}],"name":"sellAndWithdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"trader","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"limitPrice","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"sellFromWhitelisted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"int256","name":"value","type":"int256"}],"name":"setGovernanceParameter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"settleShare","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"shareTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"updateIndex","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060405162005a8738038062005a878339810160408190526200003491620000f4565b836001600160a01b038116620000675760405162461bcd60e51b81526004016200005e9062000199565b60405180910390fd5b600f80546001600160a01b03199081166001600160a01b0393841617909155600e80548216858416179055600d80548216868416179055601080549091169183169190911790556040517f6aa860b940c7799e6bdf99ed372f8f4aeb7017da638e5eedeb47cf68d577d02290600090a150505050620001e0565b8051620000ee81620001c6565b92915050565b600080600080608085870312156200010b57600080fd5b6000620001198787620000e1565b94505060206200012c87828801620000e1565b93505060406200013f87828801620000e1565b92505060606200015287828801620000e1565b91505092959194509250565b60006200016d601583620001ab565b7f696e76616c696420676c6f62616c20636f6e6669670000000000000000000000815260200192915050565b60208082528101620000ee816200015e565b90815260200190565b60006001600160a01b038216620000ee565b620001d181620001b4565b8114620001dd57600080fd5b50565b61589780620001f06000396000f3fe6080604052600436106101f85760003560e01c8063831190731161010d578063a8681826116100a0578063d3c9727c1161006f578063d3c9727c1461050a578063de12bcac1461052a578063dedcd0741461053f578063e21ebac914610561578063f3ffd28a14610574576101f8565b8063a8681826146104ad578063b6a20fc1146104c2578063b8f110bc146104e2578063b9f412b0146104f5576101f8565b8063a3bad878116100dc578063a3bad87814610438578063a7a7227e14610458578063a7c1abe014610478578063a812e9ac1461048d576101f8565b806383119073146103d957806384f523ad146103ee57806395af65dd146104035780639c8f9f2314610418576101f8565b80633e99a53b1161019057806353de38141161015f57806353de38141461035a57806355ddeabe1461036f5780636dcd09d71461038457806373da22bf146103a45780638259e6a0146103b9576101f8565b80633e99a53b146102f057806340993b26146103055780634928229a1461032557806351c6590a1461033a576101f8565b8063289b3c0d116101cc578063289b3c0d1461028257806330e04ca1146102a45780633aef4d0b146102c65780633b495ebf146102db576101f8565b80624f69b0146101fd57806306a7570c1461021257806310bace8c1461023d5780631fada48514610260575b600080fd5b61021061020b3660046147cc565b610589565b005b34801561021e57600080fd5b50610227610609565b6040516102349190615761565b60405180910390f35b34801561024957600080fd5b50610252610646565b60405161023492919061577d565b34801561026c57600080fd5b506102756106f2565b6040516102349190615449565b34801561028e57600080fd5b50610297610701565b6040516102349190615753565b3480156102b057600080fd5b506102b9610746565b6040516102349190615465565b3480156102d257600080fd5b506102b961075d565b3480156102e757600080fd5b506102b961076f565b3480156102fc57600080fd5b50610275610775565b34801561031157600080fd5b506102b96103203660046148cd565b610784565b34801561033157600080fd5b506102b961079c565b34801561034657600080fd5b5061021061035536600461487f565b6107eb565b34801561036657600080fd5b50610210610ad0565b34801561037b57600080fd5b506102b9610db1565b34801561039057600080fd5b506102b961039f36600461474d565b610dc3565b3480156103b057600080fd5b506102b9610e77565b3480156103c557600080fd5b506102106103d436600461487f565b610e7d565b3480156103e557600080fd5b506102b96110c7565b3480156103fa57600080fd5b506102b96110d9565b34801561040f57600080fd5b506102b9611169565b34801561042457600080fd5b5061021061043336600461487f565b61117a565b34801561044457600080fd5b506102b961045336600461474d565b611595565b34801561046457600080fd5b5061021061047336600461491a565b61163e565b34801561048457600080fd5b506102756116bd565b34801561049957600080fd5b506102106104a83660046147cc565b6116cc565b3480156104b957600080fd5b506102b9611a3e565b3480156104ce57600080fd5b506102106104dd36600461491a565b611a50565b6102106104f036600461491a565b611a61565b34801561050157600080fd5b50610210611adf565b34801561051657600080fd5b506102b96105253660046148cd565b611d1d565b34801561053657600080fd5b506102b9611d2b565b34801561054b57600080fd5b50610554611d3d565b6040516102349190615375565b61021061056f36600461491a565b611d4c565b34801561058057600080fd5b50610227611dca565b81156105f657600d546040516317a790f160e11b81526001600160a01b0390911690632f4f21e29034906105c390339087906004016153ac565b6000604051808303818588803b1580156105dc57600080fd5b505af11580156105f0573d6000803e3d6000fd5b50505050505b801561060557610605816107eb565b5050565b6106116144f9565b506040805160a08101825260065481526007546020820152600854918101919091526009546060820152600a54608082015290565b600e546040805163501ad8ff60e11b8152815160009384936001600160a01b039091169263a035b1fe9260048083019392829003018186803b15801561068b57600080fd5b505afa15801561069f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106c3919081019061489d565b9092509050816106ee5760405162461bcd60e51b81526004016106e590615673565b60405180910390fd5b9091565b600e546001600160a01b031681565b610709614528565b506040805160c08101825260005481526001546020820152600254918101919091526003546060820152600454608082015260055460a082015290565b6000610750611dd6565b610758611eb9565b905090565b6000610767611dd6565b61075861079c565b600b5481565b600d546001600160a01b031681565b600061079233858585611f52565b90505b9392505050565b6000806107a761234c565b6005549091506107e5906107c590839060000363ffffffff61239a16565b6005546107d990849063ffffffff6123b516565b9063ffffffff6123c516565b91505090565b600d5460408051631006976960e11b815290516000926001600160a01b03169163200d2ed2916004808301926020929190829003018186803b15801561083057600080fd5b505afa158015610844573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108689190810190614806565b600281111561087357fe5b146108905760405162461bcd60e51b81526004016106e590615513565b60008061089b61240b565b909250905080158015906108ae57508115155b6108ca5760405162461bcd60e51b81526004016106e590615663565b3360006108dd848463ffffffff6124bb16565b9050600061090260026108f6888563ffffffff6124ec16565b9063ffffffff61251416565b600d549091506001600160a01b0316639272c80e8461091f61254e565b846040518463ffffffff1660e01b815260040161093e9392919061542e565b600060405180830381600087803b15801561095857600080fd5b505af115801561096c573d6000803e3d6000fd5b5050600d54600092506001600160a01b031690506319d3b88b8561098e61254e565b6001878c6040518663ffffffff1660e01b81526004016109b29594939291906153e2565b6040805180830381600087803b1580156109cb57600080fd5b505af11580156109df573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a03919081019061489d565b509050610ab584610ab087610aa48b601060009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a6057600080fd5b505afa158015610a74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a989190810190614824565b9063ffffffff6124ec16565b9063ffffffff6124bb16565b61255d565b610abd6125fd565b610ac784826126c9565b50505050505050565b600d5460408051631006976960e11b815290516002926001600160a01b03169163200d2ed2916004808301926020929190829003018186803b158015610b1557600080fd5b505afa158015610b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b4d9190810190614806565b6002811115610b5857fe5b14610b755760405162461bcd60e51b81526004016106e590615513565b33610b7e61455e565b600d546001600160a01b0316622bc164610b9661254e565b6040518263ffffffff1660e01b8152600401610bb29190615375565b60c06040518083038186803b158015610bca57600080fd5b505afa158015610bde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c029190810190614842565b90506000610c0f82612934565b6010546040516370a0823160e01b81529192506000916001600160a01b03909116906370a0823190610c45908790600401615375565b60206040518083038186803b158015610c5d57600080fd5b505afa158015610c71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c959190810190614824565b90506000610d32601060009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cea57600080fd5b505afa158015610cfe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d229190810190614824565b610aa4848663ffffffff6124ec16565b600d549091506001600160a01b0316639272c80e610d4e61254e565b87846040518463ffffffff1660e01b8152600401610d6e9392919061542e565b600060405180830381600087803b158015610d8857600080fd5b505af1158015610d9c573d6000803e3d6000fd5b50505050610daa8583612a65565b5050505050565b6000610dbb611dd6565b61075861234c565b600f5460405163df5e9b2960e01b81526000916001600160a01b03169063df5e9b2990610df4903390600401615383565b60206040518083038186803b158015610e0c57600080fd5b505afa158015610e20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e4491908101906147ae565b610e605760405162461bcd60e51b81526004016106e5906154c3565b610e6c85858585612b05565b90505b949350505050565b600c5481565b60008111610e9d5760405162461bcd60e51b81526004016106e590615623565b600d5460408051631006976960e11b815290516000926001600160a01b03169163200d2ed2916004808301926020929190829003018186803b158015610ee257600080fd5b505afa158015610ef6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f1a9190810190614806565b6002811115610f2557fe5b14610f425760405162461bcd60e51b81526004016106e590615513565b610f4a6110d9565b15610f675760405162461bcd60e51b81526004016106e590615563565b336000610f72612ce7565b9050600080610f7f610646565b9092509050610f8e8284612ceb565b600d546001600160a01b0316639272c80e85610fa861254e565b610fbd60026108f6888c63ffffffff6124ec16565b6040518463ffffffff1660e01b8152600401610fdb9392919061542e565b600060405180830381600087803b158015610ff557600080fd5b505af1158015611009573d6000803e3d6000fd5b5050600d54600092506001600160a01b031690506319d3b88b8661102b61254e565b6001878b6040518663ffffffff1660e01b815260040161104f9594939291906153e2565b6040805180830381600087803b15801561106857600080fd5b505af115801561107c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110a0919081019061489d565b5090506110ad858761255d565b6110b56125fd565b6110bf85826126c9565b505050505050565b60006110d1611dd6565b610758612d1d565b600d546000906001600160a01b0316622bc1646110f461254e565b6040518263ffffffff1660e01b81526004016111109190615375565b60c06040518083038186803b15801561112857600080fd5b505afa15801561113c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111609190810190614842565b60200151905090565b6000611173611dd6565b50600a5490565b600d5460408051631006976960e11b815290516000926001600160a01b03169163200d2ed2916004808301926020929190829003018186803b1580156111bf57600080fd5b505afa1580156111d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111f79190810190614806565b600281111561120257fe5b1461121f5760405162461bcd60e51b81526004016106e590615513565b3360008061122b61240b565b9092509050801580159061123e57508115155b61125a5760405162461bcd60e51b81526004016106e590615663565b6010546040516370a0823160e01b815285916001600160a01b0316906370a082319061128a903390600401615383565b60206040518083038186803b1580156112a257600080fd5b505afa1580156112b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112da9190810190614824565b10156112f85760405162461bcd60e51b81526004016106e590615533565b600061130a838363ffffffff6124bb16565b905060006113a7601060009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561135f57600080fd5b505afa158015611373573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113979190810190614824565b610aa4888663ffffffff6124ec16565b90506000600d60009054906101000a90046001600160a01b03166001600160a01b031663289b3c0d6040518163ffffffff1660e01b81526004016101006040518083038186803b1580156113fa57600080fd5b505afa15801561140e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114329190810190614860565b60c00151905061145861144b838363ffffffff612db616565b839063ffffffff612de616565b600d549092506001600160a01b0316639272c80e61147461254e565b8861148a60026108f6898963ffffffff6124ec16565b6040518463ffffffff1660e01b81526004016114a89392919061542e565b600060405180830381600087803b1580156114c257600080fd5b505af11580156114d6573d6000803e3d6000fd5b505050506114e48688612a65565b600d546000906001600160a01b03166319d3b88b8861150161254e565b600288886040518663ffffffff1660e01b81526004016115259594939291906153e2565b6040805180830381600087803b15801561153e57600080fd5b505af1158015611552573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611576919081019061489d565b5090506115816125fd565b61158b87826126c9565b5050505050505050565b600f5460405163df5e9b2960e01b81526000916001600160a01b03169063df5e9b29906115c6903390600401615383565b60206040518083038186803b1580156115de57600080fd5b505afa1580156115f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061161691908101906147ae565b6116325760405162461bcd60e51b81526004016106e5906154c3565b610e6c85858585611f52565b83156116515761164f848484610784565b505b80156116b757600d54604051636da8c6d960e11b81526001600160a01b039091169063db518db2906116899033908590600401615391565b600060405180830381600087803b1580156116a357600080fd5b505af115801561158b573d6000803e3d6000fd5b50505050565b600f546001600160a01b031681565b600f5460408051638da5cb5b60e01b8152905133926001600160a01b031691638da5cb5b916004808301926020929190829003018186803b15801561171057600080fd5b505afa158015611724573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611748919081019061472f565b6001600160a01b03161461176e5760405162461bcd60e51b81526004016106e590615733565b816a706f6f6c4665655261746560a81b14156117955761178d81612e0e565b600055611a02565b816d706f6f6c4465764665655261746560901b14156117bf576117b781612e0e565b600155611a02565b8167656d61416c70686160c01b141561184157600081136117f25760405162461bcd60e51b81526004016106e5906156a3565b670de0b6b3a764000081131561181a5760405162461bcd60e51b81526004016106e590615493565b6002819055670de0b6b3a7640000819003600b81905561183990612e34565b600c55611a02565b81717570646174655072656d69756d5072697a6560701b141561186f5761186781612e0e565b600355611a02565b816f1b585c9ad41c995b5a5d5b531a5b5a5d60821b1415611894576004819055611a02565b816e333ab73234b733a230b6b832b732b960891b14156118b8576005819055611a02565b817f616363756d756c6174656446756e64696e67506572436f6e7472616374000000141561198f57600d5460408051631006976960e11b815290516001926001600160a01b03169163200d2ed2916004808301926020929190829003018186803b15801561192557600080fd5b505afa158015611939573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061195d9190810190614806565b600281111561196857fe5b146119855760405162461bcd60e51b81526004016106e590615513565b600a819055611a02565b816a383934b1b2a332b2b232b960a91b14156119ea576119ae816130bb565b6119ca5760405162461bcd60e51b81526004016106e5906154a3565b600e80546001600160a01b0319166001600160a01b038316179055611a02565b60405162461bcd60e51b81526004016106e590615713565b817fc3d18999fb01e35e747dd6b7658ba5c080fd98900f063b48d25d7af86f55214882604051611a329190615465565b60405180910390a25050565b6000611a48611dd6565b6107586130f4565b83156116515761164f848484611d1d565b8315611ace57600d546040516317a790f160e11b81526001600160a01b0390911690632f4f21e2903490611a9b90339089906004016153ac565b6000604051808303818588803b158015611ab457600080fd5b505af1158015611ac8573d6000803e3d6000fd5b50505050505b82156116b757610daa838383610784565b600d5460408051631006976960e11b815290516000926001600160a01b03169163200d2ed2916004808301926020929190829003018186803b158015611b2457600080fd5b505afa158015611b38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611b5c9190810190614806565b6002811115611b6757fe5b14611b845760405162461bcd60e51b81526004016106e590615513565b600954611b8f6125fd565b600d5460408051631d68877b60e11b815290516000926001600160a01b031691633ad10ef6916004808301926020929190829003018186803b158015611bd457600080fd5b505afa158015611be8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c0c919081019061472f565b600954909150821461060557600d54600354604051634939640760e11b81526001600160a01b0390921691639272c80e91611c4d91859133916004016153ba565b600060405180830381600087803b158015611c6757600080fd5b505af1158015611c7b573d6000803e3d6000fd5b5050600d54604051631da68a2b60e21b81526001600160a01b03909116925063769a28ac9150611caf908490600401615375565b602060405180830381600087803b158015611cc957600080fd5b505af1158015611cdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611d0191908101906147ae565b6106055760405162461bcd60e51b81526004016106e590615653565b600061079233858585612b05565b6000611d35611dd6565b61075861318d565b6010546001600160a01b031690565b8315611db957600d546040516317a790f160e11b81526001600160a01b0390911690632f4f21e2903490611d8690339089906004016153ac565b6000604051808303818588803b158015611d9f57600080fd5b505af1158015611db3573d6000803e3d6000fd5b50505050505b82156116b757610daa838383611d1d565b611dd26144f9565b6106115b600d5460408051631006976960e11b815290516000926001600160a01b03169163200d2ed2916004808301926020929190829003018186803b158015611e1b57600080fd5b505afa158015611e2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e539190810190614806565b6002811115611e5e57fe5b14611e6857611eb7565b6000611e72612ce7565b9050600080611e7f610646565b600654919350915083141580611e9757506009548214155b80611ea3575060065481115b15611eb357611eb3838383613236565b5050505b565b6000611ec361455e565b600d546001600160a01b0316622bc164611edb61254e565b6040518263ffffffff1660e01b8152600401611ef79190615375565b60c06040518083038186803b158015611f0f57600080fd5b505afa158015611f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611f479190810190614842565b90506107e581612934565b600080600d60009054906101000a90046001600160a01b03166001600160a01b031663200d2ed26040518163ffffffff1660e01b815260040160206040518083038186803b158015611fa357600080fd5b505afa158015611fb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611fdb9190810190614806565b6002811115611fe657fe5b146120035760405162461bcd60e51b81526004016106e590615513565b600d546040516336a250cf60e21b81526001600160a01b039091169063da89433c90612033908790600401615465565b60206040518083038186803b15801561204b57600080fd5b505afa15801561205f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061208391908101906147ae565b61209f5760405162461bcd60e51b81526004016106e590615603565b60006120aa85613341565b9050808410156120cc5760405162461bcd60e51b81526004016106e590615473565b826120d5612ce7565b11156120f35760405162461bcd60e51b81526004016106e5906155f3565b600d546000906001600160a01b03166319d3b88b8861211061254e565b6002868b6040518663ffffffff1660e01b81526004016121349594939291906153e2565b6040805180830381600087803b15801561214d57600080fd5b505af1158015612161573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612185919081019061489d565b509050600061219a838863ffffffff6124ec16565b60008054919250906121b390839063ffffffff6124ec16565b6001549091506000906121cd90849063ffffffff6124ec16565b90506000600d60009054906101000a90046001600160a01b03166001600160a01b0316633ad10ef66040518163ffffffff1660e01b815260040160206040518083038186803b15801561221f57600080fd5b505afa158015612233573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612257919081019061472f565b600d549091506001600160a01b0316639272c80e8c61227461254e565b866040518463ffffffff1660e01b81526004016122939392919061542e565b600060405180830381600087803b1580156122ad57600080fd5b505af11580156122c1573d6000803e3d6000fd5b5050600d54604051634939640760e11b81526001600160a01b039091169250639272c80e91506122f9908e908590879060040161542e565b600060405180830381600087803b15801561231357600080fd5b505af1158015612327573d6000803e3d6000fd5b505050506123336125fd565b61233d8b866126c9565b50929998505050505050505050565b60008061235d60066003015461339d565b9050600061237161236c61318d565b61339d565b905061239382612387838263ffffffff6133c616565b9063ffffffff61340c16565b9250505090565b6000818313156123aa57816123ac565b825b90505b92915050565b6000818312156123aa57816123ac565b60008282018183128015906123da5750838112155b806123ef57506000831280156123ef57508381125b6123ac5760405162461bcd60e51b81526004016106e5906155c3565b600080612416611dd6565b61241e61455e565b600d546001600160a01b0316622bc16461243661254e565b6040518263ffffffff1660e01b81526004016124529190615375565b60c06040518083038186803b15801561246a57600080fd5b505afa15801561247e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506124a29190810190614842565b90506124ad81612934565b925080602001519150509091565b6000816124dd6124d385670de0b6b3a7640000612514565b6002855b0461344e565b816124e457fe5b049392505050565b6000670de0b6b3a76400006124dd6125048585612514565b6002670de0b6b3a76400006124d7565b600082612523575060006123af565b8282028284828161253057fe5b04146123ac5760405162461bcd60e51b81526004016106e590615593565b600d546001600160a01b031690565b6010546040516340c10f1960e01b81526001600160a01b03909116906340c10f199061258f9085908590600401615391565b602060405180830381600087803b1580156125a957600080fd5b505af11580156125bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506125e191908101906147ae565b6106055760405162461bcd60e51b81526004016106e590615553565b600d5460408051631006976960e11b815290516000926001600160a01b03169163200d2ed2916004808301926020929190829003018186803b15801561264257600080fd5b505afa158015612656573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061267a9190810190614806565b600281111561268557fe5b146126a25760405162461bcd60e51b81526004016106e590615513565b60006126ac612ce7565b90506000806126b9610646565b9092509050611eb3838383613236565b600d54604080516345a15a0160e01b815290516000926001600160a01b0316916345a15a0191600480830192602092919082900301818787803b15801561270f57600080fd5b505af1158015612723573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506127479190810190614824565b905081156127ef57600d5460405163f50c138b60e01b81526001600160a01b039091169063f50c138b906127819086908590600401615391565b602060405180830381600087803b15801561279b57600080fd5b505af11580156127af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506127d391908101906147ae565b6127ef5760405162461bcd60e51b81526004016106e590615693565b600d54604051631eacda4160e31b81526001600160a01b039091169063f566d208906128219086908590600401615391565b602060405180830381600087803b15801561283b57600080fd5b505af115801561284f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061287391908101906147ae565b61288f5760405162461bcd60e51b81526004016106e5906154e3565b600d546001600160a01b031663f566d2086128a861254e565b836040518363ffffffff1660e01b81526004016128c6929190615391565b602060405180830381600087803b1580156128e057600080fd5b505af11580156128f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061291891908101906147ae565b611eb35760405162461bcd60e51b81526004016106e590615613565b60a0810151600d5482516040516324c374e760e21b81526000939284926001600160a01b039091169163930dd39c9161296f91600401615457565b60206040518083038186803b15801561298757600080fd5b505afa15801561299b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506129bf9190810190614824565b90506129de6129d1856040015161339d565b839063ffffffff6133c616565b9150612a146129d18560600151612a086129fb886020015161339d565b859063ffffffff61347316565b9063ffffffff6133c616565b9150612a406129d18560800151612a08612a31886020015161339d565b600a549063ffffffff61347316565b9150612a5b612a5683600063ffffffff6123b516565b612e0e565b925050505b919050565b601054604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90612a979085908590600401615391565b602060405180830381600087803b158015612ab157600080fd5b505af1158015612ac5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612ae991908101906147ae565b6106055760405162461bcd60e51b81526004016106e590615483565b600080600d60009054906101000a90046001600160a01b03166001600160a01b031663200d2ed26040518163ffffffff1660e01b815260040160206040518083038186803b158015612b5657600080fd5b505afa158015612b6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612b8e9190810190614806565b6002811115612b9957fe5b14612bb65760405162461bcd60e51b81526004016106e590615513565b600d546040516336a250cf60e21b81526001600160a01b039091169063da89433c90612be6908790600401615465565b60206040518083038186803b158015612bfe57600080fd5b505afa158015612c12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612c3691908101906147ae565b612c525760405162461bcd60e51b81526004016106e590615603565b6000612c5d85613499565b905080841115612c7f5760405162461bcd60e51b81526004016106e590615473565b82612c88612ce7565b1115612ca65760405162461bcd60e51b81526004016106e5906155f3565b600d546000906001600160a01b03166319d3b88b88612cc361254e565b6001868b6040518663ffffffff1660e01b81526004016121349594939291906153e2565b4290565b60065415612d0b5760405162461bcd60e51b81526004016106e590615583565b60065560095560006007819055600855565b6000612d2761455e565b600d546001600160a01b0316622bc164612d3f61254e565b6040518263ffffffff1660e01b8152600401612d5b9190615375565b60c06040518083038186803b158015612d7357600080fd5b505afa158015612d87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612dab9190810190614842565b90506107e5816134e8565b600081612dd55760405162461bcd60e51b81526004016106e590615503565b818381612dde57fe5b069392505050565b600082821115612e085760405162461bcd60e51b81526004016106e590615723565b50900390565b600080821215612e305760405162461bcd60e51b81526004016106e5906156e3565b5090565b6000808213612e555760405162461bcd60e51b81526004016106e590615573565b701d6329f1c35ca4bfabb9f5610000000000821315612e865760405162461bcd60e51b81526004016106e5906154f3565b60006012670de0b6b3a76400005b67016345785d8a00008513612ec35784600a0294506f01bb7635c5de48ef4ce5b7b41cc43db083039250612e94565b678ac7230489e800008512612ef257600a850594506f01bb7635c5de48ef4ce5b7b41cc43db083019250612ec3565b670de0b6b3a7640000851215612f2f57612f14856725b946ebc0b36173613473565b94506ec097ce7bc90715b34b9f100000000083039250612ef2565b6725b946ebc0b36173851315612f6c57612f51856725b946ebc0b3617361340c565b94506ec097ce7bc90715b34b9f100000000083019250612f2f565b670de0b6b3a7640000851415612f995780612f878483613517565b81612f8e57fe5b059350505050612a60565b6725b946ebc0b36173851415612fd05780612fb48483613517565b81612fbb57fe5b05670de0b6b3a7640000019350505050612a60565b938402936e4e16f927cdca7f15b39123f740f5d192909201916f0120e3b5b9ad8aa08cf16e980000000060008187016ec097ce7bc90715b34b9f10000000006f0120e3b5b9ad8aa08cf16e97ffffffff198901028161302b57fe5b059050806002028501945060006ec097ce7bc90715b34b9f10000000008283028161305257fe5b05905060035b6ec097ce7bc90715b34b9f10000000008383020592508060ff16836002028161307d57fe5b059690960195600201602760ff8216106130965761309b565b613058565b846130a68887613517565b816130ad57fe5b059998505050505050505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612a5b575050151592915050565b60006130fe61455e565b600d546001600160a01b0316622bc16461311661254e565b6040518263ffffffff1660e01b81526004016131329190615375565b60c06040518083038186803b15801561314a57600080fd5b505afa15801561315e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506131829190810190614842565b90506107e581613561565b60008061319e60066003015461339d565b6004549091506000906131b890839063ffffffff61347316565b905060006131d46131c76135a3565b849063ffffffff6123c516565b90506131f66131e9848463ffffffff6123c516565b829063ffffffff61239a16565b905061321861320b848463ffffffff6133c616565b829063ffffffff6123b516565b905061322e612a5682600063ffffffff6123b516565b935050505090565b60065461324257611eb3565b61324a61455e565b600d546001600160a01b0316622bc16461326261254e565b6040518263ffffffff1660e01b815260040161327e9190615375565b60c06040518083038186803b15801561329657600080fd5b505afa1580156132aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506132ce9190810190614842565b90508060200151600014156132e35750611eb3565b6006548211156132f8576132f88184846135a9565b6133038184866135a9565b7fc0f950314c1203122896795efe729e8208b4c58eb5d6f41c476f32c773250a5d6006604051613333919061576f565b60405180910390a150505050565b600080600061334e61240b565b9092509050801580159061336157508115155b61337d5760405162461bcd60e51b81526004016106e590615663565b612a5b613390828663ffffffff612de616565b839063ffffffff6124bb16565b60006001600160ff1b03821115612e305760405162461bcd60e51b81526004016106e5906156d3565b60008183038183128015906133db5750838113155b806133f057506000831280156133f057508381135b6123ac5760405162461bcd60e51b81526004016106e590615703565b600080821215613423578160000391508260000392505b8161343f61343985670de0b6b3a7640000613682565b84613517565b8161344657fe5b059392505050565b6000828201838110156123ac5760405162461bcd60e51b81526004016106e590615523565b6000670de0b6b3a764000061343f61348b8585613682565b670de0b6b3a7640000613517565b60008060006134a661240b565b909250905080158015906134b957508115155b6134d55760405162461bcd60e51b81526004016106e590615663565b612a5b613390828663ffffffff61344e16565b6000806134f761236c84613561565b905061079561350a60066003015461339d565b829063ffffffff6133c616565b60008082136135385760405162461bcd60e51b81526004016106e5906155a3565b600083126135545761354d83600284056123c5565b90506123af565b6123ac83600284056133c6565b6020810151600090806135865760405162461bcd60e51b81526004016106e5906156b3565b600061359184612934565b9050612a5b818363ffffffff6124bb16565b60085490565b6006546135c85760405162461bcd60e51b81526004016106e5906156b3565b6006548110156135ea5760405162461bcd60e51b81526004016106e590615643565b600654811461366c5760065460009061360e9061236c90849063ffffffff612de616565b905060006136358260066002015460066001015461363060066003015461339d565b6136ed565b60089190915590506136616136528261708063ffffffff61420e16565b600a549063ffffffff6123c516565b600a55505060068190555b600982905561367a836134e8565b600755505050565b600082613691575060006123af565b826000191480156136a55750600160ff1b82145b156136c25760405162461bcd60e51b81526004016106e5906156c3565b828202828482816136cf57fe5b05146123ac5760405162461bcd60e51b81526004016106e5906156c3565b600080600086136137105760405162461bcd60e51b81526004016106e5906156f3565b613718614528565b613728868663ffffffff6133c616565b925061374f61374288600b5461427290919063ffffffff16565b849063ffffffff61347316565b9250613761838663ffffffff6123c516565b600454909350613777908563ffffffff61347316565b815260055461378c908563ffffffff61347316565b602082015280516000038613613ab157805160000383136137dc576137d5876137c9836020015184600001516000036123c590919063ffffffff16565b9063ffffffff61368216565b9150613aac565b806020015160000383136138575780516137fa9060000387876142e8565b604082018190528151613819916000919091039063ffffffff61368216565b915061383b61382e82604001518989896143cd565b839063ffffffff6123c516565b91506137d561382e88836020015161368290919063ffffffff16565b806020015183136138e55780516138729060000387876142e8565b6040820152602081015161388a9060000387876142e8565b6060820152604081015181516138ac916000919091039063ffffffff61368216565b91506138c561382e8260400151836060015189896143cd565b91506137d561382e8260600151836020015161368290919063ffffffff16565b805183136139b25780516138fd9060000387876142e8565b604082015260208101516139159060000387876142e8565b6060820152602081015161392a9087876142e8565b60808201526040810151815161394c916000919091039063ffffffff61368216565b915061396561382e8260400151836060015189896143cd565b915061397a61382e82608001518989896143cd565b91506137d561382e6139a183608001516107d98b86606001516133c690919063ffffffff16565b60208401519063ffffffff61368216565b80516139c29060000387876142e8565b604082015260208101516139da9060000387876142e8565b606082015260208101516139ef9087876142e8565b60808201528051613a019087876142e8565b60a082015260408101518151613a23916000919091039063ffffffff61368216565b9150613a3c61382e8260400151836060015189896143cd565b9150613a5561382e82608001518360a0015189896143cd565b9150613a8261382e613a748360a001518a6133c690919063ffffffff16565b83519063ffffffff61368216565b9150613aa961382e6139a183608001516107d98b86606001516133c690919063ffffffff16565b91505b614204565b80602001516000038613613c045780516000038313613b1f578051613ada9060000387876142e8565b60a08201819052613aef9060009088886143cd565b915061383b61382e613b0e8360a001518a6133c690919063ffffffff16565b83516000039063ffffffff61368216565b80602001516000038313613b3a5761383b60008888886143cd565b80602001518313613b6c57613b57816020015160000387876142e8565b606082018190526138c59060009088886143cd565b80518313613bb357613b86816020015160000387876142e8565b60608201526020810151613b9b9087876142e8565b608082015260608101516139659060009088886143cd565b613bc5816020015160000387876142e8565b60608201526020810151613bda9087876142e8565b60808201528051613bec9087876142e8565b60a08201526060810151613a3c9060009088886143cd565b80602001518613613d9c5780516000038313613c9657613c2c816020015160000387876142e8565b60808201528051613c419060000387876142e8565b60a082018190526080820151613c589188886143cd565b9150613c7761382e613b0e8360a001518a6133c690919063ffffffff16565b91506137d561382e6139a183608001518a6133c690919063ffffffff16565b80602001516000038313613cc957613cb6816020015160000387876142e8565b60808201819052613c77908888886143cd565b80602001518313613cdd5760009150613aac565b80518313613d2657613cf4816020015187876142e8565b60808201819052613d07908888886143cd565b91506137d56129d16139a183608001518a6133c690919063ffffffff16565b613d35816020015187876142e8565b60808201528051613d479087876142e8565b60a082018190526080820151613d5e9188886143cd565b9150613d7d61382e613a748360a001518a6133c690919063ffffffff16565b9150613aa96129d16139a183608001518a6133c690919063ffffffff16565b80518613613fa15780516000038313613e6257613dbe816020015187876142e8565b60608201526020810151613dd69060000387876142e8565b60808201528051613deb9060000387876142e8565b60a08201526060810151613e039060009088886143cd565b9150613e1c61382e82608001518360a0015189896143cd565b9150613e3b61382e613b0e8360a001518a6133c690919063ffffffff16565b91506137d561382e6139a18360600151612a0885608001518c6133c690919063ffffffff16565b80602001516000038313613ec457613e7f816020015187876142e8565b60608201526020810151613e979060000387876142e8565b60808201526060810151613eaf9060009088886143cd565b9150613e3b61382e82608001518989896143cd565b80602001518313613f1357613ede816020015187876142e8565b60608201819052613ef39060009088886143cd565b91506137d56129d18260600151836020015161368290919063ffffffff16565b80518313613f4457613f2860008888886143cd565b91506137d56129d188836020015161368290919063ffffffff16565b8051613f519087876142e8565b60a08201819052613f669060009088886143cd565b9150613f8561382e613a748360a001518a6133c690919063ffffffff16565b9150613aa96129d188836020015161368290919063ffffffff16565b8051600003831361408e578051613fb99087876142e8565b60408201526020810151613fce9087876142e8565b60608201526020810151613fe69060000387876142e8565b60808201528051613ffb9060000387876142e8565b60a0820152604081015181516140169163ffffffff61368216565b915061402f61382e8260400151836060015189896143cd565b915061404861382e82608001518360a0015189896143cd565b915061406761382e613b0e8360a001518a6133c690919063ffffffff16565b9150613aa961382e6139a18360600151612a0885608001518c6133c690919063ffffffff16565b8060200151600003831361411f5780516140a99087876142e8565b604082015260208101516140be9087876142e8565b606082015260208101516140d69060000387876142e8565b6080820152604081015181516140f19163ffffffff61368216565b915061410a61382e8260400151836060015189896143cd565b915061406761382e82608001518989896143cd565b806020015183136141a35780516141379087876142e8565b6040820152602081015161414c9087876142e8565b6060820152604081015181516141679163ffffffff61368216565b915061418061382e8260400151836060015189896143cd565b9150613aa961382e8260600151600003836020015161368290919063ffffffff16565b805183136141e55780516141b89087876142e8565b6040820181905281516141d09163ffffffff61368216565b9150613f8561382e82604001518989896143cd565b602081015181516142019189916137c99163ffffffff6133c616565b91505b5094509492505050565b60008161422d5760405162461bcd60e51b81526004016106e5906155d3565b816000191480156142415750600160ff1b83145b1561425e5760405162461bcd60e51b81526004016106e590615633565b600082848161426957fe5b05949350505050565b6000808212156142945760405162461bcd60e51b81526004016106e5906155b3565b600282076142aa57670de0b6b3a76400006142ac565b825b90506002820591505b81156123af576142c58384613473565b925060028207156142dd576142da8184613473565b90505b6002820591506142b5565b60008184141561430a5760405162461bcd60e51b81526004016106e5906154b3565b61431a848363ffffffff6133c616565b905061433c61432f848463ffffffff6133c616565b829063ffffffff61340c16565b90506000811361435e5760405162461bcd60e51b81526004016106e590615743565b614366614485565b81126143845760405162461bcd60e51b81526004016106e5906155e3565b61438d81612e34565b90506143a4600c548261340c90919063ffffffff16565b90506143ae614485565b6143c66143b9614485565b839063ffffffff61449116565b8161426957fe5b6000838513156143ef5760405162461bcd60e51b81526004016106e590615543565b6143ff838363ffffffff6133c616565b905061443c61442f61441c86600b5461427290919063ffffffff16565b600b54612a08908963ffffffff61427216565b829063ffffffff61347316565b60025490915061445390829063ffffffff61340c16565b9050610e6c61447861446b868863ffffffff6133c616565b849063ffffffff61368216565b829063ffffffff6123c516565b670de0b6b3a764000090565b6000808312156144b35760405162461bcd60e51b81526004016106e590615683565b600082136144d35760405162461bcd60e51b81526004016106e5906154d3565b81826144e96144e286866123c5565b60016133c6565b816144f057fe5b05029392505050565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805160c08101909152806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b80356123af81615821565b80516123af81615821565b80516123af81615835565b80356123af8161583e565b80516123af81615847565b80516123af8161583e565b600060c082840312156145e957600080fd5b6145f360c061578b565b9050600061460184846145c1565b8252506020614612848483016145cc565b6020830152506040614626848285016145cc565b604083015250606061463a848285016145cc565b606083015250608061464e848285016145cc565b60808301525060a0614662848285016145cc565b60a08301525092915050565b6000610100828403121561468157600080fd5b61468c61010061578b565b9050600061469a84846145cc565b82525060206146ab848483016145cc565b60208301525060406146bf848285016145cc565b60408301525060606146d3848285016145cc565b60608301525060806146e7848285016145cc565b60808301525060a06146fb848285016145cc565b60a08301525060c061470f848285016145cc565b60c08301525060e0614723848285016145cc565b60e08301525092915050565b60006020828403121561474157600080fd5b6000610e6f84846145a0565b6000806000806080858703121561476357600080fd5b600061476f8787614595565b9450506020614780878288016145b6565b9350506040614791878288016145b6565b92505060606147a2878288016145b6565b91505092959194509250565b6000602082840312156147c057600080fd5b6000610e6f84846145ab565b600080604083850312156147df57600080fd5b60006147eb85856145b6565b92505060206147fc858286016145b6565b9150509250929050565b60006020828403121561481857600080fd5b6000610e6f84846145c1565b60006020828403121561483657600080fd5b6000610e6f84846145cc565b600060c0828403121561485457600080fd5b6000610e6f84846145d7565b6000610100828403121561487357600080fd5b6000610e6f848461466e565b60006020828403121561489157600080fd5b6000610e6f84846145b6565b600080604083850312156148b057600080fd5b60006148bc85856145cc565b92505060206147fc858286016145cc565b6000806000606084860312156148e257600080fd5b60006148ee86866145b6565b93505060206148ff868287016145b6565b9250506040614910868287016145b6565b9150509250925092565b6000806000806080858703121561493057600080fd5b600061476f87876145b6565b614945816157e4565b82525050565b614945816157be565b614945816157eb565b614945816157f6565b614945816157bb565b600061497c600d836157b2565b6c1c1c9a58d9481b1a5b5a5d1959609a1b815260200192915050565b60006149a5600b836157b2565b6a189d5c9b8819985a5b195960aa1b815260200192915050565b60006149cc6014836157b2565b73616c7068612073686f756c64206265203c3d203160601b815260200192915050565b60006149fc600d836157b2565b6c77726f6e67206164647265737360981b815260200192915050565b6000614a25601e836157b2565b7f6e6f20736f6c7574696f6e2031206f6e2066756e64696e672063757276650000815260200192915050565b6000614a5e6013836157b2565b723ab730baba3437b934bd32b21031b0b63632b960691b815260200192915050565b6000614a8d600f836157b2565b6e06365696c206e656564206d203e203608c1b815260200192915050565b6000614ab8600d836157b2565b6c73656e64657220756e7361666560981b815260200192915050565b6000614ae16022836157b2565b7f6c6f6745206f6e6c7920616363657074732076203c3d2031653232202a203165815261062760f31b602082015260400192915050565b6000614b25600b836157b2565b6a6d6f64206279207a65726f60a81b815260200192915050565b6000614b4c6016836157b2565b7577726f6e672070657270657475616c2073746174757360501b815260200192915050565b6000614b7e6013836157b2565b72556e6164646974696f6e206f766572666c6f7760681b815260200192915050565b6000614bad6014836157b2565b73736861726542616c616e636520746f6f206c6f7760601b815260200192915050565b6000614bdd6012836157b2565b711a5b9d1959dc985d19481c995d995c9cd95960721b815260200192915050565b6000614c0b600b836157b2565b6a1b5a5b9d0819985a5b195960aa1b815260200192915050565b6000614c32600e836157b2565b6d706f6f6c206e6f7420656d70747960901b815260200192915050565b6000614c5c6017836157b2565b7f6c6f6745206f66206e65676174697665206e756d626572000000000000000000815260200192915050565b6000614c956013836157b2565b72185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b815260200192915050565b6000614cc46019836157b2565b7f556e6d756c7469706c69636174696f6e206f766572666c6f7700000000000000815260200192915050565b6000614cfd601f836157b2565b7f726f756e6448616c665570206f6e6c7920737570706f7274732079203e203000815260200192915050565b6000614d36601a836157b2565b7f77706f7769206f6e6c7920737570706f727473206e203e3d2030000000000000815260200192915050565b6000614d6f6011836157b2565b706164646974696f6e206f766572666c6f7760781b815260200192915050565b6000614d9c6011836157b2565b70776469766973696f6e206279207a65726f60781b815260200192915050565b6000614dc9601e836157b2565b7f6e6f20736f6c7574696f6e2033206f6e2066756e64696e672063757276650000815260200192915050565b6000614e026011836157b2565b70191958591b1a5b9948195e18d959591959607a1b815260200192915050565b6000614e2f602a836157b2565b7f616d6f756e74206d75737420626520646976697369626c652062792074726164815269696e674c6f7453697a6560b01b602082015260400192915050565b6000614e7b600a836157b2565b69616d6d20756e7361666560b01b815260200192915050565b6000614ea16020836157b2565b7f616d6f756e74206d7573742062652067726561746572207468616e207a65726f815260200192915050565b6000614eda6012836157b2565b71776469766973696f6e206f766572666c6f7760701b815260200192915050565b6000614f08601f836157b2565b7f74696d6520737465707320286e29206d75737420626520706f73697469766500815260200192915050565b6000614f41600a836157b2565b6964657620756e7361666560b01b815260200192915050565b6000614f67600a836157b2565b69195b5c1d1e481c1bdbdb60b21b815260200192915050565b6000614f8d6015836157b2565b7464616e6765726f757320696e64657820707269636560581b815260200192915050565b6000614fbe6010836157b2565b6f06365696c206e6565642078203e3d20360841b815260200192915050565b6000614fea6009836157b2565b68696d20756e7361666560b81b815260200192915050565b600061500f6013836157b2565b720616c7068612073686f756c64206265203e203606c1b815260200192915050565b600061503e601f836157b2565b7f66756e64696e6720696e697469616c697a6174696f6e20726571756972656400815260200192915050565b60006150776018836157b2565b7f776d756c7469706c69636174696f6e206f766572666c6f770000000000000000815260200192915050565b60006150b06010836157b2565b6f75696e74323536206f766572666c6f7760801b815260200192915050565b60006150dc600c836157b2565b6b696e74206f766572666c6f7760a01b815260200192915050565b60006151046018836157b2565b7f77652063616e277420676f206261636b20696e2074696d650000000000000000815260200192915050565b600061513d6014836157b2565b737375627472616374696f6e206f766572666c6f7760601b815260200192915050565b600061516d600e836157b2565b6d6b6579206e6f742065786973747360901b815260200192915050565b60006151976016836157b2565b75556e7375627472616374696f6e206f766572666c6f7760501b815260200192915050565b60006151c96009836157b2565b683737ba1037bbb732b960b91b815260200192915050565b60006151ee601e836157b2565b7f6e6f20736f6c7574696f6e2032206f6e2066756e64696e672063757276650000815260200192915050565b805160c083019061522b8482614966565b50602082015161523e6020850182614966565b5060408201516152516040850182614966565b5060608201516152646060850182614966565b5060808201516152776080850182614966565b5060a08201516116b760a0850182614966565b805160a083019061529b8482614966565b5060208201516152ae6020850182614966565b5060408201516152c16040850182614966565b5060608201516152d46060850182614966565b5060808201516116b76080850182614966565b805460a08301906152f781615801565b6153018582614966565b5050600182015461531181615801565b61531e6020860182614966565b5050600282015461532e81615801565b61533b6040860182614966565b5050600382015461534b81615801565b6153586060860182614966565b5050600482015461536881615801565b610daa6080860182614966565b602081016123af828461494b565b602081016123af828461493c565b6040810161539f828561494b565b6107956020830184614966565b6040810161539f828561493c565b606081016153c8828661494b565b6153d5602083018561493c565b610e6f6040830184614966565b60a081016153f0828861494b565b6153fd602083018761494b565b61540a604083018661495d565b6154176060830185614966565b6154246080830184614966565b9695505050505050565b6060810161543c828661494b565b6153d5602083018561494b565b602081016123af8284614954565b602081016123af828461495d565b602081016123af8284614966565b602080825281016123af8161496f565b602080825281016123af81614998565b602080825281016123af816149bf565b602080825281016123af816149ef565b602080825281016123af81614a18565b602080825281016123af81614a51565b602080825281016123af81614a80565b602080825281016123af81614aab565b602080825281016123af81614ad4565b602080825281016123af81614b18565b602080825281016123af81614b3f565b602080825281016123af81614b71565b602080825281016123af81614ba0565b602080825281016123af81614bd0565b602080825281016123af81614bfe565b602080825281016123af81614c25565b602080825281016123af81614c4f565b602080825281016123af81614c88565b602080825281016123af81614cb7565b602080825281016123af81614cf0565b602080825281016123af81614d29565b602080825281016123af81614d62565b602080825281016123af81614d8f565b602080825281016123af81614dbc565b602080825281016123af81614df5565b602080825281016123af81614e22565b602080825281016123af81614e6e565b602080825281016123af81614e94565b602080825281016123af81614ecd565b602080825281016123af81614efb565b602080825281016123af81614f34565b602080825281016123af81614f5a565b602080825281016123af81614f80565b602080825281016123af81614fb1565b602080825281016123af81614fdd565b602080825281016123af81615002565b602080825281016123af81615031565b602080825281016123af8161506a565b602080825281016123af816150a3565b602080825281016123af816150cf565b602080825281016123af816150f7565b602080825281016123af81615130565b602080825281016123af81615160565b602080825281016123af8161518a565b602080825281016123af816151bc565b602080825281016123af816151e1565b60c081016123af828461521a565b60a081016123af828461528a565b60a081016123af82846152e7565b6040810161539f8285614966565b60405181810167ffffffffffffffff811182821017156157aa57600080fd5b604052919050565b90815260200190565b90565b60006123af826157d8565b151590565b80612a6081615814565b6001600160a01b031690565b60006123af825b60006123af826157be565b60006123af826157ce565b60006123af61580f836157bb565b6157bb565b6003811061581e57fe5b50565b61582a816157be565b811461581e57600080fd5b61582a816157c9565b61582a816157bb565b6003811061581e57600080fdfea365627a7a72315820afea0d0400ac60b2c919243edd9ad1a4c662c5e60924ae327140ed3d7dd3891e6c6578706572696d656e74616cf564736f6c634300050f004000000000000000000000000071e77ffbbfd4418ed47981927738b5425c187f6400000000000000000000000005c363d2b9afc36b070fe2c61711280edc2146780000000000000000000000009b2d7d7f7b2810ef2be979fc2acebe6097d9563a000000000000000000000000ae694fb9dcd1e6195519c0056b2ab19380b26ff2

Deployed Bytecode

0x6080604052600436106101f85760003560e01c8063831190731161010d578063a8681826116100a0578063d3c9727c1161006f578063d3c9727c1461050a578063de12bcac1461052a578063dedcd0741461053f578063e21ebac914610561578063f3ffd28a14610574576101f8565b8063a8681826146104ad578063b6a20fc1146104c2578063b8f110bc146104e2578063b9f412b0146104f5576101f8565b8063a3bad878116100dc578063a3bad87814610438578063a7a7227e14610458578063a7c1abe014610478578063a812e9ac1461048d576101f8565b806383119073146103d957806384f523ad146103ee57806395af65dd146104035780639c8f9f2314610418576101f8565b80633e99a53b1161019057806353de38141161015f57806353de38141461035a57806355ddeabe1461036f5780636dcd09d71461038457806373da22bf146103a45780638259e6a0146103b9576101f8565b80633e99a53b146102f057806340993b26146103055780634928229a1461032557806351c6590a1461033a576101f8565b8063289b3c0d116101cc578063289b3c0d1461028257806330e04ca1146102a45780633aef4d0b146102c65780633b495ebf146102db576101f8565b80624f69b0146101fd57806306a7570c1461021257806310bace8c1461023d5780631fada48514610260575b600080fd5b61021061020b3660046147cc565b610589565b005b34801561021e57600080fd5b50610227610609565b6040516102349190615761565b60405180910390f35b34801561024957600080fd5b50610252610646565b60405161023492919061577d565b34801561026c57600080fd5b506102756106f2565b6040516102349190615449565b34801561028e57600080fd5b50610297610701565b6040516102349190615753565b3480156102b057600080fd5b506102b9610746565b6040516102349190615465565b3480156102d257600080fd5b506102b961075d565b3480156102e757600080fd5b506102b961076f565b3480156102fc57600080fd5b50610275610775565b34801561031157600080fd5b506102b96103203660046148cd565b610784565b34801561033157600080fd5b506102b961079c565b34801561034657600080fd5b5061021061035536600461487f565b6107eb565b34801561036657600080fd5b50610210610ad0565b34801561037b57600080fd5b506102b9610db1565b34801561039057600080fd5b506102b961039f36600461474d565b610dc3565b3480156103b057600080fd5b506102b9610e77565b3480156103c557600080fd5b506102106103d436600461487f565b610e7d565b3480156103e557600080fd5b506102b96110c7565b3480156103fa57600080fd5b506102b96110d9565b34801561040f57600080fd5b506102b9611169565b34801561042457600080fd5b5061021061043336600461487f565b61117a565b34801561044457600080fd5b506102b961045336600461474d565b611595565b34801561046457600080fd5b5061021061047336600461491a565b61163e565b34801561048457600080fd5b506102756116bd565b34801561049957600080fd5b506102106104a83660046147cc565b6116cc565b3480156104b957600080fd5b506102b9611a3e565b3480156104ce57600080fd5b506102106104dd36600461491a565b611a50565b6102106104f036600461491a565b611a61565b34801561050157600080fd5b50610210611adf565b34801561051657600080fd5b506102b96105253660046148cd565b611d1d565b34801561053657600080fd5b506102b9611d2b565b34801561054b57600080fd5b50610554611d3d565b6040516102349190615375565b61021061056f36600461491a565b611d4c565b34801561058057600080fd5b50610227611dca565b81156105f657600d546040516317a790f160e11b81526001600160a01b0390911690632f4f21e29034906105c390339087906004016153ac565b6000604051808303818588803b1580156105dc57600080fd5b505af11580156105f0573d6000803e3d6000fd5b50505050505b801561060557610605816107eb565b5050565b6106116144f9565b506040805160a08101825260065481526007546020820152600854918101919091526009546060820152600a54608082015290565b600e546040805163501ad8ff60e11b8152815160009384936001600160a01b039091169263a035b1fe9260048083019392829003018186803b15801561068b57600080fd5b505afa15801561069f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106c3919081019061489d565b9092509050816106ee5760405162461bcd60e51b81526004016106e590615673565b60405180910390fd5b9091565b600e546001600160a01b031681565b610709614528565b506040805160c08101825260005481526001546020820152600254918101919091526003546060820152600454608082015260055460a082015290565b6000610750611dd6565b610758611eb9565b905090565b6000610767611dd6565b61075861079c565b600b5481565b600d546001600160a01b031681565b600061079233858585611f52565b90505b9392505050565b6000806107a761234c565b6005549091506107e5906107c590839060000363ffffffff61239a16565b6005546107d990849063ffffffff6123b516565b9063ffffffff6123c516565b91505090565b600d5460408051631006976960e11b815290516000926001600160a01b03169163200d2ed2916004808301926020929190829003018186803b15801561083057600080fd5b505afa158015610844573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108689190810190614806565b600281111561087357fe5b146108905760405162461bcd60e51b81526004016106e590615513565b60008061089b61240b565b909250905080158015906108ae57508115155b6108ca5760405162461bcd60e51b81526004016106e590615663565b3360006108dd848463ffffffff6124bb16565b9050600061090260026108f6888563ffffffff6124ec16565b9063ffffffff61251416565b600d549091506001600160a01b0316639272c80e8461091f61254e565b846040518463ffffffff1660e01b815260040161093e9392919061542e565b600060405180830381600087803b15801561095857600080fd5b505af115801561096c573d6000803e3d6000fd5b5050600d54600092506001600160a01b031690506319d3b88b8561098e61254e565b6001878c6040518663ffffffff1660e01b81526004016109b29594939291906153e2565b6040805180830381600087803b1580156109cb57600080fd5b505af11580156109df573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a03919081019061489d565b509050610ab584610ab087610aa48b601060009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a6057600080fd5b505afa158015610a74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a989190810190614824565b9063ffffffff6124ec16565b9063ffffffff6124bb16565b61255d565b610abd6125fd565b610ac784826126c9565b50505050505050565b600d5460408051631006976960e11b815290516002926001600160a01b03169163200d2ed2916004808301926020929190829003018186803b158015610b1557600080fd5b505afa158015610b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b4d9190810190614806565b6002811115610b5857fe5b14610b755760405162461bcd60e51b81526004016106e590615513565b33610b7e61455e565b600d546001600160a01b0316622bc164610b9661254e565b6040518263ffffffff1660e01b8152600401610bb29190615375565b60c06040518083038186803b158015610bca57600080fd5b505afa158015610bde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c029190810190614842565b90506000610c0f82612934565b6010546040516370a0823160e01b81529192506000916001600160a01b03909116906370a0823190610c45908790600401615375565b60206040518083038186803b158015610c5d57600080fd5b505afa158015610c71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c959190810190614824565b90506000610d32601060009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cea57600080fd5b505afa158015610cfe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d229190810190614824565b610aa4848663ffffffff6124ec16565b600d549091506001600160a01b0316639272c80e610d4e61254e565b87846040518463ffffffff1660e01b8152600401610d6e9392919061542e565b600060405180830381600087803b158015610d8857600080fd5b505af1158015610d9c573d6000803e3d6000fd5b50505050610daa8583612a65565b5050505050565b6000610dbb611dd6565b61075861234c565b600f5460405163df5e9b2960e01b81526000916001600160a01b03169063df5e9b2990610df4903390600401615383565b60206040518083038186803b158015610e0c57600080fd5b505afa158015610e20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e4491908101906147ae565b610e605760405162461bcd60e51b81526004016106e5906154c3565b610e6c85858585612b05565b90505b949350505050565b600c5481565b60008111610e9d5760405162461bcd60e51b81526004016106e590615623565b600d5460408051631006976960e11b815290516000926001600160a01b03169163200d2ed2916004808301926020929190829003018186803b158015610ee257600080fd5b505afa158015610ef6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f1a9190810190614806565b6002811115610f2557fe5b14610f425760405162461bcd60e51b81526004016106e590615513565b610f4a6110d9565b15610f675760405162461bcd60e51b81526004016106e590615563565b336000610f72612ce7565b9050600080610f7f610646565b9092509050610f8e8284612ceb565b600d546001600160a01b0316639272c80e85610fa861254e565b610fbd60026108f6888c63ffffffff6124ec16565b6040518463ffffffff1660e01b8152600401610fdb9392919061542e565b600060405180830381600087803b158015610ff557600080fd5b505af1158015611009573d6000803e3d6000fd5b5050600d54600092506001600160a01b031690506319d3b88b8661102b61254e565b6001878b6040518663ffffffff1660e01b815260040161104f9594939291906153e2565b6040805180830381600087803b15801561106857600080fd5b505af115801561107c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110a0919081019061489d565b5090506110ad858761255d565b6110b56125fd565b6110bf85826126c9565b505050505050565b60006110d1611dd6565b610758612d1d565b600d546000906001600160a01b0316622bc1646110f461254e565b6040518263ffffffff1660e01b81526004016111109190615375565b60c06040518083038186803b15801561112857600080fd5b505afa15801561113c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111609190810190614842565b60200151905090565b6000611173611dd6565b50600a5490565b600d5460408051631006976960e11b815290516000926001600160a01b03169163200d2ed2916004808301926020929190829003018186803b1580156111bf57600080fd5b505afa1580156111d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111f79190810190614806565b600281111561120257fe5b1461121f5760405162461bcd60e51b81526004016106e590615513565b3360008061122b61240b565b9092509050801580159061123e57508115155b61125a5760405162461bcd60e51b81526004016106e590615663565b6010546040516370a0823160e01b815285916001600160a01b0316906370a082319061128a903390600401615383565b60206040518083038186803b1580156112a257600080fd5b505afa1580156112b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112da9190810190614824565b10156112f85760405162461bcd60e51b81526004016106e590615533565b600061130a838363ffffffff6124bb16565b905060006113a7601060009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561135f57600080fd5b505afa158015611373573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113979190810190614824565b610aa4888663ffffffff6124ec16565b90506000600d60009054906101000a90046001600160a01b03166001600160a01b031663289b3c0d6040518163ffffffff1660e01b81526004016101006040518083038186803b1580156113fa57600080fd5b505afa15801561140e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506114329190810190614860565b60c00151905061145861144b838363ffffffff612db616565b839063ffffffff612de616565b600d549092506001600160a01b0316639272c80e61147461254e565b8861148a60026108f6898963ffffffff6124ec16565b6040518463ffffffff1660e01b81526004016114a89392919061542e565b600060405180830381600087803b1580156114c257600080fd5b505af11580156114d6573d6000803e3d6000fd5b505050506114e48688612a65565b600d546000906001600160a01b03166319d3b88b8861150161254e565b600288886040518663ffffffff1660e01b81526004016115259594939291906153e2565b6040805180830381600087803b15801561153e57600080fd5b505af1158015611552573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611576919081019061489d565b5090506115816125fd565b61158b87826126c9565b5050505050505050565b600f5460405163df5e9b2960e01b81526000916001600160a01b03169063df5e9b29906115c6903390600401615383565b60206040518083038186803b1580156115de57600080fd5b505afa1580156115f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061161691908101906147ae565b6116325760405162461bcd60e51b81526004016106e5906154c3565b610e6c85858585611f52565b83156116515761164f848484610784565b505b80156116b757600d54604051636da8c6d960e11b81526001600160a01b039091169063db518db2906116899033908590600401615391565b600060405180830381600087803b1580156116a357600080fd5b505af115801561158b573d6000803e3d6000fd5b50505050565b600f546001600160a01b031681565b600f5460408051638da5cb5b60e01b8152905133926001600160a01b031691638da5cb5b916004808301926020929190829003018186803b15801561171057600080fd5b505afa158015611724573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611748919081019061472f565b6001600160a01b03161461176e5760405162461bcd60e51b81526004016106e590615733565b816a706f6f6c4665655261746560a81b14156117955761178d81612e0e565b600055611a02565b816d706f6f6c4465764665655261746560901b14156117bf576117b781612e0e565b600155611a02565b8167656d61416c70686160c01b141561184157600081136117f25760405162461bcd60e51b81526004016106e5906156a3565b670de0b6b3a764000081131561181a5760405162461bcd60e51b81526004016106e590615493565b6002819055670de0b6b3a7640000819003600b81905561183990612e34565b600c55611a02565b81717570646174655072656d69756d5072697a6560701b141561186f5761186781612e0e565b600355611a02565b816f1b585c9ad41c995b5a5d5b531a5b5a5d60821b1415611894576004819055611a02565b816e333ab73234b733a230b6b832b732b960891b14156118b8576005819055611a02565b817f616363756d756c6174656446756e64696e67506572436f6e7472616374000000141561198f57600d5460408051631006976960e11b815290516001926001600160a01b03169163200d2ed2916004808301926020929190829003018186803b15801561192557600080fd5b505afa158015611939573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061195d9190810190614806565b600281111561196857fe5b146119855760405162461bcd60e51b81526004016106e590615513565b600a819055611a02565b816a383934b1b2a332b2b232b960a91b14156119ea576119ae816130bb565b6119ca5760405162461bcd60e51b81526004016106e5906154a3565b600e80546001600160a01b0319166001600160a01b038316179055611a02565b60405162461bcd60e51b81526004016106e590615713565b817fc3d18999fb01e35e747dd6b7658ba5c080fd98900f063b48d25d7af86f55214882604051611a329190615465565b60405180910390a25050565b6000611a48611dd6565b6107586130f4565b83156116515761164f848484611d1d565b8315611ace57600d546040516317a790f160e11b81526001600160a01b0390911690632f4f21e2903490611a9b90339089906004016153ac565b6000604051808303818588803b158015611ab457600080fd5b505af1158015611ac8573d6000803e3d6000fd5b50505050505b82156116b757610daa838383610784565b600d5460408051631006976960e11b815290516000926001600160a01b03169163200d2ed2916004808301926020929190829003018186803b158015611b2457600080fd5b505afa158015611b38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611b5c9190810190614806565b6002811115611b6757fe5b14611b845760405162461bcd60e51b81526004016106e590615513565b600954611b8f6125fd565b600d5460408051631d68877b60e11b815290516000926001600160a01b031691633ad10ef6916004808301926020929190829003018186803b158015611bd457600080fd5b505afa158015611be8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c0c919081019061472f565b600954909150821461060557600d54600354604051634939640760e11b81526001600160a01b0390921691639272c80e91611c4d91859133916004016153ba565b600060405180830381600087803b158015611c6757600080fd5b505af1158015611c7b573d6000803e3d6000fd5b5050600d54604051631da68a2b60e21b81526001600160a01b03909116925063769a28ac9150611caf908490600401615375565b602060405180830381600087803b158015611cc957600080fd5b505af1158015611cdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611d0191908101906147ae565b6106055760405162461bcd60e51b81526004016106e590615653565b600061079233858585612b05565b6000611d35611dd6565b61075861318d565b6010546001600160a01b031690565b8315611db957600d546040516317a790f160e11b81526001600160a01b0390911690632f4f21e2903490611d8690339089906004016153ac565b6000604051808303818588803b158015611d9f57600080fd5b505af1158015611db3573d6000803e3d6000fd5b50505050505b82156116b757610daa838383611d1d565b611dd26144f9565b6106115b600d5460408051631006976960e11b815290516000926001600160a01b03169163200d2ed2916004808301926020929190829003018186803b158015611e1b57600080fd5b505afa158015611e2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e539190810190614806565b6002811115611e5e57fe5b14611e6857611eb7565b6000611e72612ce7565b9050600080611e7f610646565b600654919350915083141580611e9757506009548214155b80611ea3575060065481115b15611eb357611eb3838383613236565b5050505b565b6000611ec361455e565b600d546001600160a01b0316622bc164611edb61254e565b6040518263ffffffff1660e01b8152600401611ef79190615375565b60c06040518083038186803b158015611f0f57600080fd5b505afa158015611f23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611f479190810190614842565b90506107e581612934565b600080600d60009054906101000a90046001600160a01b03166001600160a01b031663200d2ed26040518163ffffffff1660e01b815260040160206040518083038186803b158015611fa357600080fd5b505afa158015611fb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611fdb9190810190614806565b6002811115611fe657fe5b146120035760405162461bcd60e51b81526004016106e590615513565b600d546040516336a250cf60e21b81526001600160a01b039091169063da89433c90612033908790600401615465565b60206040518083038186803b15801561204b57600080fd5b505afa15801561205f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061208391908101906147ae565b61209f5760405162461bcd60e51b81526004016106e590615603565b60006120aa85613341565b9050808410156120cc5760405162461bcd60e51b81526004016106e590615473565b826120d5612ce7565b11156120f35760405162461bcd60e51b81526004016106e5906155f3565b600d546000906001600160a01b03166319d3b88b8861211061254e565b6002868b6040518663ffffffff1660e01b81526004016121349594939291906153e2565b6040805180830381600087803b15801561214d57600080fd5b505af1158015612161573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612185919081019061489d565b509050600061219a838863ffffffff6124ec16565b60008054919250906121b390839063ffffffff6124ec16565b6001549091506000906121cd90849063ffffffff6124ec16565b90506000600d60009054906101000a90046001600160a01b03166001600160a01b0316633ad10ef66040518163ffffffff1660e01b815260040160206040518083038186803b15801561221f57600080fd5b505afa158015612233573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612257919081019061472f565b600d549091506001600160a01b0316639272c80e8c61227461254e565b866040518463ffffffff1660e01b81526004016122939392919061542e565b600060405180830381600087803b1580156122ad57600080fd5b505af11580156122c1573d6000803e3d6000fd5b5050600d54604051634939640760e11b81526001600160a01b039091169250639272c80e91506122f9908e908590879060040161542e565b600060405180830381600087803b15801561231357600080fd5b505af1158015612327573d6000803e3d6000fd5b505050506123336125fd565b61233d8b866126c9565b50929998505050505050505050565b60008061235d60066003015461339d565b9050600061237161236c61318d565b61339d565b905061239382612387838263ffffffff6133c616565b9063ffffffff61340c16565b9250505090565b6000818313156123aa57816123ac565b825b90505b92915050565b6000818312156123aa57816123ac565b60008282018183128015906123da5750838112155b806123ef57506000831280156123ef57508381125b6123ac5760405162461bcd60e51b81526004016106e5906155c3565b600080612416611dd6565b61241e61455e565b600d546001600160a01b0316622bc16461243661254e565b6040518263ffffffff1660e01b81526004016124529190615375565b60c06040518083038186803b15801561246a57600080fd5b505afa15801561247e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506124a29190810190614842565b90506124ad81612934565b925080602001519150509091565b6000816124dd6124d385670de0b6b3a7640000612514565b6002855b0461344e565b816124e457fe5b049392505050565b6000670de0b6b3a76400006124dd6125048585612514565b6002670de0b6b3a76400006124d7565b600082612523575060006123af565b8282028284828161253057fe5b04146123ac5760405162461bcd60e51b81526004016106e590615593565b600d546001600160a01b031690565b6010546040516340c10f1960e01b81526001600160a01b03909116906340c10f199061258f9085908590600401615391565b602060405180830381600087803b1580156125a957600080fd5b505af11580156125bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506125e191908101906147ae565b6106055760405162461bcd60e51b81526004016106e590615553565b600d5460408051631006976960e11b815290516000926001600160a01b03169163200d2ed2916004808301926020929190829003018186803b15801561264257600080fd5b505afa158015612656573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061267a9190810190614806565b600281111561268557fe5b146126a25760405162461bcd60e51b81526004016106e590615513565b60006126ac612ce7565b90506000806126b9610646565b9092509050611eb3838383613236565b600d54604080516345a15a0160e01b815290516000926001600160a01b0316916345a15a0191600480830192602092919082900301818787803b15801561270f57600080fd5b505af1158015612723573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506127479190810190614824565b905081156127ef57600d5460405163f50c138b60e01b81526001600160a01b039091169063f50c138b906127819086908590600401615391565b602060405180830381600087803b15801561279b57600080fd5b505af11580156127af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506127d391908101906147ae565b6127ef5760405162461bcd60e51b81526004016106e590615693565b600d54604051631eacda4160e31b81526001600160a01b039091169063f566d208906128219086908590600401615391565b602060405180830381600087803b15801561283b57600080fd5b505af115801561284f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061287391908101906147ae565b61288f5760405162461bcd60e51b81526004016106e5906154e3565b600d546001600160a01b031663f566d2086128a861254e565b836040518363ffffffff1660e01b81526004016128c6929190615391565b602060405180830381600087803b1580156128e057600080fd5b505af11580156128f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061291891908101906147ae565b611eb35760405162461bcd60e51b81526004016106e590615613565b60a0810151600d5482516040516324c374e760e21b81526000939284926001600160a01b039091169163930dd39c9161296f91600401615457565b60206040518083038186803b15801561298757600080fd5b505afa15801561299b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506129bf9190810190614824565b90506129de6129d1856040015161339d565b839063ffffffff6133c616565b9150612a146129d18560600151612a086129fb886020015161339d565b859063ffffffff61347316565b9063ffffffff6133c616565b9150612a406129d18560800151612a08612a31886020015161339d565b600a549063ffffffff61347316565b9150612a5b612a5683600063ffffffff6123b516565b612e0e565b925050505b919050565b601054604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90612a979085908590600401615391565b602060405180830381600087803b158015612ab157600080fd5b505af1158015612ac5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612ae991908101906147ae565b6106055760405162461bcd60e51b81526004016106e590615483565b600080600d60009054906101000a90046001600160a01b03166001600160a01b031663200d2ed26040518163ffffffff1660e01b815260040160206040518083038186803b158015612b5657600080fd5b505afa158015612b6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612b8e9190810190614806565b6002811115612b9957fe5b14612bb65760405162461bcd60e51b81526004016106e590615513565b600d546040516336a250cf60e21b81526001600160a01b039091169063da89433c90612be6908790600401615465565b60206040518083038186803b158015612bfe57600080fd5b505afa158015612c12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612c3691908101906147ae565b612c525760405162461bcd60e51b81526004016106e590615603565b6000612c5d85613499565b905080841115612c7f5760405162461bcd60e51b81526004016106e590615473565b82612c88612ce7565b1115612ca65760405162461bcd60e51b81526004016106e5906155f3565b600d546000906001600160a01b03166319d3b88b88612cc361254e565b6001868b6040518663ffffffff1660e01b81526004016121349594939291906153e2565b4290565b60065415612d0b5760405162461bcd60e51b81526004016106e590615583565b60065560095560006007819055600855565b6000612d2761455e565b600d546001600160a01b0316622bc164612d3f61254e565b6040518263ffffffff1660e01b8152600401612d5b9190615375565b60c06040518083038186803b158015612d7357600080fd5b505afa158015612d87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612dab9190810190614842565b90506107e5816134e8565b600081612dd55760405162461bcd60e51b81526004016106e590615503565b818381612dde57fe5b069392505050565b600082821115612e085760405162461bcd60e51b81526004016106e590615723565b50900390565b600080821215612e305760405162461bcd60e51b81526004016106e5906156e3565b5090565b6000808213612e555760405162461bcd60e51b81526004016106e590615573565b701d6329f1c35ca4bfabb9f5610000000000821315612e865760405162461bcd60e51b81526004016106e5906154f3565b60006012670de0b6b3a76400005b67016345785d8a00008513612ec35784600a0294506f01bb7635c5de48ef4ce5b7b41cc43db083039250612e94565b678ac7230489e800008512612ef257600a850594506f01bb7635c5de48ef4ce5b7b41cc43db083019250612ec3565b670de0b6b3a7640000851215612f2f57612f14856725b946ebc0b36173613473565b94506ec097ce7bc90715b34b9f100000000083039250612ef2565b6725b946ebc0b36173851315612f6c57612f51856725b946ebc0b3617361340c565b94506ec097ce7bc90715b34b9f100000000083019250612f2f565b670de0b6b3a7640000851415612f995780612f878483613517565b81612f8e57fe5b059350505050612a60565b6725b946ebc0b36173851415612fd05780612fb48483613517565b81612fbb57fe5b05670de0b6b3a7640000019350505050612a60565b938402936e4e16f927cdca7f15b39123f740f5d192909201916f0120e3b5b9ad8aa08cf16e980000000060008187016ec097ce7bc90715b34b9f10000000006f0120e3b5b9ad8aa08cf16e97ffffffff198901028161302b57fe5b059050806002028501945060006ec097ce7bc90715b34b9f10000000008283028161305257fe5b05905060035b6ec097ce7bc90715b34b9f10000000008383020592508060ff16836002028161307d57fe5b059690960195600201602760ff8216106130965761309b565b613058565b846130a68887613517565b816130ad57fe5b059998505050505050505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612a5b575050151592915050565b60006130fe61455e565b600d546001600160a01b0316622bc16461311661254e565b6040518263ffffffff1660e01b81526004016131329190615375565b60c06040518083038186803b15801561314a57600080fd5b505afa15801561315e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506131829190810190614842565b90506107e581613561565b60008061319e60066003015461339d565b6004549091506000906131b890839063ffffffff61347316565b905060006131d46131c76135a3565b849063ffffffff6123c516565b90506131f66131e9848463ffffffff6123c516565b829063ffffffff61239a16565b905061321861320b848463ffffffff6133c616565b829063ffffffff6123b516565b905061322e612a5682600063ffffffff6123b516565b935050505090565b60065461324257611eb3565b61324a61455e565b600d546001600160a01b0316622bc16461326261254e565b6040518263ffffffff1660e01b815260040161327e9190615375565b60c06040518083038186803b15801561329657600080fd5b505afa1580156132aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506132ce9190810190614842565b90508060200151600014156132e35750611eb3565b6006548211156132f8576132f88184846135a9565b6133038184866135a9565b7fc0f950314c1203122896795efe729e8208b4c58eb5d6f41c476f32c773250a5d6006604051613333919061576f565b60405180910390a150505050565b600080600061334e61240b565b9092509050801580159061336157508115155b61337d5760405162461bcd60e51b81526004016106e590615663565b612a5b613390828663ffffffff612de616565b839063ffffffff6124bb16565b60006001600160ff1b03821115612e305760405162461bcd60e51b81526004016106e5906156d3565b60008183038183128015906133db5750838113155b806133f057506000831280156133f057508381135b6123ac5760405162461bcd60e51b81526004016106e590615703565b600080821215613423578160000391508260000392505b8161343f61343985670de0b6b3a7640000613682565b84613517565b8161344657fe5b059392505050565b6000828201838110156123ac5760405162461bcd60e51b81526004016106e590615523565b6000670de0b6b3a764000061343f61348b8585613682565b670de0b6b3a7640000613517565b60008060006134a661240b565b909250905080158015906134b957508115155b6134d55760405162461bcd60e51b81526004016106e590615663565b612a5b613390828663ffffffff61344e16565b6000806134f761236c84613561565b905061079561350a60066003015461339d565b829063ffffffff6133c616565b60008082136135385760405162461bcd60e51b81526004016106e5906155a3565b600083126135545761354d83600284056123c5565b90506123af565b6123ac83600284056133c6565b6020810151600090806135865760405162461bcd60e51b81526004016106e5906156b3565b600061359184612934565b9050612a5b818363ffffffff6124bb16565b60085490565b6006546135c85760405162461bcd60e51b81526004016106e5906156b3565b6006548110156135ea5760405162461bcd60e51b81526004016106e590615643565b600654811461366c5760065460009061360e9061236c90849063ffffffff612de616565b905060006136358260066002015460066001015461363060066003015461339d565b6136ed565b60089190915590506136616136528261708063ffffffff61420e16565b600a549063ffffffff6123c516565b600a55505060068190555b600982905561367a836134e8565b600755505050565b600082613691575060006123af565b826000191480156136a55750600160ff1b82145b156136c25760405162461bcd60e51b81526004016106e5906156c3565b828202828482816136cf57fe5b05146123ac5760405162461bcd60e51b81526004016106e5906156c3565b600080600086136137105760405162461bcd60e51b81526004016106e5906156f3565b613718614528565b613728868663ffffffff6133c616565b925061374f61374288600b5461427290919063ffffffff16565b849063ffffffff61347316565b9250613761838663ffffffff6123c516565b600454909350613777908563ffffffff61347316565b815260055461378c908563ffffffff61347316565b602082015280516000038613613ab157805160000383136137dc576137d5876137c9836020015184600001516000036123c590919063ffffffff16565b9063ffffffff61368216565b9150613aac565b806020015160000383136138575780516137fa9060000387876142e8565b604082018190528151613819916000919091039063ffffffff61368216565b915061383b61382e82604001518989896143cd565b839063ffffffff6123c516565b91506137d561382e88836020015161368290919063ffffffff16565b806020015183136138e55780516138729060000387876142e8565b6040820152602081015161388a9060000387876142e8565b6060820152604081015181516138ac916000919091039063ffffffff61368216565b91506138c561382e8260400151836060015189896143cd565b91506137d561382e8260600151836020015161368290919063ffffffff16565b805183136139b25780516138fd9060000387876142e8565b604082015260208101516139159060000387876142e8565b6060820152602081015161392a9087876142e8565b60808201526040810151815161394c916000919091039063ffffffff61368216565b915061396561382e8260400151836060015189896143cd565b915061397a61382e82608001518989896143cd565b91506137d561382e6139a183608001516107d98b86606001516133c690919063ffffffff16565b60208401519063ffffffff61368216565b80516139c29060000387876142e8565b604082015260208101516139da9060000387876142e8565b606082015260208101516139ef9087876142e8565b60808201528051613a019087876142e8565b60a082015260408101518151613a23916000919091039063ffffffff61368216565b9150613a3c61382e8260400151836060015189896143cd565b9150613a5561382e82608001518360a0015189896143cd565b9150613a8261382e613a748360a001518a6133c690919063ffffffff16565b83519063ffffffff61368216565b9150613aa961382e6139a183608001516107d98b86606001516133c690919063ffffffff16565b91505b614204565b80602001516000038613613c045780516000038313613b1f578051613ada9060000387876142e8565b60a08201819052613aef9060009088886143cd565b915061383b61382e613b0e8360a001518a6133c690919063ffffffff16565b83516000039063ffffffff61368216565b80602001516000038313613b3a5761383b60008888886143cd565b80602001518313613b6c57613b57816020015160000387876142e8565b606082018190526138c59060009088886143cd565b80518313613bb357613b86816020015160000387876142e8565b60608201526020810151613b9b9087876142e8565b608082015260608101516139659060009088886143cd565b613bc5816020015160000387876142e8565b60608201526020810151613bda9087876142e8565b60808201528051613bec9087876142e8565b60a08201526060810151613a3c9060009088886143cd565b80602001518613613d9c5780516000038313613c9657613c2c816020015160000387876142e8565b60808201528051613c419060000387876142e8565b60a082018190526080820151613c589188886143cd565b9150613c7761382e613b0e8360a001518a6133c690919063ffffffff16565b91506137d561382e6139a183608001518a6133c690919063ffffffff16565b80602001516000038313613cc957613cb6816020015160000387876142e8565b60808201819052613c77908888886143cd565b80602001518313613cdd5760009150613aac565b80518313613d2657613cf4816020015187876142e8565b60808201819052613d07908888886143cd565b91506137d56129d16139a183608001518a6133c690919063ffffffff16565b613d35816020015187876142e8565b60808201528051613d479087876142e8565b60a082018190526080820151613d5e9188886143cd565b9150613d7d61382e613a748360a001518a6133c690919063ffffffff16565b9150613aa96129d16139a183608001518a6133c690919063ffffffff16565b80518613613fa15780516000038313613e6257613dbe816020015187876142e8565b60608201526020810151613dd69060000387876142e8565b60808201528051613deb9060000387876142e8565b60a08201526060810151613e039060009088886143cd565b9150613e1c61382e82608001518360a0015189896143cd565b9150613e3b61382e613b0e8360a001518a6133c690919063ffffffff16565b91506137d561382e6139a18360600151612a0885608001518c6133c690919063ffffffff16565b80602001516000038313613ec457613e7f816020015187876142e8565b60608201526020810151613e979060000387876142e8565b60808201526060810151613eaf9060009088886143cd565b9150613e3b61382e82608001518989896143cd565b80602001518313613f1357613ede816020015187876142e8565b60608201819052613ef39060009088886143cd565b91506137d56129d18260600151836020015161368290919063ffffffff16565b80518313613f4457613f2860008888886143cd565b91506137d56129d188836020015161368290919063ffffffff16565b8051613f519087876142e8565b60a08201819052613f669060009088886143cd565b9150613f8561382e613a748360a001518a6133c690919063ffffffff16565b9150613aa96129d188836020015161368290919063ffffffff16565b8051600003831361408e578051613fb99087876142e8565b60408201526020810151613fce9087876142e8565b60608201526020810151613fe69060000387876142e8565b60808201528051613ffb9060000387876142e8565b60a0820152604081015181516140169163ffffffff61368216565b915061402f61382e8260400151836060015189896143cd565b915061404861382e82608001518360a0015189896143cd565b915061406761382e613b0e8360a001518a6133c690919063ffffffff16565b9150613aa961382e6139a18360600151612a0885608001518c6133c690919063ffffffff16565b8060200151600003831361411f5780516140a99087876142e8565b604082015260208101516140be9087876142e8565b606082015260208101516140d69060000387876142e8565b6080820152604081015181516140f19163ffffffff61368216565b915061410a61382e8260400151836060015189896143cd565b915061406761382e82608001518989896143cd565b806020015183136141a35780516141379087876142e8565b6040820152602081015161414c9087876142e8565b6060820152604081015181516141679163ffffffff61368216565b915061418061382e8260400151836060015189896143cd565b9150613aa961382e8260600151600003836020015161368290919063ffffffff16565b805183136141e55780516141b89087876142e8565b6040820181905281516141d09163ffffffff61368216565b9150613f8561382e82604001518989896143cd565b602081015181516142019189916137c99163ffffffff6133c616565b91505b5094509492505050565b60008161422d5760405162461bcd60e51b81526004016106e5906155d3565b816000191480156142415750600160ff1b83145b1561425e5760405162461bcd60e51b81526004016106e590615633565b600082848161426957fe5b05949350505050565b6000808212156142945760405162461bcd60e51b81526004016106e5906155b3565b600282076142aa57670de0b6b3a76400006142ac565b825b90506002820591505b81156123af576142c58384613473565b925060028207156142dd576142da8184613473565b90505b6002820591506142b5565b60008184141561430a5760405162461bcd60e51b81526004016106e5906154b3565b61431a848363ffffffff6133c616565b905061433c61432f848463ffffffff6133c616565b829063ffffffff61340c16565b90506000811361435e5760405162461bcd60e51b81526004016106e590615743565b614366614485565b81126143845760405162461bcd60e51b81526004016106e5906155e3565b61438d81612e34565b90506143a4600c548261340c90919063ffffffff16565b90506143ae614485565b6143c66143b9614485565b839063ffffffff61449116565b8161426957fe5b6000838513156143ef5760405162461bcd60e51b81526004016106e590615543565b6143ff838363ffffffff6133c616565b905061443c61442f61441c86600b5461427290919063ffffffff16565b600b54612a08908963ffffffff61427216565b829063ffffffff61347316565b60025490915061445390829063ffffffff61340c16565b9050610e6c61447861446b868863ffffffff6133c616565b849063ffffffff61368216565b829063ffffffff6123c516565b670de0b6b3a764000090565b6000808312156144b35760405162461bcd60e51b81526004016106e590615683565b600082136144d35760405162461bcd60e51b81526004016106e5906154d3565b81826144e96144e286866123c5565b60016133c6565b816144f057fe5b05029392505050565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805160c08101909152806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b80356123af81615821565b80516123af81615821565b80516123af81615835565b80356123af8161583e565b80516123af81615847565b80516123af8161583e565b600060c082840312156145e957600080fd5b6145f360c061578b565b9050600061460184846145c1565b8252506020614612848483016145cc565b6020830152506040614626848285016145cc565b604083015250606061463a848285016145cc565b606083015250608061464e848285016145cc565b60808301525060a0614662848285016145cc565b60a08301525092915050565b6000610100828403121561468157600080fd5b61468c61010061578b565b9050600061469a84846145cc565b82525060206146ab848483016145cc565b60208301525060406146bf848285016145cc565b60408301525060606146d3848285016145cc565b60608301525060806146e7848285016145cc565b60808301525060a06146fb848285016145cc565b60a08301525060c061470f848285016145cc565b60c08301525060e0614723848285016145cc565b60e08301525092915050565b60006020828403121561474157600080fd5b6000610e6f84846145a0565b6000806000806080858703121561476357600080fd5b600061476f8787614595565b9450506020614780878288016145b6565b9350506040614791878288016145b6565b92505060606147a2878288016145b6565b91505092959194509250565b6000602082840312156147c057600080fd5b6000610e6f84846145ab565b600080604083850312156147df57600080fd5b60006147eb85856145b6565b92505060206147fc858286016145b6565b9150509250929050565b60006020828403121561481857600080fd5b6000610e6f84846145c1565b60006020828403121561483657600080fd5b6000610e6f84846145cc565b600060c0828403121561485457600080fd5b6000610e6f84846145d7565b6000610100828403121561487357600080fd5b6000610e6f848461466e565b60006020828403121561489157600080fd5b6000610e6f84846145b6565b600080604083850312156148b057600080fd5b60006148bc85856145cc565b92505060206147fc858286016145cc565b6000806000606084860312156148e257600080fd5b60006148ee86866145b6565b93505060206148ff868287016145b6565b9250506040614910868287016145b6565b9150509250925092565b6000806000806080858703121561493057600080fd5b600061476f87876145b6565b614945816157e4565b82525050565b614945816157be565b614945816157eb565b614945816157f6565b614945816157bb565b600061497c600d836157b2565b6c1c1c9a58d9481b1a5b5a5d1959609a1b815260200192915050565b60006149a5600b836157b2565b6a189d5c9b8819985a5b195960aa1b815260200192915050565b60006149cc6014836157b2565b73616c7068612073686f756c64206265203c3d203160601b815260200192915050565b60006149fc600d836157b2565b6c77726f6e67206164647265737360981b815260200192915050565b6000614a25601e836157b2565b7f6e6f20736f6c7574696f6e2031206f6e2066756e64696e672063757276650000815260200192915050565b6000614a5e6013836157b2565b723ab730baba3437b934bd32b21031b0b63632b960691b815260200192915050565b6000614a8d600f836157b2565b6e06365696c206e656564206d203e203608c1b815260200192915050565b6000614ab8600d836157b2565b6c73656e64657220756e7361666560981b815260200192915050565b6000614ae16022836157b2565b7f6c6f6745206f6e6c7920616363657074732076203c3d2031653232202a203165815261062760f31b602082015260400192915050565b6000614b25600b836157b2565b6a6d6f64206279207a65726f60a81b815260200192915050565b6000614b4c6016836157b2565b7577726f6e672070657270657475616c2073746174757360501b815260200192915050565b6000614b7e6013836157b2565b72556e6164646974696f6e206f766572666c6f7760681b815260200192915050565b6000614bad6014836157b2565b73736861726542616c616e636520746f6f206c6f7760601b815260200192915050565b6000614bdd6012836157b2565b711a5b9d1959dc985d19481c995d995c9cd95960721b815260200192915050565b6000614c0b600b836157b2565b6a1b5a5b9d0819985a5b195960aa1b815260200192915050565b6000614c32600e836157b2565b6d706f6f6c206e6f7420656d70747960901b815260200192915050565b6000614c5c6017836157b2565b7f6c6f6745206f66206e65676174697665206e756d626572000000000000000000815260200192915050565b6000614c956013836157b2565b72185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b815260200192915050565b6000614cc46019836157b2565b7f556e6d756c7469706c69636174696f6e206f766572666c6f7700000000000000815260200192915050565b6000614cfd601f836157b2565b7f726f756e6448616c665570206f6e6c7920737570706f7274732079203e203000815260200192915050565b6000614d36601a836157b2565b7f77706f7769206f6e6c7920737570706f727473206e203e3d2030000000000000815260200192915050565b6000614d6f6011836157b2565b706164646974696f6e206f766572666c6f7760781b815260200192915050565b6000614d9c6011836157b2565b70776469766973696f6e206279207a65726f60781b815260200192915050565b6000614dc9601e836157b2565b7f6e6f20736f6c7574696f6e2033206f6e2066756e64696e672063757276650000815260200192915050565b6000614e026011836157b2565b70191958591b1a5b9948195e18d959591959607a1b815260200192915050565b6000614e2f602a836157b2565b7f616d6f756e74206d75737420626520646976697369626c652062792074726164815269696e674c6f7453697a6560b01b602082015260400192915050565b6000614e7b600a836157b2565b69616d6d20756e7361666560b01b815260200192915050565b6000614ea16020836157b2565b7f616d6f756e74206d7573742062652067726561746572207468616e207a65726f815260200192915050565b6000614eda6012836157b2565b71776469766973696f6e206f766572666c6f7760701b815260200192915050565b6000614f08601f836157b2565b7f74696d6520737465707320286e29206d75737420626520706f73697469766500815260200192915050565b6000614f41600a836157b2565b6964657620756e7361666560b01b815260200192915050565b6000614f67600a836157b2565b69195b5c1d1e481c1bdbdb60b21b815260200192915050565b6000614f8d6015836157b2565b7464616e6765726f757320696e64657820707269636560581b815260200192915050565b6000614fbe6010836157b2565b6f06365696c206e6565642078203e3d20360841b815260200192915050565b6000614fea6009836157b2565b68696d20756e7361666560b81b815260200192915050565b600061500f6013836157b2565b720616c7068612073686f756c64206265203e203606c1b815260200192915050565b600061503e601f836157b2565b7f66756e64696e6720696e697469616c697a6174696f6e20726571756972656400815260200192915050565b60006150776018836157b2565b7f776d756c7469706c69636174696f6e206f766572666c6f770000000000000000815260200192915050565b60006150b06010836157b2565b6f75696e74323536206f766572666c6f7760801b815260200192915050565b60006150dc600c836157b2565b6b696e74206f766572666c6f7760a01b815260200192915050565b60006151046018836157b2565b7f77652063616e277420676f206261636b20696e2074696d650000000000000000815260200192915050565b600061513d6014836157b2565b737375627472616374696f6e206f766572666c6f7760601b815260200192915050565b600061516d600e836157b2565b6d6b6579206e6f742065786973747360901b815260200192915050565b60006151976016836157b2565b75556e7375627472616374696f6e206f766572666c6f7760501b815260200192915050565b60006151c96009836157b2565b683737ba1037bbb732b960b91b815260200192915050565b60006151ee601e836157b2565b7f6e6f20736f6c7574696f6e2032206f6e2066756e64696e672063757276650000815260200192915050565b805160c083019061522b8482614966565b50602082015161523e6020850182614966565b5060408201516152516040850182614966565b5060608201516152646060850182614966565b5060808201516152776080850182614966565b5060a08201516116b760a0850182614966565b805160a083019061529b8482614966565b5060208201516152ae6020850182614966565b5060408201516152c16040850182614966565b5060608201516152d46060850182614966565b5060808201516116b76080850182614966565b805460a08301906152f781615801565b6153018582614966565b5050600182015461531181615801565b61531e6020860182614966565b5050600282015461532e81615801565b61533b6040860182614966565b5050600382015461534b81615801565b6153586060860182614966565b5050600482015461536881615801565b610daa6080860182614966565b602081016123af828461494b565b602081016123af828461493c565b6040810161539f828561494b565b6107956020830184614966565b6040810161539f828561493c565b606081016153c8828661494b565b6153d5602083018561493c565b610e6f6040830184614966565b60a081016153f0828861494b565b6153fd602083018761494b565b61540a604083018661495d565b6154176060830185614966565b6154246080830184614966565b9695505050505050565b6060810161543c828661494b565b6153d5602083018561494b565b602081016123af8284614954565b602081016123af828461495d565b602081016123af8284614966565b602080825281016123af8161496f565b602080825281016123af81614998565b602080825281016123af816149bf565b602080825281016123af816149ef565b602080825281016123af81614a18565b602080825281016123af81614a51565b602080825281016123af81614a80565b602080825281016123af81614aab565b602080825281016123af81614ad4565b602080825281016123af81614b18565b602080825281016123af81614b3f565b602080825281016123af81614b71565b602080825281016123af81614ba0565b602080825281016123af81614bd0565b602080825281016123af81614bfe565b602080825281016123af81614c25565b602080825281016123af81614c4f565b602080825281016123af81614c88565b602080825281016123af81614cb7565b602080825281016123af81614cf0565b602080825281016123af81614d29565b602080825281016123af81614d62565b602080825281016123af81614d8f565b602080825281016123af81614dbc565b602080825281016123af81614df5565b602080825281016123af81614e22565b602080825281016123af81614e6e565b602080825281016123af81614e94565b602080825281016123af81614ecd565b602080825281016123af81614efb565b602080825281016123af81614f34565b602080825281016123af81614f5a565b602080825281016123af81614f80565b602080825281016123af81614fb1565b602080825281016123af81614fdd565b602080825281016123af81615002565b602080825281016123af81615031565b602080825281016123af8161506a565b602080825281016123af816150a3565b602080825281016123af816150cf565b602080825281016123af816150f7565b602080825281016123af81615130565b602080825281016123af81615160565b602080825281016123af8161518a565b602080825281016123af816151bc565b602080825281016123af816151e1565b60c081016123af828461521a565b60a081016123af828461528a565b60a081016123af82846152e7565b6040810161539f8285614966565b60405181810167ffffffffffffffff811182821017156157aa57600080fd5b604052919050565b90815260200190565b90565b60006123af826157d8565b151590565b80612a6081615814565b6001600160a01b031690565b60006123af825b60006123af826157be565b60006123af826157ce565b60006123af61580f836157bb565b6157bb565b6003811061581e57fe5b50565b61582a816157be565b811461581e57600080fd5b61582a816157c9565b61582a816157bb565b6003811061581e57600080fdfea365627a7a72315820afea0d0400ac60b2c919243edd9ad1a4c662c5e60924ae327140ed3d7dd3891e6c6578706572696d656e74616cf564736f6c634300050f0040

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

00000000000000000000000071e77ffbbfd4418ed47981927738b5425c187f6400000000000000000000000005c363d2b9afc36b070fe2c61711280edc2146780000000000000000000000009b2d7d7f7b2810ef2be979fc2acebe6097d9563a000000000000000000000000ae694fb9dcd1e6195519c0056b2ab19380b26ff2

-----Decoded View---------------
Arg [0] : _globalConfig (address): 0x71e77Ffbbfd4418ED47981927738b5425c187F64
Arg [1] : _perpetualProxy (address): 0x05c363D2B9AFc36b070fe2c61711280eDC214678
Arg [2] : _priceFeeder (address): 0x9B2D7D7f7b2810Ef2be979fc2ACebe6097d9563A
Arg [3] : _shareToken (address): 0xAe694FB9DCD1E6195519c0056B2aB19380B26FF2

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000071e77ffbbfd4418ed47981927738b5425c187f64
Arg [1] : 00000000000000000000000005c363d2b9afc36b070fe2c61711280edc214678
Arg [2] : 0000000000000000000000009b2d7d7f7b2810ef2be979fc2acebe6097d9563a
Arg [3] : 000000000000000000000000ae694fb9dcd1e6195519c0056b2ab19380b26ff2


Deployed Bytecode Sourcemap

45453:47523:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70123:296;;;;;;;;;:::i;:::-;;47161:117;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47161:117:0;;;:::i;:::-;;;;;;;;;;;;;;;;46482:191;;8:9:-1;5:2;;;30:1;27;20:12;5:2;46482:191:0;;;:::i;:::-;;;;;;;;;43131:31;;8:9:-1;5:2;;;30:1;27;20:12;5:2;43131:31:0;;;:::i;:::-;;;;;;;;45327:119;;8:9:-1;5:2;;;30:1;27;20:12;5:2;45327:119:0;;;:::i;:::-;;;;;;;;51606:126;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51606:126:0;;;:::i;:::-;;;;;;;;53663:117;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53663:117:0;;;:::i;42995:23::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;42995:23:0;;;:::i;43092:32::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;43092:32:0;;;:::i;58568:201::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;58568:201:0;;;;;;;;:::i;50638:203::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50638:203:0;;;:::i;62349:987::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;62349:987:0;;;;;;;;:::i;65243:614::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;65243:614:0;;;:::i;53249:117::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53249:117:0;;;:::i;60957:286::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;60957:286:0;;;;;;;;:::i;43041:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;43041:25:0;;;:::i;54814:1014::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;54814:1014:0;;;;;;;;:::i;52434:109::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52434:109:0;;;:::i;46741:134::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;46741:134:0;;;:::i;54095:160::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54095:160:0;;;:::i;63695:1220::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;63695:1220:0;;;;;;;;:::i;58023:284::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;58023:284:0;;;;;;;;:::i;68066:376::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;68066:376:0;;;;;;;;:::i;43169:33::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;43169:33:0;;;:::i;43866:1414::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;43866:1414:0;;;;;;;;:::i;52027:114::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52027:114:0;;;:::i;68901:378::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;68901:378:0;;;;;;;;:::i;66312:419::-;;;;;;;;;:::i;70558:526::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70558:526:0;;;:::i;61507:203::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;61507:203:0;;;;;;;;:::i;52838:114::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52838:114:0;;;:::i;46253:104::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;46253:104:0;;;:::i;:::-;;;;;;;;67188:421;;;;;;;;;:::i;51166:135::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51166:135:0;;;:::i;70123:296::-;70224:17;;70220:119;;70258:14;;:69;;-1:-1:-1;;;70258:69:0;;-1:-1:-1;;;;;70258:14:0;;;;:25;;70290:9;;70258:69;;70301:10;;70313:13;;70258:69;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70258:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70258:69:0;;;;;70220:119;70353:10;;70349:63;;70380:20;70393:6;70380:12;:20::i;:::-;70123:296;;:::o;47161:117::-;47210:28;;:::i;:::-;-1:-1:-1;47251:19:0;;;;;;;;47258:12;47251:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47161:117;:::o;46482:191::-;46591:11;;:19;;;-1:-1:-1;;;46591:19:0;;;;46525:13;;;;-1:-1:-1;;;;;46591:11:0;;;;:17;;:19;;;;;;;;;;;:11;:19;;;5:2:-1;;;;30:1;27;20:12;5:2;46591:19:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;46591:19:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;46591:19:0;;;;;;;;;46570:40;;-1:-1:-1;46570:40:0;-1:-1:-1;46629:10:0;46621:44;;;;-1:-1:-1;;;46621:44:0;;;;;;;;;;;;;;;;;46482:191;;:::o;43131:31::-;;;-1:-1:-1;;;;;43131:31:0;;:::o;45327:119::-;45373:35;;:::i;:::-;-1:-1:-1;45421:17:0;;;;;;;;45428:10;45421:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45327:119;:::o;51606:126::-;51656:7;51676:9;:7;:9::i;:::-;51703:21;:19;:21::i;:::-;51696:28;;51606:126;:::o;53663:117::-;53709:6;53728:9;:7;:9::i;:::-;53755:17;:15;:17::i;42995:23::-;;;;:::o;43092:32::-;;;-1:-1:-1;;;;;43092:32:0;;:::o;58568:201::-;58685:7;58712:49;58720:10;58732:6;58740:10;58752:8;58712:7;:49::i;:::-;58705:56;;58568:201;;;;;;:::o;50638:203::-;50686:6;50705:11;50719:17;:15;:17::i;:::-;50805:26;;50705:31;;-1:-1:-1;50754:79:0;;50795:37;;50705:31;;50805:10;50804:27;50795:37;:8;:37;:::i;:::-;50763:26;;50754:36;;:4;;:36;:8;:36;:::i;:::-;:40;:79;:40;:79;:::i;:::-;50747:86;;;50638:203;:::o;62349:987::-;62413:14;;:23;;;-1:-1:-1;;;62413:23:0;;;;62440:22;;-1:-1:-1;;;;;62413:14:0;;:21;;:23;;;;;;;;;;;;;;:14;:23;;;5:2:-1;;;;30:1;27;20:12;5:2;62413:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62413:23:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;62413:23:0;;;;;;;;;:49;;;;;;;;;62405:84;;;;-1:-1:-1;;;62405:84:0;;;;;;;;;62502:26;62539:27;62621:11;:9;:11::i;:::-;62577:55;;-1:-1:-1;62577:55:0;-1:-1:-1;62651:24:0;;;;;:51;;-1:-1:-1;62679:23:0;;;62651:51;62643:74;;;;-1:-1:-1;;;62643:74:0;;;;;;;;;62747:10;62730:14;62784:44;:18;62808:19;62784:44;:23;:44;:::i;:::-;62768:60;-1:-1:-1;62841:24:0;62868:25;62891:1;62868:18;:6;62768:60;62868:18;:11;:18;:::i;:::-;:22;:25;:22;:25;:::i;:::-;62904:14;;62841:52;;-1:-1:-1;;;;;;62904:14:0;:34;62939:6;62947:16;:14;:16::i;:::-;62965;62904:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62904:78:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;63014:14:0;;62994;;-1:-1:-1;;;;;;63014:14:0;;-1:-1:-1;63014:28:0;63043:6;63051:16;:14;:16::i;:::-;63069:19;63090:5;63097:6;63014:90;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63014:90:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63014:90:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;63014:90:0;;;;;;;;;62993:111;;;63117:89;63134:6;63142:63;63185:19;63142:37;63172:6;63142:10;;;;;;;;;-1:-1:-1;;;;;63142:10:0;-1:-1:-1;;;;;63142:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63142:24:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63142:24:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;63142:24:0;;;;;;;;;:29;:37;:29;:37;:::i;:::-;:42;:63;:42;:63;:::i;:::-;63117:16;:89::i;:::-;63219:14;:12;:14::i;:::-;63304:24;63313:6;63321;63304:8;:24::i;:::-;62349:987;;;;;;;:::o;65243:614::-;65292:14;;:23;;;-1:-1:-1;;;65292:23:0;;;;65319;;-1:-1:-1;;;;;65292:14:0;;:21;;:23;;;;;;;;;;;;;;:14;:23;;;5:2:-1;;;;30:1;27;20:12;5:2;65292:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65292:23:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;65292:23:0;;;;;;;;;:50;;;;;;;;;65284:85;;;;-1:-1:-1;;;65284:85:0;;;;;;;;;65399:10;65420:37;;:::i;:::-;65460:14;;-1:-1:-1;;;;;65460:14:0;:31;65492:16;:14;:16::i;:::-;65460:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;65460:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65460:49:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;65460:49:0;;;;;;;;;65420:89;;65520:13;65536:39;65567:7;65536:30;:39::i;:::-;65608:10;;:28;;-1:-1:-1;;;65608:28:0;;65520:55;;-1:-1:-1;65586:19:0;;-1:-1:-1;;;;;65608:10:0;;;;:20;;:28;;65629:6;;65608:28;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;65608:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65608:28:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;65608:28:0;;;;;;;;;65586:50;;65647:15;65665:54;65694:10;;;;;;;;;-1:-1:-1;;;;;65694:10:0;-1:-1:-1;;;;;65694:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;65694:24:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65694:24:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;65694:24:0;;;;;;;;;65665:23;:11;65682:5;65665:23;:16;:23;:::i;:54::-;65730:14;;65647:72;;-1:-1:-1;;;;;;65730:14:0;:34;65765:16;:14;:16::i;:::-;65783:6;65791:7;65730:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;65730:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65730:69:0;;;;65810:39;65829:6;65837:11;65810:18;:39::i;:::-;65243:614;;;;;:::o;53249:117::-;53295:6;53314:9;:7;:9::i;:::-;53341:17;:15;:17::i;60957:286::-;43631:12;;:36;;-1:-1:-1;;;43631:36:0;;61157:7;;-1:-1:-1;;;;;43631:12:0;;:24;;:36;;43656:10;;43631:36;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;43631:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;43631:36:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;43631:36:0;;;;;;;;;43623:68;;;;-1:-1:-1;;;43623:68:0;;;;;;;;;61189:46;61198:6;61206;61214:10;61226:8;61189;:46::i;:::-;61182:53;;43702:1;60957:286;;;;;;:::o;43041:25::-;;;;:::o;54814:1014::-;54885:1;54876:6;:10;54868:55;;;;-1:-1:-1;;;54868:55:0;;;;;;;;;54942:14;;:23;;;-1:-1:-1;;;54942:23:0;;;;54969:22;;-1:-1:-1;;;;;54942:14:0;;:21;;:23;;;;;;;;;;;;;;:14;:23;;;5:2:-1;;;;30:1;27;20:12;5:2;54942:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54942:23:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;54942:23:0;;;;;;;;;:49;;;;;;;;;54934:84;;;;-1:-1:-1;;;54934:84:0;;;;;;;;;55037:14;:12;:14::i;:::-;:19;55029:46;;;;-1:-1:-1;;;55029:46:0;;;;;;;;;55105:10;55088:14;55146:19;:17;:19::i;:::-;55126:39;;55176:21;55208:25;55281:12;:10;:12::i;:::-;55244:49;;-1:-1:-1;55244:49:0;-1:-1:-1;55306:37:0;55244:49;55333:9;55306:11;:37::i;:::-;55354:14;;-1:-1:-1;;;;;55354:14:0;:34;55389:6;55397:16;:14;:16::i;:::-;55415:33;55446:1;55415:26;:13;55434:6;55415:26;:18;:26;:::i;:33::-;55354:95;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55354:95:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;55481:14:0;;55461;;-1:-1:-1;;;;;;55481:14:0;;-1:-1:-1;55481:28:0;55524:6;55545:16;:14;:16::i;:::-;55576:19;55610:13;55638:6;55481:174;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55481:174:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55481:174:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;55481:174:0;;;;;;;;;55460:195;;;55666:32;55683:6;55691;55666:16;:32::i;:::-;55711:14;:12;:14::i;:::-;55796:24;55805:6;55813;55796:8;:24::i;:::-;54814:1014;;;;;;:::o;52434:109::-;52476:6;52495:9;:7;:9::i;:::-;52522:13;:11;:13::i;46741:134::-;46813:14;;46786:7;;-1:-1:-1;;;;;46813:14:0;:31;46845:16;:14;:16::i;:::-;46813:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;46813:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;46813:49:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;46813:49:0;;;;;;;;;:54;;;46806:61;;46741:134;:::o;54095:160::-;54159:6;54178:9;:7;:9::i;:::-;-1:-1:-1;54205:42:0;;54095:160;:::o;63695:1220::-;63767:14;;:23;;;-1:-1:-1;;;63767:23:0;;;;63794:22;;-1:-1:-1;;;;;63767:14:0;;:21;;:23;;;;;;;;;;;;;;:14;:23;;;5:2:-1;;;;30:1;27;20:12;5:2;63767:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63767:23:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;63767:23:0;;;;;;;;;:49;;;;;;;;;63759:84;;;;-1:-1:-1;;;63759:84:0;;;;;;;;;63873:10;63856:14;;64013:11;:9;:11::i;:::-;63969:55;;-1:-1:-1;63969:55:0;-1:-1:-1;64043:24:0;;;;;:51;;-1:-1:-1;64071:23:0;;;64043:51;64035:74;;;;-1:-1:-1;;;64035:74:0;;;;;;;;;64128:10;;:32;;-1:-1:-1;;;64128:32:0;;64164:11;;-1:-1:-1;;;;;64128:10:0;;:20;;:32;;64149:10;;64128:32;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64128:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64128:32:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;64128:32:0;;;;;;;;;:47;;64120:80;;;;-1:-1:-1;;;64120:80:0;;;;;;;;;64211:13;64227:44;:18;64251:19;64227:44;:23;:44;:::i;:::-;64211:60;;64282:14;64299:68;64342:10;;;;;;;;;-1:-1:-1;;;;;64342:10:0;-1:-1:-1;;;;;64342:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64342:24:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64342:24:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;64342:24:0;;;;;;;;;64299:37;:11;64316:19;64299:37;:16;:37;:::i;:68::-;64282:85;;64407:15;64425:14;;;;;;;;;-1:-1:-1;;;;;64425:14:0;-1:-1:-1;;;;;64425:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64425:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64425:30:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;64425:30:0;;;;;;;;;:38;;;;-1:-1:-1;64483:31:0;64494:19;:6;64425:38;64494:19;:10;:19;:::i;:::-;64483:6;;:31;:10;:31;:::i;:::-;64527:14;;64474:40;;-1:-1:-1;;;;;;64527:14:0;:34;64562:16;:14;:16::i;:::-;64580:6;64588:25;64611:1;64588:18;:5;64599:6;64588:18;:10;:18;:::i;:25::-;64527:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64527:87:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64527:87:0;;;;64625:39;64644:6;64652:11;64625:18;:39::i;:::-;64696:14;;64676;;-1:-1:-1;;;;;64696:14:0;:28;64725:6;64733:16;:14;:16::i;:::-;64751:18;64771:5;64778:6;64696:89;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64696:89:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64696:89:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;64696:89:0;;;;;;;;;64675:110;;;64798:14;:12;:14::i;:::-;64883:24;64892:6;64900;64883:8;:24::i;:::-;63695:1220;;;;;;;;:::o;58023:284::-;43631:12;;:36;;-1:-1:-1;;;43631:36:0;;58222:7;;-1:-1:-1;;;;;43631:12:0;;:24;;:36;;43656:10;;43631:36;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;43631:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;43631:36:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;43631:36:0;;;;;;;;;43623:68;;;;-1:-1:-1;;;43623:68:0;;;;;;;;;58254:45;58262:6;58270;58278:10;58290:8;58254:7;:45::i;68066:376::-;68238:15;;68234:86;;68270:38;68274:11;68287:10;68299:8;68270:3;:38::i;:::-;;68234:86;68334:18;;68330:105;;68369:14;;:54;;-1:-1:-1;;;68369:54:0;;-1:-1:-1;;;;;68369:14:0;;;;:26;;:54;;68396:10;;68408:14;;68369:54;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68369:54:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;68330:105:0;68066:376;;;;:::o;43169:33::-;;;-1:-1:-1;;;;;43169:33:0;;:::o;43866:1414::-;43510:12;;:20;;;-1:-1:-1;;;43510:20:0;;;;43534:10;;-1:-1:-1;;;;;43510:12:0;;:18;;:20;;;;;;;;;;;;;;:12;:20;;;5:2:-1;;;;30:1;27;20:12;5:2;43510:20:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;43510:20:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;43510:20:0;;;;;;;;;-1:-1:-1;;;;;43510:34:0;;43502:56;;;;-1:-1:-1;;;43502:56:0;;;;;;;;;43957:3;-1:-1:-1;;;43957:20:0;43953:1267;;;44019:17;:5;:15;:17::i;:::-;43994:10;:42;43953:1267;;;44058:3;-1:-1:-1;;;44058:23:0;44054:1166;;;44126:17;:5;:15;:17::i;:::-;44098:25;:45;44054:1166;;;44165:3;-1:-1:-1;;;44165:17:0;44161:1059;;;44215:1;44207:5;:9;44199:41;;;;-1:-1:-1;;;44199:41:0;;;;;;;;;44272:6;44263:5;:15;;44255:48;;;;-1:-1:-1;;;44255:48:0;;;;;;;;;44318:19;:27;;;44372:6;:28;;;44360:9;:40;;;44429:15;;:13;:15::i;:::-;44415:11;:29;44161:1059;;;44466:3;-1:-1:-1;;;44466:27:0;44462:758;;;44542:17;:5;:15;:17::i;:::-;44510:29;:49;44462:758;;;44581:3;-1:-1:-1;;;44581:25:0;44577:643;;;44623:27;:35;;;44577:643;;;44680:3;-1:-1:-1;;;44680:24:0;44676:544;;;44721:26;:34;;;44676:544;;;44777:3;:38;;44773:447;;;44840:14;;:23;;;-1:-1:-1;;;44840:23:0;;;;44867:25;;-1:-1:-1;;;;;44840:14:0;;:21;;:23;;;;;;;;;;;;;;:14;:23;;;5:2:-1;;;;30:1;27;20:12;5:2;44840:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;44840:23:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;44840:23:0;;;;;;;;;:52;;;;;;;;;44832:87;;;;-1:-1:-1;;;44832:87:0;;;;;;;;;44934:42;:50;;;44773:447;;;45006:3;-1:-1:-1;;;45006:20:0;45002:218;;;45051:34;45078:5;45051:18;:34::i;:::-;45043:60;;;;-1:-1:-1;;;45043:60:0;;;;;;;;;45118:11;:33;;-1:-1:-1;;;;;;45118:33:0;-1:-1:-1;;;;;45118:33:0;;;;;45002:218;;;45184:24;;-1:-1:-1;;;45184:24:0;;;;;;;;45002:218;45261:3;45235:37;45266:5;45235:37;;;;;;;;;;;;;;;43866:1414;;:::o;52027:114::-;52071:7;52091:9;:7;:9::i;:::-;52118:15;:13;:15::i;68901:378::-;69074:15;;69070:87;;69106:39;69111:11;69124:10;69136:8;69106:4;:39::i;66312:419::-;66513:17;;66509:119;;66547:14;;:69;;-1:-1:-1;;;66547:69:0;;-1:-1:-1;;;;;66547:14:0;;;;:25;;66579:9;;66547:69;;66590:10;;66602:13;;66547:69;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66547:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;66547:69:0;;;;;66509:119;66642:15;;66638:86;;66674:38;66678:11;66691:10;66703:8;66674:3;:38::i;70558:526::-;70607:14;;:23;;;-1:-1:-1;;;70607:23:0;;;;70634:22;;-1:-1:-1;;;;;70607:14:0;;:21;;:23;;;;;;;;;;;;;;:14;:23;;;5:2:-1;;;;30:1;27;20:12;5:2;70607:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70607:23:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;70607:23:0;;;;;;;;;:49;;;;;;;;;70599:84;;;;-1:-1:-1;;;70599:84:0;;;;;;;;;70718:27;;70756:14;:12;:14::i;:::-;70802;;:27;;;-1:-1:-1;;;70802:27:0;;;;70781:18;;-1:-1:-1;;;;;70802:14:0;;:25;;:27;;;;;;;;;;;;;;:14;:27;;;5:2:-1;;;;30:1;27;20:12;5:2;70802:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70802:27:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;70802:27:0;;;;;;;;;70861;;70781:48;;-1:-1:-1;70844:44:0;;70840:237;;70905:14;;70964:29;;70905:89;;-1:-1:-1;;;70905:89:0;;-1:-1:-1;;;;;70905:14:0;;;;:34;;:89;;70940:10;;70952;;70905:89;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70905:89:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;71017:14:0;;:33;;-1:-1:-1;;;71017:33:0;;-1:-1:-1;;;;;71017:14:0;;;;-1:-1:-1;71017:21:0;;-1:-1:-1;71017:33:0;;71039:10;;71017:33;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71017:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71017:33:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;71017:33:0;;;;;;;;;71009:56;;;;-1:-1:-1;;;71009:56:0;;;;;;;;61507:203;61625:7;61652:50;61661:10;61673:6;61681:10;61693:8;61652;:50::i;52838:114::-;52882:7;52902:9;:7;:9::i;:::-;52929:15;:13;:15::i;46253:104::-;46338:10;;-1:-1:-1;;;;;46338:10:0;46253:104;:::o;67188:421::-;67390:17;;67386:119;;67424:14;;:69;;-1:-1:-1;;;67424:69:0;;-1:-1:-1;;;;;67424:14:0;;;;:25;;67456:9;;67424:69;;67467:10;;67479:13;;67424:69;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67424:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67424:69:0;;;;;67386:119;67519:15;;67515:87;;67551:39;67556:11;67569:10;67581:8;67551:4;:39::i;51166:135::-;51213:28;;:::i;:::-;51254:9;75704:712;75747:14;;:23;;;-1:-1:-1;;;75747:23:0;;;;75774:22;;-1:-1:-1;;;;;75747:14:0;;:21;;:23;;;;;;;;;;;;;;:14;:23;;;5:2:-1;;;;30:1;27;20:12;5:2;75747:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75747:23:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;75747:23:0;;;;;;;;;:49;;;;;;;;;75743:88;;75813:7;;75743:88;75841:17;75861:19;:17;:19::i;:::-;75841:39;;75891:21;75923:25;75996:12;:10;:12::i;:::-;76050;:28;75959:49;;-1:-1:-1;75959:49:0;-1:-1:-1;76037:41:0;;;;:117;;-1:-1:-1;76127:27:0;;76110:44;;;76037:117;:261;;;-1:-1:-1;76270:12:0;:28;76250:48;;76037:261;76019:390;;;76340:57;76353:9;76364:13;76379:17;76340:12;:57::i;:::-;75704:712;;;;:::o;47571:228::-;47625:7;47645:37;;:::i;:::-;47685:14;;-1:-1:-1;;;;;47685:14:0;:31;47717:16;:14;:16::i;:::-;47685:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47685:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;47685:49:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;47685:49:0;;;;;;;;;47645:89;;47752:39;47783:7;47752:30;:39::i;56478:1211::-;56643:7;;56671:14;;;;;;;;;-1:-1:-1;;;;;56671:14:0;-1:-1:-1;;;;;56671:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56671:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56671:23:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;56671:23:0;;;;;;;;;:49;;;;;;;;;56663:84;;;;-1:-1:-1;;;56663:84:0;;;;;;;;;56766:14;;:44;;-1:-1:-1;;;56766:44:0;;-1:-1:-1;;;;;56766:14:0;;;;:36;;:44;;56803:6;;56766:44;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56766:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56766:44:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;56766:44:0;;;;;;;;;56758:99;;;;-1:-1:-1;;;56758:99:0;;;;;;;;;56870:13;56886:19;56898:6;56886:11;:19::i;:::-;56870:35;;56938:5;56924:10;:19;;56916:45;;;;-1:-1:-1;;;56916:45:0;;;;;;;;;57003:8;56980:19;:17;:19::i;:::-;:31;;56972:61;;;;-1:-1:-1;;;56972:61:0;;;;;;;;;57065:14;;57045;;-1:-1:-1;;;;;57065:14:0;:28;57094:6;57102:16;:14;:16::i;:::-;57120:18;57140:5;57147:6;57065:89;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57065:89:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57065:89:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;57065:89:0;;;;;;;;;-1:-1:-1;57044:110:0;-1:-1:-1;57167:13:0;57183:18;:5;57194:6;57183:18;:10;:18;:::i;:::-;57212:11;57237:22;;57167:34;;-1:-1:-1;57212:11:0;57226:34;;57167;;57226;:10;:34;:::i;:::-;57299:25;;57212:48;;-1:-1:-1;57271:14:0;;57288:37;;:5;;:37;:10;:37;:::i;:::-;57271:54;;57336:18;57357:14;;;;;;;;;-1:-1:-1;;;;;57357:14:0;-1:-1:-1;;;;;57357:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57357:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57357:27:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;57357:27:0;;;;;;;;;57397:14;;57336:48;;-1:-1:-1;;;;;;57397:14:0;:34;57432:6;57440:16;:14;:16::i;:::-;57458:3;57397:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57397:65:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;57473:14:0;;:62;;-1:-1:-1;;;57473:62:0;;-1:-1:-1;;;;;57473:14:0;;;;-1:-1:-1;57473:34:0;;-1:-1:-1;57473:62:0;;57508:6;;57516:10;;57528:6;;57473:62;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57473:62:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57473:62:0;;;;57548:14;:12;:14::i;:::-;57633:24;57642:6;57650;57633:8;:24::i;:::-;-1:-1:-1;57675:6:0;;56478:1211;-1:-1:-1;;;;;;;;;56478:1211:0:o;50105:248::-;50155:6;50174:12;50189:38;:12;:27;;;:36;:38::i;:::-;50174:53;;50238:11;50252:26;:15;:13;:15::i;:::-;:24;:26::i;:::-;50238:40;-1:-1:-1;50296:27:0;50317:5;50296:15;50238:40;50317:5;50296:15;:8;:15;:::i;:::-;:20;:27;:20;:27;:::i;:::-;50289:34;-1:-1:-1;;;50105:248:0;:::o;4588:104::-;4644:6;4675:1;4670;:6;;:14;;4683:1;4670:14;;;4679:1;4670:14;4663:21;;4588:104;;;;;:::o;4700:::-;4756:6;4787:1;4782;:6;;:14;;4795:1;4782:14;;3681:199;3737:6;3767:5;;;3792:6;;;;;;:16;;;3807:1;3802;:6;;3792:16;3791:38;;;;3818:1;3814;:5;:14;;;;;3827:1;3823;:5;3814:14;3783:68;;;;-1:-1:-1;;;3783:68:0;;;;;;;;71505:270;71544:9;71555;71577;:7;:9::i;:::-;71597:37;;:::i;:::-;71637:14;;-1:-1:-1;;;;;71637:14:0;:31;71669:16;:14;:16::i;:::-;71637:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71637:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71637:49:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;71637:49:0;;;;;;;;;71597:89;;71701:39;71732:7;71701:30;:39::i;:::-;71697:43;;71755:7;:12;;;71751:16;;71505:270;;;:::o;11208:121::-;11267:9;11320:1;11293:24;11297:12;11301:1;8740:6;11297:3;:12::i;:::-;11315:1;11311;:5;;11293:3;:24::i;:::-;:28;;;;;;;11208:121;-1:-1:-1;;;11208:121:0:o;11076:124::-;11135:9;8740:6;11161:24;11165:9;11169:1;11172;11165:3;:9::i;:::-;11183:1;8740:6;11176:8;;9981:463;10039:7;10284:6;10280:47;;-1:-1:-1;10314:1:0;10307:8;;10280:47;10351:5;;;10355:1;10351;:5;:1;10375:5;;;;;:10;10367:48;;;;-1:-1:-1;;;10367:48:0;;;;;;;;54324:107;54408:14;;-1:-1:-1;;;;;54408:14:0;54324:107;:::o;74218:141::-;74304:10;;:31;;-1:-1:-1;;;74304:31:0;;-1:-1:-1;;;;;74304:10:0;;;;:15;;:31;;74320:6;;74328;;74304:31;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74304:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;74304:31:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;74304:31:0;;;;;;;;;74296:55;;;;-1:-1:-1;;;74296:55:0;;;;;;;;76736:382;76788:14;;:23;;;-1:-1:-1;;;76788:23:0;;;;76815:22;;-1:-1:-1;;;;;76788:14:0;;:21;;:23;;;;;;;;;;;;;;:14;:23;;;5:2:-1;;;;30:1;27;20:12;5:2;76788:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;76788:23:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;76788:23:0;;;;;;;;;:49;;;;;;;;;76780:84;;;;-1:-1:-1;;;76780:84:0;;;;;;;;;76875:17;76895:19;:17;:19::i;:::-;76875:39;;76925:21;76957:25;77030:12;:10;:12::i;:::-;76993:49;;-1:-1:-1;76993:49:0;-1:-1:-1;77053:57:0;77066:9;76993:49;;77053:12;:57::i;73539:529::-;73702:14;;:26;;;-1:-1:-1;;;73702:26:0;;;;73673;;-1:-1:-1;;;;;73702:14:0;;:24;;:26;;;;;;;;;;;;;;73673;73702:14;:26;;;5:2:-1;;;;30:1;27;20:12;5:2;73702:26:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73702:26:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;73702:26:0;;;;;;;;;73673:55;-1:-1:-1;73743:10:0;;73739:125;;73778:14;;:60;;-1:-1:-1;;;73778:60:0;;-1:-1:-1;;;;;73778:14:0;;;;:32;;:60;;73811:6;;73819:18;;73778:60;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73778:60:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73778:60:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;73778:60:0;;;;;;;;;73770:82;;;;-1:-1:-1;;;73770:82:0;;;;;;;;;73882:14;;:58;;-1:-1:-1;;;73882:58:0;;-1:-1:-1;;;;;73882:14:0;;;;:30;;:58;;73913:6;;73921:18;;73882:58;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73882:58:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73882:58:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;73882:58:0;;;;;;;;;73874:84;;;;-1:-1:-1;;;73874:84:0;;;;;;;;;73977:14;;-1:-1:-1;;;;;73977:14:0;:30;74008:16;:14;:16::i;:::-;74026:18;73977:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73977:68:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73977:68:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;73977:68:0;;;;;;;;;73969:91;;;;-1:-1:-1;;;73969:91:0;;;;;;;;71866:655;72007:19;;;;72068:14;;72105:12;;72068:50;;-1:-1:-1;;;72068:50:0;;71968:7;;72007:19;71968:7;;-1:-1:-1;;;;;72068:14:0;;;;:36;;:50;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72068:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72068:50:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;72068:50:0;;;;;;;;;72037:81;;72141:44;72155:29;:7;:18;;;:27;:29::i;:::-;72141:9;;:44;:13;:44;:::i;:::-;72129:56;;72208:95;72222:80;72278:7;:23;;;72222:51;72249:23;:7;:12;;;:21;:23::i;:::-;72222:21;;:51;:26;:51;:::i;:::-;:55;:80;:55;:80;:::i;72208:95::-;72196:107;;72326:141;72354:102;72431:7;:24;;;72354:72;72402:23;:7;:12;;;:21;:23::i;:::-;72354:42;;;:72;:47;:72;:::i;72326:141::-;72314:153;-1:-1:-1;72485:28:0;:16;72314:153;72499:1;72485:16;:13;:16;:::i;:::-;:26;:28::i;:::-;72478:35;;;;71866:655;;;;:::o;74503:143::-;74591:10;;:31;;-1:-1:-1;;;74591:31:0;;-1:-1:-1;;;;;74591:10:0;;;;:15;;:31;;74607:6;;74615;;74591:31;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74591:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;74591:31:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;74591:31:0;;;;;;;;;74583:55;;;;-1:-1:-1;;;74583:55:0;;;;;;;;59426:1194;59574:7;;59602:14;;;;;;;;;-1:-1:-1;;;;;59602:14:0;-1:-1:-1;;;;;59602:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59602:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59602:23:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;59602:23:0;;;;;;;;;:49;;;;;;;;;59594:84;;;;-1:-1:-1;;;59594:84:0;;;;;;;;;59697:14;;:44;;-1:-1:-1;;;59697:44:0;;-1:-1:-1;;;;;59697:14:0;;;;:36;;:44;;59734:6;;59697:44;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59697:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59697:44:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;59697:44:0;;;;;;;;;59689:99;;;;-1:-1:-1;;;59689:99:0;;;;;;;;;59801:13;59817:20;59830:6;59817:12;:20::i;:::-;59801:36;;59870:5;59856:10;:19;;59848:45;;;;-1:-1:-1;;;59848:45:0;;;;;;;;;59935:8;59912:19;:17;:19::i;:::-;:31;;59904:61;;;;-1:-1:-1;;;59904:61:0;;;;;;;;;59997:14;;59977;;-1:-1:-1;;;;;59997:14:0;:28;60026:6;60034:16;:14;:16::i;:::-;60052:19;60073:5;60080:6;59997:90;;;;;;;;;;;;;;;;;;;;71190:165;71332:15;71190:165;:::o;74953:341::-;75043:12;:28;:33;75035:65;;;;-1:-1:-1;;;75035:65:0;;;;;;;;;75111:12;:40;75162:27;:43;75111:28;75216:24;:28;;;75255:27;:31;74953:341::o;48579:211::-;48625:6;48644:37;;:::i;:::-;48684:14;;-1:-1:-1;;;;;48684:14:0;:31;48716:16;:14;:16::i;:::-;48684:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48684:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;48684:49:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;48684:49:0;;;;;;;;;48644:89;;48751:31;48774:7;48751:22;:31::i;12147:139::-;12205:7;12233:6;12225:30;;;;-1:-1:-1;;;12225:30:0;;;;;;;;;12277:1;12273;:5;;;;;;;12147:139;-1:-1:-1;;;12147:139:0:o;9571:176::-;9629:7;9662:1;9657;:6;;9649:41;;;;-1:-1:-1;;;9649:41:0;;;;;;;;;-1:-1:-1;9713:5:0;;;9571:176::o;4925:139::-;4977:7;5010:1;5005;:6;;4997:31;;;;-1:-1:-1;;;4997:31:0;;;;;;;;;-1:-1:-1;5054:1:0;4925:139::o;6014:2294::-;6060:6;6091:1;6087;:5;6079:41;;;;-1:-1:-1;;;6079:41:0;;;;;;;;;6144;6139:1;:46;;6131:93;;;;-1:-1:-1;;;6131:93:0;;;;;;;;;6274:8;1217:2;6374:33;6421:104;6433:12;6428:17;;6421:104;;6466:1;6470:2;6466:6;6462:10;;1579:37;6487:26;;;;6421:104;;;6547:12;6542:17;;6535:104;;6584:2;6580:1;:6;6576:10;;1579:37;6601:26;;;;6535:104;;;1260:8;6656:1;:11;6649:101;;;6688:16;6693:1;1309:19;6688:4;:16::i;:::-;6684:20;;1516:8;6719:19;;;;6649:101;;;1309:19;6767:1;:11;6760:101;;;6799:16;6804:1;1309:19;6799:4;:16::i;:::-;6795:20;;1516:8;6830:19;;;;6760:101;;;1260:8;6875:1;:12;6871:73;;;6931:1;6911:17;6923:1;6926;6911:11;:17::i;:::-;:21;;;;;;6904:28;;;;;;;6871:73;1309:19;6958:1;:12;6954:83;;;7024:1;7004:17;7016:1;7019;7004:11;:17::i;:::-;:21;;;;;;1260:8;6994:31;6987:38;;;;;;;6954:83;7047:6;;;;1432:36;7802:26;;;;;7853:24;7839:11;7932:8;;;1516;-1:-1:-1;;7918:8:0;;7900:27;7932:8;7899:42;;;;;7888:53;;7964:1;7960;:5;7956:1;:9;7952:13;;7976:9;1516:8;7993:1;7989;:5;7988:24;;;;;;;-1:-1:-1;8033:1:0;8045:217;1516:8;8078:6;;;8077:25;8073:29;;8142:1;8135:9;;8130:1;8126;:5;8125:19;;;;;;8121:23;;;;;8164:1;8159:6;8189:20;8184:25;;;;8180:71;;8230:5;;8180:71;8045:217;;;8299:1;8279:17;8291:1;8294;8279:11;:17::i;:::-;:21;;;;;;;6014:2294;-1:-1:-1;;;;;;;;;6014:2294:0:o;39334:619::-;39394:4;39862:20;;39705:66;39902:23;;;;;;:42;;-1:-1:-1;;39929:15:0;;;39334:619;-1:-1:-1;;39334:619:0:o;48082:216::-;48130:7;48150:37;;:::i;:::-;48190:14;;-1:-1:-1;;;;;48190:14:0;:31;48222:16;:14;:16::i;:::-;48190:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48190:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;48190:49:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;48190:49:0;;;;;;;;;48150:89;;48257:33;48282:7;48257:24;:33::i;49463:357::-;49511:7;49531:12;49546:38;:12;:27;;;:36;:38::i;:::-;49621:27;;49531:53;;-1:-1:-1;49595:12:0;;49610:39;;49531:53;;49610:39;:10;:39;:::i;:::-;49595:54;;49660:8;49671:27;49681:16;:14;:16::i;:::-;49671:5;;:27;:9;:27;:::i;:::-;49660:38;-1:-1:-1;49713:23:0;49719:16;:5;49729;49719:16;:9;:16;:::i;:::-;49713:1;;:23;:5;:23;:::i;:::-;49709:27;-1:-1:-1;49751:23:0;49757:16;:5;49767;49757:16;:9;:16;:::i;:::-;49751:1;;:23;:5;:23;:::i;:::-;49747:27;-1:-1:-1;49792:20:0;:8;49747:27;49798:1;49792:8;:5;:8;:::i;:20::-;49785:27;;;;;49463:357;:::o;77603:862::-;77717:12;:28;77713:179;;77874:7;;77713:179;77902:37;;:::i;:::-;77942:14;;-1:-1:-1;;;;;77942:14:0;:31;77974:16;:14;:16::i;:::-;77942:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;77942:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;77942:49:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;77942:49:0;;;;;;;;;77902:89;;78006:7;:12;;;78022:1;78006:17;78002:124;;;78108:7;;;78002:124;78162:12;:28;78142:48;;78138:176;;;78238:64;78260:7;78269:13;78284:17;78238:21;:64::i;:::-;78352:56;78374:7;78383:13;78398:9;78352:21;:56::i;:::-;78426:31;78444:12;78426:31;;;;;;;;;;;;;;;77603:862;;;;:::o;55931:238::-;55986:13;56012:9;56032;56061:11;:9;:11::i;:::-;56052:20;;-1:-1:-1;56052:20:0;-1:-1:-1;56091:6:0;;;;;:16;;-1:-1:-1;56101:6:0;;;56091:16;56083:39;;;;-1:-1:-1;;;56083:39:0;;;;;;;;;56140:21;56147:13;:1;56153:6;56147:13;:5;:13;:::i;:::-;56140:1;;:21;:6;:21;:::i;11693:160::-;11745:6;-1:-1:-1;;;;;11772:1:0;:25;;11764:54;;;;-1:-1:-1;;;11764:54:0;;;;;;;;3276:202;3332:6;3362:5;;;3387:6;;;;;;:16;;;3402:1;3397;:6;;3387:16;3386:38;;;;3413:1;3409;:5;:14;;;;;3422:1;3418;:5;3409:14;3378:71;;;;-1:-1:-1;;;3378:71:0;;;;;;;;4080:197;4137:8;4166:1;4162;:5;4158:65;;;4189:1;4188:2;;4184:6;;4210:1;4209:2;;4205:6;;4158:65;4268:1;4237:28;4249:12;4253:1;1108:8;4249:3;:12::i;:::-;4263:1;4237:11;:28::i;:::-;:32;;;;;;;4080:197;-1:-1:-1;;;4080:197:0:o;9117:173::-;9175:7;9207:5;;;9231:6;;;;9223:38;;;;-1:-1:-1;;;9223:38:0;;;;;;;;3888:125;3945:8;1108;3970:28;3982:9;3986:1;3989;3982:3;:9::i;:::-;1108:8;3970:11;:28::i;58875:239::-;58931:13;58957:9;58977;59006:11;:9;:11::i;:::-;58997:20;;-1:-1:-1;58997:20:0;-1:-1:-1;59036:6:0;;;;;:16;;-1:-1:-1;59046:6:0;;;59036:16;59028:39;;;;-1:-1:-1;;;59028:39:0;;;;;;;;;59085:21;59092:13;:1;59098:6;59092:13;:5;:13;:::i;72982:255::-;73076:6;73095:8;73106:44;:33;73131:7;73106:24;:33::i;:44::-;73095:55;;73165:45;73171:38;:12;:27;;;:36;:38::i;:::-;73165:1;;:45;:5;:45;:::i;5707:240::-;5771:6;5802:1;5798;:5;5790:49;;;;-1:-1:-1;;;5790:49:0;;;;;;;;;5859:1;5854;:6;5850:59;;5884:13;5888:1;5895;5891;:5;5884:3;:13::i;:::-;5877:20;;;;5850:59;5926:13;5930:1;5937;5933;:5;5926:3;:13::i;72604:297::-;72732:12;;;;72700:7;;72763:5;72755:49;;;;-1:-1:-1;;;72755:49:0;;;;;;;;;72815:9;72827:39;72858:7;72827:30;:39::i;:::-;72815:51;-1:-1:-1;72884:9:0;72815:51;72891:1;72884:9;:6;:9;:::i;49070:110::-;49145:27;;49070:110;:::o;78889:1270::-;79065:12;:28;79057:77;;;;-1:-1:-1;;;79057:77:0;;;;;;;;;79169:12;:28;79153:44;;;79145:88;;;;-1:-1:-1;;;79145:88:0;;;;;;;;;79273:12;:28;:44;;79269:698;;79370:12;:28;79334:16;;79353:57;;:46;;:12;;:46;:16;:46;:::i;:57::-;79334:76;;79425:10;79487:247;79527:9;79555:12;:27;;;79601:12;:24;;;79644:38;:12;:27;;;:36;:38::i;:::-;79487:21;:247::i;:::-;79451:27;79450:284;;;;;-1:-1:-1;79794:103:0;79859:23;79450:284;45610:5;79859:23;:7;:23;:::i;:::-;79794:42;;;:103;:46;:103;:::i;:::-;79749:42;:148;-1:-1:-1;;79749:12:0;79912:43;;;79269:698;80005:27;:43;;;80120:31;80143:7;80120:22;:31::i;:::-;80093:24;:58;-1:-1:-1;;;78889:1270:0:o;2041:536::-;2097:6;2341;2337:47;;-1:-1:-1;2371:1:0;2364:8;;2337:47;2404:1;-1:-1:-1;;2404:7:0;:27;;;;;-1:-1:-1;;;2415:1:0;:16;2404:27;2402:30;2394:67;;;;-1:-1:-1;;;2394:67:0;;;;;;;;;2485:5;;;2489:1;2485;:5;:1;2509:5;;;;;:10;2501:47;;;;-1:-1:-1;;;2501:47:0;;;;;;;;82782:10166;82986:9;83032:10;83082:1;83078;:5;83070:42;;;;-1:-1:-1;;;83070:42:0;;;;;;;;;83123:39;;:::i;:::-;83178:20;:2;83185:12;83178:20;:6;:20;:::i;:::-;83173:25;;83214:27;83222:18;83238:1;83222:9;;:15;;:18;;;;:::i;:::-;83214:2;;:27;:7;:27;:::i;:::-;83209:32;-1:-1:-1;83257:20:0;83209:32;83264:12;83257:20;:6;:20;:::i;:::-;83301:27;;83252:25;;-1:-1:-1;83301:49:0;;83334:15;83301:49;:32;:49;:::i;:::-;83288:62;;83377:26;;:48;;83409:15;83377:48;:31;:48;:::i;:::-;83361:13;;;:64;83447:10;;;83446:11;83440:17;;83436:9505;;83508:10;;;83507:11;83501:17;;83497:2114;;83545:39;83582:1;83545:32;83563:3;:13;;;83547:3;:10;;;83546:11;;83545:17;;:32;;;;:::i;:::-;:36;:39;:36;:39;:::i;:::-;83539:45;;83497:2114;;;83617:3;:13;;;83616:14;;83610:2;:20;83606:2005;;83680:10;;83660:49;;83680:10;83679:11;83692:2;83696:12;83660:18;:49::i;:::-;83651:6;;;:58;;;83736:10;;83734:25;;83736:10;83735:11;;;;;83734:25;:17;:25;:::i;:::-;83728:31;;83784:61;83792:52;83816:3;:6;;;83824:1;83827:2;83831:12;83792:23;:52::i;:::-;83784:3;;:61;:7;:61;:::i;:::-;83778:67;;83870:29;83878:20;83896:1;83878:3;:13;;;:17;;:20;;;;:::i;83606:2005::-;83931:3;:13;;;83925:2;:19;83921:1690;;83994:10;;83974:49;;83994:10;83993:11;84006:2;84010:12;83974:18;:49::i;:::-;83965:6;;;:58;84071:13;;;;84051:52;;84070:14;;84086:2;84090:12;84051:18;:52::i;:::-;84042:6;;;:61;84146:6;;;;84130:10;;84128:25;;84130:10;84129:11;;;;;84128:25;:17;:25;:::i;:::-;84122:31;;84178:66;84186:57;84210:3;:6;;;84218:3;:6;;;84226:2;84230:12;84186:23;:57::i;84178:66::-;84172:72;;84269:34;84277:25;84295:3;:6;;;84277:3;:13;;;:17;;:25;;;;:::i;83921:1690::-;84335:10;;84329:16;;84325:1286;;84395:10;;84375:49;;84395:10;84394:11;84407:2;84411:12;84375:18;:49::i;:::-;84366:6;;;:58;84472:13;;;;84452:52;;84471:14;;84487:2;84491:12;84452:18;:52::i;:::-;84443:6;;;:61;84551:13;;;;84532:51;;84566:2;84570:12;84532:18;:51::i;:::-;84523:6;;;:60;84626:6;;;;84610:10;;84608:25;;84610:10;84609:11;;;;;84608:25;:17;:25;:::i;:::-;84602:31;;84658:66;84666:57;84690:3;:6;;;84698:3;:6;;;84706:2;84710:12;84666:23;:57::i;84658:66::-;84652:72;;84749:61;84757:52;84781:3;:6;;;84789:1;84792:2;84796:12;84757:23;:52::i;84749:61::-;84743:67;;84835:53;84843:44;84861:25;84879:3;:6;;;84861:13;84872:1;84861:3;:6;;;:10;;:13;;;;:::i;:25::-;84843:13;;;;;:44;:17;:44;:::i;84325:1286::-;84958:10;;84938:49;;84958:10;84957:11;84970:2;84974:12;84938:18;:49::i;:::-;84929:6;;;:58;85035:13;;;;85015:52;;85034:14;;85050:2;85054:12;85015:18;:52::i;:::-;85006:6;;;:61;85114:13;;;;85095:51;;85129:2;85133:12;85095:18;:51::i;:::-;85086:6;;;:60;85193:10;;85174:48;;85205:2;85209:12;85174:18;:48::i;:::-;85165:6;;;:57;85265:6;;;;85249:10;;85247:25;;85249:10;85248:11;;;;;85247:25;:17;:25;:::i;:::-;85241:31;;85297:66;85305:57;85329:3;:6;;;85337:3;:6;;;85345:2;85349:12;85305:23;:57::i;85297:66::-;85291:72;;85388:66;85396:57;85420:3;:6;;;85428:3;:6;;;85436:2;85440:12;85396:23;:57::i;85388:66::-;85382:72;;85479:38;85487:29;85502:13;85508:3;:6;;;85502:1;:5;;:13;;;;:::i;:::-;85487:10;;;:29;:14;:29;:::i;85479:38::-;85473:44;;85542:53;85550:44;85568:25;85586:3;:6;;;85568:13;85579:1;85568:3;:6;;;:10;;:13;;;;:::i;85542:53::-;85536:59;;84325:1286;83436:9505;;;85639:3;:13;;;85638:14;;85632:2;:20;85628:7313;;85703:10;;;85702:11;85696:17;;85692:1760;;85763:10;;85743:49;;85763:10;85762:11;85775:2;85779:12;85743:18;:49::i;:::-;85734:6;;;:58;;;85817:52;;85841:1;;85852:2;85856:12;85817:23;:52::i;:::-;85811:58;;85894:41;85902:32;85920:13;85926:3;:6;;;85920:1;:5;;:13;;;;:::i;:::-;85904:10;;;85903:11;;85902:32;:17;:32;:::i;85692:1760::-;86022:3;:13;;;86021:14;;86015:2;:20;86011:1441;;86062:47;86086:1;86089;86092:2;86096:12;86062:23;:47::i;86011:1441::-;86195:3;:13;;;86189:2;:19;86185:1267;;86238:52;86258:3;:13;;;86257:14;;86273:2;86277:12;86238:18;:52::i;:::-;86229:6;;;:61;;;86315:52;;86339:1;;86350:2;86354:12;86315:23;:52::i;86185:1267::-;86458:10;;86452:16;;86448:1004;;86498:52;86518:3;:13;;;86517:14;;86533:2;86537:12;86498:18;:52::i;:::-;86489:6;;;:61;86597:13;;;;86578:51;;86612:2;86616:12;86578:18;:51::i;:::-;86569:6;;;:60;86681:6;;;;86654:52;;86678:1;;86689:2;86693:12;86654:23;:52::i;86448:1004::-;86920:52;86940:3;:13;;;86939:14;;86955:2;86959:12;86920:18;:52::i;:::-;86911:6;;;:61;87019:13;;;;87000:51;;87034:2;87038:12;87000:18;:51::i;:::-;86991:6;;;:60;87098:10;;87079:48;;87110:2;87114:12;87079:18;:48::i;:::-;87070:6;;;:57;87179:6;;;;87152:52;;87176:1;;87187:2;87191:12;87152:23;:52::i;85628:7313::-;87479:3;:13;;;87473:2;:19;87469:5472;;87543:10;;;87542:11;87536:17;;87532:1408;;87583:52;87603:3;:13;;;87602:14;;87618:2;87622:12;87583:18;:52::i;:::-;87574:6;;;:61;87683:10;;87663:49;;87683:10;87682:11;87695:2;87699:12;87663:18;:49::i;:::-;87654:6;;;:58;;;87761:6;;;;87737:57;;87777:2;87781:12;87737:23;:57::i;:::-;87731:63;;87819:41;87827:32;87845:13;87851:3;:6;;;87845:1;:5;;:13;;;;:::i;87819:41::-;87813:47;;87885:41;87893:32;87911:13;87917:3;:6;;;87911:1;:5;;:13;;;;:::i;87532:1408::-;87959:3;:13;;;87958:14;;87952:2;:20;87948:992;;88002:52;88022:3;:13;;;88021:14;;88037:2;88041:12;88002:18;:52::i;:::-;87993:6;;;:61;;;88079:52;;88111:1;88114:2;88118:12;88079:23;:52::i;87948:992::-;88229:3;:13;;;88223:2;:19;88219:721;;88269:1;88263:7;;88219:721;;;88302:10;;88296:16;;88292:648;;88342:51;88361:3;:13;;;88376:2;88380:12;88342:18;:51::i;:::-;88333:6;;;:60;;;88418:52;;88450:1;88453:2;88457:12;88418:23;:52::i;:::-;88412:58;;88495:41;88503:32;88521:13;88527:3;:6;;;88521:1;:5;;:13;;;;:::i;88292:648::-;88586:51;88605:3;:13;;;88620:2;88624:12;88586:18;:51::i;:::-;88577:6;;;:60;88684:10;;88665:48;;88696:2;88700:12;88665:18;:48::i;:::-;88656:6;;;:57;;;88762:6;;;;88738:57;;88778:2;88782:12;88738:23;:57::i;:::-;88732:63;;88820:38;88828:29;88843:13;88849:3;:6;;;88843:1;:5;;:13;;;;:::i;88820:38::-;88814:44;;88883:41;88891:32;88909:13;88915:3;:6;;;88909:1;:5;;:13;;;;:::i;87469:5472::-;88967:10;;88961:16;;88957:3984;;89028:10;;;89027:11;89021:17;;89017:1759;;89068:51;89087:3;:13;;;89102:2;89106:12;89068:18;:51::i;:::-;89059:6;;;:60;89167:13;;;;89147:52;;89166:14;;89182:2;89186:12;89147:18;:52::i;:::-;89138:6;;;:61;89247:10;;89227:49;;89247:10;89246:11;89259:2;89263:12;89227:18;:49::i;:::-;89218:6;;;:58;89328:6;;;;89301:52;;89325:1;;89336:2;89340:12;89301:23;:52::i;:::-;89295:58;;89378:66;89386:57;89410:3;:6;;;89418:3;:6;;;89426:2;89430:12;89386:23;:57::i;89378:66::-;89372:72;;89469:41;89477:32;89495:13;89501:3;:6;;;89495:1;:5;;:13;;;;:::i;89469:41::-;89463:47;;89535:53;89543:44;89561:25;89579:3;:6;;;89561:13;89567:3;:6;;;89561:1;:5;;:13;;;;:::i;89017:1759::-;89621:3;:13;;;89620:14;;89614:2;:20;89610:1166;;89664:51;89683:3;:13;;;89698:2;89702:12;89664:18;:51::i;:::-;89655:6;;;:60;89763:13;;;;89743:52;;89762:14;;89778:2;89782:12;89743:18;:52::i;:::-;89734:6;;;:61;89847:6;;;;89820:52;;89844:1;;89855:2;89859:12;89820:23;:52::i;:::-;89814:58;;89897:61;89905:52;89929:3;:6;;;89937:1;89940:2;89944:12;89905:23;:52::i;89610:1166::-;90068:3;:13;;;90062:2;:19;90058:718;;90111:51;90130:3;:13;;;90145:2;90149:12;90111:18;:51::i;:::-;90102:6;;;:60;;;90187:52;;90211:1;;90222:2;90226:12;90187:23;:52::i;:::-;90181:58;;90264:34;90272:25;90290:3;:6;;;90272:3;:13;;;:17;;:25;;;;:::i;90058:718::-;90330:10;;90324:16;;90320:456;;90367:47;90391:1;90394;90397:2;90401:12;90367:23;:47::i;:::-;90361:53;;90439:29;90447:20;90465:1;90447:3;:13;;;:17;;:20;;;;:::i;90320:456::-;90537:10;;90518:48;;90549:2;90553:12;90518:18;:48::i;:::-;90509:6;;;:57;;;90591:52;;90615:1;;90626:2;90630:12;90591:23;:52::i;:::-;90585:58;;90668:38;90676:29;90691:13;90697:3;:6;;;90691:1;:5;;:13;;;;:::i;90668:38::-;90662:44;;90731:29;90739:20;90757:1;90739:3;:13;;;:17;;:20;;;;:::i;88957:3984::-;90842:10;;;90841:11;90835:17;;90831:2099;;90901:10;;90882:48;;90913:2;90917:12;90882:18;:48::i;:::-;90873:6;;;:57;90977:13;;;;90958:51;;90992:2;90996:12;90958:18;:51::i;:::-;90949:6;;;:60;91057:13;;;;91037:52;;91056:14;;91072:2;91076:12;91037:18;:52::i;:::-;91028:6;;;:61;91137:10;;91117:49;;91137:10;91136:11;91149:2;91153:12;91117:18;:49::i;:::-;91108:6;;;:58;91206:6;;;;91191:10;;:22;;;:14;:22;:::i;:::-;91185:28;;91238:66;91246:57;91270:3;:6;;;91278:3;:6;;;91286:2;91290:12;91246:23;:57::i;91238:66::-;91232:72;;91329:66;91337:57;91361:3;:6;;;91369:3;:6;;;91377:2;91381:12;91337:23;:57::i;91329:66::-;91323:72;;91420:41;91428:32;91446:13;91452:3;:6;;;91446:1;:5;;:13;;;;:::i;91420:41::-;91414:47;;91486:53;91494:44;91512:25;91530:3;:6;;;91512:13;91518:3;:6;;;91512:1;:5;;:13;;;;:::i;90831:2099::-;91572:3;:13;;;91571:14;;91565:2;:20;91561:1369;;91634:10;;91615:48;;91646:2;91650:12;91615:18;:48::i;:::-;91606:6;;;:57;91710:13;;;;91691:51;;91725:2;91729:12;91691:18;:51::i;:::-;91682:6;;;:60;91790:13;;;;91770:52;;91789:14;;91805:2;91809:12;91770:18;:52::i;:::-;91761:6;;;:61;91862:6;;;;91847:10;;:22;;;:14;:22;:::i;:::-;91841:28;;91894:66;91902:57;91926:3;:6;;;91934:3;:6;;;91942:2;91946:12;91902:23;:57::i;91894:66::-;91888:72;;91985:61;91993:52;92017:3;:6;;;92025:1;92028:2;92032:12;91993:23;:52::i;91561:1369::-;92156:3;:13;;;92150:2;:19;92146:784;;92218:10;;92199:48;;92230:2;92234:12;92199:18;:48::i;:::-;92190:6;;;:57;92294:13;;;;92275:51;;92309:2;92313:12;92275:18;:51::i;:::-;92266:6;;;:60;92366:6;;;;92351:10;;:22;;;:14;:22;:::i;:::-;92345:28;;92398:66;92406:57;92430:3;:6;;;92438:3;:6;;;92446:2;92450:12;92406:23;:57::i;92398:66::-;92392:72;;92489:35;92497:26;92516:3;:6;;;92515:7;;92497:3;:13;;;:17;;:26;;;;:::i;92146:784::-;92556:10;;92550:16;;92546:384;;92615:10;;92596:48;;92627:2;92631:12;92596:18;:48::i;:::-;92587:6;;;:57;;;92669:10;;:22;;;:14;:22;:::i;:::-;92663:28;;92716:61;92724:52;92748:3;:6;;;92756:1;92759:2;92763:12;92724:23;:52::i;92546:384::-;92893:13;;;;92878:10;;:36;;92912:1;;92878:29;;;:14;:29;:::i;:36::-;92872:42;;92546:384;82782:10166;;;;;;;;:::o;2827:241::-;2883:6;2910;2902:36;;;;-1:-1:-1;;;2902:36:0;;;;;;;;;2959:1;-1:-1:-1;;2959:7:0;:27;;;;;-1:-1:-1;;;2970:1:0;:16;2959:27;2957:30;2949:61;;;;-1:-1:-1;;;2949:61:0;;;;;;;;;3023:8;3038:1;3034;:5;;;;;;;2827:241;-1:-1:-1;;;;2827:241:0:o;5207:331::-;5265:8;5299:1;5294;:6;;5286:45;;;;-1:-1:-1;;;5286:45:0;;;;;;;;;5350:1;5346;:5;:21;;1108:8;5346:21;;;5359:1;5346:21;5342:25;-1:-1:-1;5390:1:0;5385:6;;;;5380:151;5393:6;;5380:151;;5428:10;5433:1;5436;5428:4;:10::i;:::-;5424:14;-1:-1:-1;5463:1:0;5459;:5;:10;5455:65;;5494:10;5499:1;5502;5494:4;:10::i;:::-;5490:14;;5455:65;5406:1;5401:6;;;;5380:151;;80363:628;80531:8;80603:12;80598:1;:17;;80590:60;;;;-1:-1:-1;;;80590:60:0;;;;;;;;;80665:19;:1;80671:12;80665:19;:5;:19;:::i;:::-;80661:23;-1:-1:-1;80699:28:0;80706:20;:2;80713:12;80706:20;:6;:20;:::i;:::-;80699:1;;:28;:6;:28;:::i;:::-;80695:32;;80750:1;80746;:5;80738:48;;;;-1:-1:-1;;;80738:48:0;;;;;;;;;80809:19;:17;:19::i;:::-;80805:1;:23;80797:66;;;;-1:-1:-1;;;80797:66:0;;;;;;;;;80878:7;:1;:5;:7::i;:::-;80874:11;;80900:19;80907:11;;80900:1;:6;;:19;;;;:::i;:::-;80896:23;;80964:19;:17;:19::i;:::-;80934:27;80941:19;:17;:19::i;:::-;80934:1;;:27;:6;:27;:::i;:::-;:49;;;;81250:407;81401:8;81435:1;81430;:6;;81422:37;;;;-1:-1:-1;;;81422:37:0;;;;;;;;;81474:20;:2;81481:12;81474:20;:6;:20;:::i;:::-;81470:24;;81509:50;81516:42;81539:18;81555:1;81539:9;;:15;;:18;;;;:::i;:::-;81516:9;;:18;;81532:1;81516:18;:15;:18;:::i;:42::-;81509:1;;:50;:6;:50;:::i;:::-;81581:19;;81505:54;;-1:-1:-1;81574:27:0;;81505:54;;81574:27;:6;:27;:::i;:::-;81570:31;-1:-1:-1;81616:33:0;81622:26;81639:8;:1;81645;81639:8;:5;:8;:::i;:::-;81622:12;;:26;:16;:26;:::i;:::-;81616:1;;:33;:5;:33;:::i;1627:76::-;1108:8;1627:76;:::o;8462:208::-;8519:6;8551:1;8546;:6;;8538:35;;;;-1:-1:-1;;;8538:35:0;;;;;;;;;8596:1;8592;:5;8584:33;;;;-1:-1:-1;;;8584:33:0;;;;;;;;;8661:1;8656;8636:17;8640:9;8644:1;8647;8640:3;:9::i;:::-;8651:1;8636:3;:17::i;:::-;:21;;;;;;8635:27;;8462:208;-1:-1:-1;;;8462:208:0:o;45453:47523::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;-1:-1:-1;45453:47523:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5:130:-1:-;72:20;;97:33;72:20;97:33;;142:134;220:13;;238:33;220:13;238:33;;283:128;358:13;;376:30;358:13;376:30;;418:130;485:20;;510:33;485:20;510:33;;555:152;642:13;;660:42;642:13;660:42;;1012:132;1089:13;;1107:32;1089:13;1107:32;;1187:1170;;1318:4;1306:9;1301:3;1297:19;1293:30;1290:2;;;1336:1;1333;1326:12;1290:2;1354:20;1369:4;1354:20;;;1345:29;-1:-1;1424:1;1456:69;1521:3;1501:9;1456:69;;;1431:95;;-1:-1;1587:2;1620:60;1676:3;1652:22;;;1620:60;;;1613:4;1606:5;1602:16;1595:86;1547:145;1748:2;1781:60;1837:3;1828:6;1817:9;1813:22;1781:60;;;1774:4;1767:5;1763:16;1756:86;1702:151;1914:2;1947:59;2002:3;1993:6;1982:9;1978:22;1947:59;;;1940:4;1933:5;1929:16;1922:85;1863:155;2080:3;2114:59;2169:3;2160:6;2149:9;2145:22;2114:59;;;2107:4;2100:5;2096:16;2089:85;2028:157;2242:3;2276:59;2331:3;2322:6;2311:9;2307:22;2276:59;;;2269:4;2262:5;2258:16;2251:85;2195:152;1284:1073;;;;;2407:1543;;2545:6;2533:9;2528:3;2524:19;2520:32;2517:2;;;2565:1;2562;2555:12;2517:2;2583:22;2598:6;2583:22;;;2574:31;-1:-1;2668:1;2700:60;2756:3;2736:9;2700:60;;;2675:86;;-1:-1;2839:2;2872:60;2928:3;2904:22;;;2872:60;;;2865:4;2858:5;2854:16;2847:86;2782:162;3012:2;3045:60;3101:3;3092:6;3081:9;3077:22;3045:60;;;3038:4;3031:5;3027:16;3020:86;2954:163;3178:2;3211:60;3267:3;3258:6;3247:9;3243:22;3211:60;;;3204:4;3197:5;3193:16;3186:86;3127:156;3344:3;3378:59;3433:3;3424:6;3413:9;3409:22;3378:59;;;3371:4;3364:5;3360:16;3353:85;3293:156;3510:3;3544:59;3599:3;3590:6;3579:9;3575:22;3544:59;;;3537:4;3530:5;3526:16;3519:85;3459:156;3668:3;3702:60;3758:3;3749:6;3738:9;3734:22;3702:60;;;3695:4;3688:5;3684:16;3677:86;3625:149;3834:3;3868:60;3924:3;3915:6;3904:9;3900:22;3868:60;;;3861:4;3854:5;3850:16;3843:86;3784:156;2511:1439;;;;;4235:263;;4350:2;4338:9;4329:7;4325:23;4321:32;4318:2;;;4366:1;4363;4356:12;4318:2;4401:1;4418:64;4474:7;4454:9;4418:64;;4505:617;;;;;4660:3;4648:9;4639:7;4635:23;4631:33;4628:2;;;4677:1;4674;4667:12;4628:2;4712:1;4729:53;4774:7;4754:9;4729:53;;;4719:63;;4691:97;4819:2;4837:53;4882:7;4873:6;4862:9;4858:22;4837:53;;;4827:63;;4798:98;4927:2;4945:53;4990:7;4981:6;4970:9;4966:22;4945:53;;;4935:63;;4906:98;5035:2;5053:53;5098:7;5089:6;5078:9;5074:22;5053:53;;;5043:63;;5014:98;4622:500;;;;;;;;5129:257;;5241:2;5229:9;5220:7;5216:23;5212:32;5209:2;;;5257:1;5254;5247:12;5209:2;5292:1;5309:61;5362:7;5342:9;5309:61;;5393:364;;;5513:2;5501:9;5492:7;5488:23;5484:32;5481:2;;;5529:1;5526;5519:12;5481:2;5564:1;5581:53;5626:7;5606:9;5581:53;;;5571:63;;5543:97;5671:2;5689:52;5733:7;5724:6;5713:9;5709:22;5689:52;;;5679:62;;5650:97;5475:282;;;;;;5764:285;;5890:2;5878:9;5869:7;5865:23;5861:32;5858:2;;;5906:1;5903;5896:12;5858:2;5941:1;5958:75;6025:7;6005:9;5958:75;;6056:261;;6170:2;6158:9;6149:7;6145:23;6141:32;6138:2;;;6186:1;6183;6176:12;6138:2;6221:1;6238:63;6293:7;6273:9;6238:63;;6324:326;;6470:3;6458:9;6449:7;6445:23;6441:33;6438:2;;;6487:1;6484;6477:12;6438:2;6522:1;6539:95;6626:7;6606:9;6539:95;;6657:340;;6810:3;6798:9;6789:7;6785:23;6781:33;6778:2;;;6827:1;6824;6817:12;6778:2;6862:1;6879:102;6973:7;6953:9;6879:102;;7004:241;;7108:2;7096:9;7087:7;7083:23;7079:32;7076:2;;;7124:1;7121;7114:12;7076:2;7159:1;7176:53;7221:7;7201:9;7176:53;;7895:399;;;8027:2;8015:9;8006:7;8002:23;7998:32;7995:2;;;8043:1;8040;8033:12;7995:2;8078:1;8095:64;8151:7;8131:9;8095:64;;;8085:74;;8057:108;8196:2;8214:64;8270:7;8261:6;8250:9;8246:22;8214:64;;8301:491;;;;8439:2;8427:9;8418:7;8414:23;8410:32;8407:2;;;8455:1;8452;8445:12;8407:2;8490:1;8507:53;8552:7;8532:9;8507:53;;;8497:63;;8469:97;8597:2;8615:53;8660:7;8651:6;8640:9;8636:22;8615:53;;;8605:63;;8576:98;8705:2;8723:53;8768:7;8759:6;8748:9;8744:22;8723:53;;;8713:63;;8684:98;8401:391;;;;;;8799:617;;;;;8954:3;8942:9;8933:7;8929:23;8925:33;8922:2;;;8971:1;8968;8961:12;8922:2;9006:1;9023:53;9068:7;9048:9;9023:53;;9423:142;9514:45;9553:5;9514:45;;;9509:3;9502:58;9496:69;;;9572:137;9671:32;9697:5;9671:32;;9836:170;9941:59;9994:5;9941:59;;10359:140;10449:44;10487:5;10449:44;;10506:100;10577:23;10594:5;10577:23;;10731:313;;10891:67;10955:2;10950:3;10891:67;;;-1:-1;;;10971:36;;11035:2;11026:12;;10877:167;-1:-1;;10877:167;11053:311;;11213:67;11277:2;11272:3;11213:67;;;-1:-1;;;11293:34;;11355:2;11346:12;;11199:165;-1:-1;;11199:165;11373:320;;11533:67;11597:2;11592:3;11533:67;;;-1:-1;;;11613:43;;11684:2;11675:12;;11519:174;-1:-1;;11519:174;11702:313;;11862:67;11926:2;11921:3;11862:67;;;-1:-1;;;11942:36;;12006:2;11997:12;;11848:167;-1:-1;;11848:167;12024:330;;12184:67;12248:2;12243:3;12184:67;;;12284:32;12264:53;;12345:2;12336:12;;12170:184;-1:-1;;12170:184;12363:319;;12523:67;12587:2;12582:3;12523:67;;;-1:-1;;;12603:42;;12673:2;12664:12;;12509:173;-1:-1;;12509:173;12691:315;;12851:67;12915:2;12910:3;12851:67;;;-1:-1;;;12931:38;;12997:2;12988:12;;12837:169;-1:-1;;12837:169;13015:313;;13175:67;13239:2;13234:3;13175:67;;;-1:-1;;;13255:36;;13319:2;13310:12;;13161:167;-1:-1;;13161:167;13337:371;;13497:67;13561:2;13556:3;13497:67;;;13597:34;13577:55;;-1:-1;;;13661:2;13652:12;;13645:26;13699:2;13690:12;;13483:225;-1:-1;;13483:225;13717:311;;13877:67;13941:2;13936:3;13877:67;;;-1:-1;;;13957:34;;14019:2;14010:12;;13863:165;-1:-1;;13863:165;14037:322;;14197:67;14261:2;14256:3;14197:67;;;-1:-1;;;14277:45;;14350:2;14341:12;;14183:176;-1:-1;;14183:176;14368:319;;14528:67;14592:2;14587:3;14528:67;;;-1:-1;;;14608:42;;14678:2;14669:12;;14514:173;-1:-1;;14514:173;14696:320;;14856:67;14920:2;14915:3;14856:67;;;-1:-1;;;14936:43;;15007:2;14998:12;;14842:174;-1:-1;;14842:174;15025:318;;15185:67;15249:2;15244:3;15185:67;;;-1:-1;;;15265:41;;15334:2;15325:12;;15171:172;-1:-1;;15171:172;15352:311;;15512:67;15576:2;15571:3;15512:67;;;-1:-1;;;15592:34;;15654:2;15645:12;;15498:165;-1:-1;;15498:165;15672:314;;15832:67;15896:2;15891:3;15832:67;;;-1:-1;;;15912:37;;15977:2;15968:12;;15818:168;-1:-1;;15818:168;15995:323;;16155:67;16219:2;16214:3;16155:67;;;16255:25;16235:46;;16309:2;16300:12;;16141:177;-1:-1;;16141:177;16327:319;;16487:67;16551:2;16546:3;16487:67;;;-1:-1;;;16567:42;;16637:2;16628:12;;16473:173;-1:-1;;16473:173;16655:325;;16815:67;16879:2;16874:3;16815:67;;;16915:27;16895:48;;16971:2;16962:12;;16801:179;-1:-1;;16801:179;16989:331;;17149:67;17213:2;17208:3;17149:67;;;17249:33;17229:54;;17311:2;17302:12;;17135:185;-1:-1;;17135:185;17329:326;;17489:67;17553:2;17548:3;17489:67;;;17589:28;17569:49;;17646:2;17637:12;;17475:180;-1:-1;;17475:180;17664:317;;17824:67;17888:2;17883:3;17824:67;;;-1:-1;;;17904:40;;17972:2;17963:12;;17810:171;-1:-1;;17810:171;17990:317;;18150:67;18214:2;18209:3;18150:67;;;-1:-1;;;18230:40;;18298:2;18289:12;;18136:171;-1:-1;;18136:171;18316:330;;18476:67;18540:2;18535:3;18476:67;;;18576:32;18556:53;;18637:2;18628:12;;18462:184;-1:-1;;18462:184;18655:317;;18815:67;18879:2;18874:3;18815:67;;;-1:-1;;;18895:40;;18963:2;18954:12;;18801:171;-1:-1;;18801:171;18981:379;;19141:67;19205:2;19200:3;19141:67;;;19241:34;19221:55;;-1:-1;;;19305:2;19296:12;;19289:34;19351:2;19342:12;;19127:233;-1:-1;;19127:233;19369:310;;19529:67;19593:2;19588:3;19529:67;;;-1:-1;;;19609:33;;19670:2;19661:12;;19515:164;-1:-1;;19515:164;19688:332;;19848:67;19912:2;19907:3;19848:67;;;19948:34;19928:55;;20011:2;20002:12;;19834:186;-1:-1;;19834:186;20029:318;;20189:67;20253:2;20248:3;20189:67;;;-1:-1;;;20269:41;;20338:2;20329:12;;20175:172;-1:-1;;20175:172;20356:331;;20516:67;20580:2;20575:3;20516:67;;;20616:33;20596:54;;20678:2;20669:12;;20502:185;-1:-1;;20502:185;20696:310;;20856:67;20920:2;20915:3;20856:67;;;-1:-1;;;20936:33;;20997:2;20988:12;;20842:164;-1:-1;;20842:164;21015:310;;21175:67;21239:2;21234:3;21175:67;;;-1:-1;;;21255:33;;21316:2;21307:12;;21161:164;-1:-1;;21161:164;21334:321;;21494:67;21558:2;21553:3;21494:67;;;-1:-1;;;21574:44;;21646:2;21637:12;;21480:175;-1:-1;;21480:175;21664:316;;21824:67;21888:2;21883:3;21824:67;;;-1:-1;;;21904:39;;21971:2;21962:12;;21810:170;-1:-1;;21810:170;21989:308;;22149:66;22213:1;22208:3;22149:66;;;-1:-1;;;22228:32;;22288:2;22279:12;;22135:162;-1:-1;;22135:162;22306:319;;22466:67;22530:2;22525:3;22466:67;;;-1:-1;;;22546:42;;22616:2;22607:12;;22452:173;-1:-1;;22452:173;22634:331;;22794:67;22858:2;22853:3;22794:67;;;22894:33;22874:54;;22956:2;22947:12;;22780:185;-1:-1;;22780:185;22974:324;;23134:67;23198:2;23193:3;23134:67;;;23234:26;23214:47;;23289:2;23280:12;;23120:178;-1:-1;;23120:178;23307:316;;23467:67;23531:2;23526:3;23467:67;;;-1:-1;;;23547:39;;23614:2;23605:12;;23453:170;-1:-1;;23453:170;23632:312;;23792:67;23856:2;23851:3;23792:67;;;-1:-1;;;23872:35;;23935:2;23926:12;;23778:166;-1:-1;;23778:166;23953:324;;24113:67;24177:2;24172:3;24113:67;;;24213:26;24193:47;;24268:2;24259:12;;24099:178;-1:-1;;24099:178;24286:320;;24446:67;24510:2;24505:3;24446:67;;;-1:-1;;;24526:43;;24597:2;24588:12;;24432:174;-1:-1;;24432:174;24615:314;;24775:67;24839:2;24834:3;24775:67;;;-1:-1;;;24855:37;;24920:2;24911:12;;24761:168;-1:-1;;24761:168;24938:322;;25098:67;25162:2;25157:3;25098:67;;;-1:-1;;;25178:45;;25251:2;25242:12;;25084:176;-1:-1;;25084:176;25269:308;;25429:66;25493:1;25488:3;25429:66;;;-1:-1;;;25508:32;;25568:2;25559:12;;25415:162;-1:-1;;25415:162;25586:330;;25746:67;25810:2;25805:3;25746:67;;;25846:32;25826:53;;25907:2;25898:12;;25732:184;-1:-1;;25732:184;26005:1168;26245:23;;26172:4;26163:14;;;26274:63;26167:3;26245:23;26274:63;;;26192:151;26426:4;26419:5;26415:16;26409:23;26438:63;26495:4;26490:3;26486:14;26472:12;26438:63;;;26353:154;26584:4;26577:5;26573:16;26567:23;26596:61;26651:4;26646:3;26642:14;26628:12;26596:61;;;26517:146;26750:4;26743:5;26739:16;26733:23;26762:63;26819:4;26814:3;26810:14;26796:12;26762:63;;;26673:158;26916:4;26909:5;26905:16;26899:23;26928:61;26983:4;26978:3;26974:14;26960:12;26928:61;;;26841:154;27079:4;27072:5;27068:16;27062:23;27091:61;27146:4;27141:3;27137:14;27123:12;27091:61;;27247:1005;27477:23;;27400:4;27391:14;;;27506:63;27395:3;27477:23;27506:63;;;27420:155;27655:4;27648:5;27644:16;27638:23;27667:61;27722:4;27717:3;27713:14;27699:12;27667:61;;;27585:149;27817:4;27810:5;27806:16;27800:23;27829:61;27884:4;27879:3;27875:14;27861:12;27829:61;;;27744:152;27979:4;27972:5;27968:16;27962:23;27991:63;28048:4;28043:3;28039:14;28025:12;27991:63;;;27906:154;28158:4;28151:5;28147:16;28141:23;28170:61;28225:4;28220:3;28216:14;28202:12;28170:61;;28326:1357;28558:23;;28476:4;28467:14;;;28607:55;28558:23;28607:55;;;28668:63;28720:3;28702:12;28668:63;;;-1:-1;;28804:4;28793:16;;28787:23;28836:54;28787:23;28836:54;;;28896:61;28951:4;28946:3;28942:14;28928:12;28896:61;;;-1:-1;;29033:4;29022:16;;29016:23;29065:54;29016:23;29065:54;;;29125:61;29180:4;29175:3;29171:14;29157:12;29125:61;;;-1:-1;;29262:4;29251:16;;29245:23;29294:55;29245:23;29294:55;;;29355:63;29412:4;29407:3;29403:14;29389:12;29355:63;;;-1:-1;;29509:4;29498:16;;29492:23;29541:54;29492:23;29541:54;;;29601:61;29656:4;29651:3;29647:14;29633:12;29601:61;;29920:213;30038:2;30023:18;;30052:71;30027:9;30096:6;30052:71;;30140:229;30266:2;30251:18;;30280:79;30255:9;30332:6;30280:79;;30376:356;30538:2;30523:18;;30552:87;30527:9;30612:6;30552:87;;;30650:72;30718:2;30707:9;30703:18;30694:6;30650:72;;30739:340;30893:2;30878:18;;30907:79;30882:9;30959:6;30907:79;;31086:451;31268:2;31253:18;;31282:71;31257:9;31326:6;31282:71;;;31364:80;31440:2;31429:9;31425:18;31416:6;31364:80;;;31455:72;31523:2;31512:9;31508:18;31499:6;31455:72;;31544:673;31781:3;31766:19;;31796:71;31770:9;31840:6;31796:71;;;31878:72;31946:2;31935:9;31931:18;31922:6;31878:72;;;31961:79;32036:2;32025:9;32021:18;32012:6;31961:79;;;32051:72;32119:2;32108:9;32104:18;32095:6;32051:72;;;32134:73;32202:3;32191:9;32187:19;32178:6;32134:73;;;31752:465;;;;;;;;;32224:435;32398:2;32383:18;;32412:71;32387:9;32456:6;32412:71;;;32494:72;32562:2;32551:9;32547:18;32538:6;32494:72;;32997:257;33137:2;33122:18;;33151:93;33126:9;33217:6;33151:93;;33781:227;33906:2;33891:18;;33920:78;33895:9;33971:6;33920:78;;34015:209;34131:2;34116:18;;34145:69;34120:9;34187:6;34145:69;;34231:407;34422:2;34436:47;;;34407:18;;34497:131;34407:18;34497:131;;34645:407;34836:2;34850:47;;;34821:18;;34911:131;34821:18;34911:131;;35059:407;35250:2;35264:47;;;35235:18;;35325:131;35235:18;35325:131;;35473:407;35664:2;35678:47;;;35649:18;;35739:131;35649:18;35739:131;;35887:407;36078:2;36092:47;;;36063:18;;36153:131;36063:18;36153:131;;36301:407;36492:2;36506:47;;;36477:18;;36567:131;36477:18;36567:131;;36715:407;36906:2;36920:47;;;36891:18;;36981:131;36891:18;36981:131;;37129:407;37320:2;37334:47;;;37305:18;;37395:131;37305:18;37395:131;;37543:407;37734:2;37748:47;;;37719:18;;37809:131;37719:18;37809:131;;37957:407;38148:2;38162:47;;;38133:18;;38223:131;38133:18;38223:131;;38371:407;38562:2;38576:47;;;38547:18;;38637:131;38547:18;38637:131;;38785:407;38976:2;38990:47;;;38961:18;;39051:131;38961:18;39051:131;;39199:407;39390:2;39404:47;;;39375:18;;39465:131;39375:18;39465:131;;39613:407;39804:2;39818:47;;;39789:18;;39879:131;39789:18;39879:131;;40027:407;40218:2;40232:47;;;40203:18;;40293:131;40203:18;40293:131;;40441:407;40632:2;40646:47;;;40617:18;;40707:131;40617:18;40707:131;;40855:407;41046:2;41060:47;;;41031:18;;41121:131;41031:18;41121:131;;41269:407;41460:2;41474:47;;;41445:18;;41535:131;41445:18;41535:131;;41683:407;41874:2;41888:47;;;41859:18;;41949:131;41859:18;41949:131;;42097:407;42288:2;42302:47;;;42273:18;;42363:131;42273:18;42363:131;;42511:407;42702:2;42716:47;;;42687:18;;42777:131;42687:18;42777:131;;42925:407;43116:2;43130:47;;;43101:18;;43191:131;43101:18;43191:131;;43339:407;43530:2;43544:47;;;43515:18;;43605:131;43515:18;43605:131;;43753:407;43944:2;43958:47;;;43929:18;;44019:131;43929:18;44019:131;;44167:407;44358:2;44372:47;;;44343:18;;44433:131;44343:18;44433:131;;44581:407;44772:2;44786:47;;;44757:18;;44847:131;44757:18;44847:131;;44995:407;45186:2;45200:47;;;45171:18;;45261:131;45171:18;45261:131;;45409:407;45600:2;45614:47;;;45585:18;;45675:131;45585:18;45675:131;;45823:407;46014:2;46028:47;;;45999:18;;46089:131;45999:18;46089:131;;46237:407;46428:2;46442:47;;;46413:18;;46503:131;46413:18;46503:131;;46651:407;46842:2;46856:47;;;46827:18;;46917:131;46827:18;46917:131;;47065:407;47256:2;47270:47;;;47241:18;;47331:131;47241:18;47331:131;;47479:407;47670:2;47684:47;;;47655:18;;47745:131;47655:18;47745:131;;47893:407;48084:2;48098:47;;;48069:18;;48159:131;48069:18;48159:131;;48307:407;48498:2;48512:47;;;48483:18;;48573:131;48483:18;48573:131;;48721:407;48912:2;48926:47;;;48897:18;;48987:131;48897:18;48987:131;;49135:407;49326:2;49340:47;;;49311:18;;49401:131;49311:18;49401:131;;49549:407;49740:2;49754:47;;;49725:18;;49815:131;49725:18;49815:131;;49963:407;50154:2;50168:47;;;50139:18;;50229:131;50139:18;50229:131;;50377:407;50568:2;50582:47;;;50553:18;;50643:131;50553:18;50643:131;;50791:407;50982:2;50996:47;;;50967:18;;51057:131;50967:18;51057:131;;51205:407;51396:2;51410:47;;;51381:18;;51471:131;51381:18;51471:131;;51619:407;51810:2;51824:47;;;51795:18;;51885:131;51795:18;51885:131;;52033:407;52224:2;52238:47;;;52209:18;;52299:131;52209:18;52299:131;;52447:407;52638:2;52652:47;;;52623:18;;52713:131;52623:18;52713:131;;52861:407;53052:2;53066:47;;;53037:18;;53127:131;53037:18;53127:131;;53275:362;53467:3;53452:19;;53482:145;53456:9;53600:6;53482:145;;53644:334;53822:3;53807:19;;53837:131;53811:9;53941:6;53837:131;;53985:328;54160:3;54145:19;;54175:128;54149:9;54276:6;54175:128;;54540:324;54686:2;54671:18;;54700:71;54675:9;54744:6;54700:71;;54871:256;54933:2;54927:9;54959:17;;;55034:18;55019:34;;55055:22;;;55016:62;55013:2;;;55091:1;55088;55081:12;55013:2;55107;55100:22;54911:216;;-1:-1;54911:216;55135:163;55238:19;;;55287:4;55278:14;;55231:67;55306:84;55380:5;55363:27;55489:91;;55551:24;55569:5;55551:24;;55693:85;55759:13;55752:21;;55735:43;55864:124;55935:5;55941:42;55935:5;55941:42;;56073:121;-1:-1;;;;;56135:54;;56118:76;56280:129;;56367:37;56398:5;56416:165;;56517:59;56570:5;56517:59;;57331:124;;57417:33;57444:5;57417:33;;57705:159;;57794:65;57824:34;57847:10;57824:34;;;57794:65;;58149:100;58227:1;58220:5;58217:12;58207:2;;58233:9;58207:2;58201:48;;58256:117;58325:24;58343:5;58325:24;;;58318:5;58315:35;58305:2;;58364:1;58361;58354:12;58380:111;58446:21;58461:5;58446:21;;58498:117;58567:24;58585:5;58567:24;;58622:103;58700:1;58693:5;58690:12;58680:2;;58716:1;58713;58706:12

Swarm Source

bzzr://afea0d0400ac60b2c919243edd9ad1a4c662c5e60924ae327140ed3d7dd3891e

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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