Latest 25 from a total of 11,309 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Settle Share | 12994637 | 1580 days ago | IN | 0 ETH | 0.00706629 | ||||
| Settle Share | 12658853 | 1633 days ago | IN | 0 ETH | 0.00222789 | ||||
| Settle Share | 12343449 | 1682 days ago | IN | 0 ETH | 0.00784606 | ||||
| Settle Share | 12038315 | 1729 days ago | IN | 0 ETH | 0.01086382 | ||||
| Settle Share | 11958203 | 1741 days ago | IN | 0 ETH | 0.00879452 | ||||
| Settle Share | 11958133 | 1741 days ago | IN | 0 ETH | 0.00931185 | ||||
| Deposit And Buy | 11953928 | 1742 days ago | IN | 0 ETH | 0.0635594 | ||||
| Deposit And Buy | 11952299 | 1742 days ago | IN | 0 ETH | 0.06694149 | ||||
| Remove Liquidity | 11937603 | 1744 days ago | IN | 0 ETH | 0.07710696 | ||||
| Sell | 11925137 | 1746 days ago | IN | 0 ETH | 0.13011438 | ||||
| Buy | 11922684 | 1746 days ago | IN | 0 ETH | 0.15491005 | ||||
| Sell | 11921064 | 1747 days ago | IN | 0 ETH | 0.25019709 | ||||
| Sell | 11918646 | 1747 days ago | IN | 0 ETH | 0.11478909 | ||||
| Sell | 11916242 | 1747 days ago | IN | 0 ETH | 0.1444316 | ||||
| Buy | 11914588 | 1748 days ago | IN | 0 ETH | 0.32229894 | ||||
| Buy | 11912141 | 1748 days ago | IN | 0 ETH | 0.34778919 | ||||
| Buy | 11909729 | 1748 days ago | IN | 0 ETH | 0.17336779 | ||||
| Deposit And Sell | 11909564 | 1748 days ago | IN | 0 ETH | 0.13315333 | ||||
| Buy | 11908140 | 1749 days ago | IN | 0 ETH | 0.37492224 | ||||
| Buy | 11905657 | 1749 days ago | IN | 0 ETH | 0.10725031 | ||||
| Deposit And Sell | 11904945 | 1749 days ago | IN | 0.42 ETH | 0.12032487 | ||||
| Deposit And Sell | 11904937 | 1749 days ago | IN | 0.457 ETH | 0.02519217 | ||||
| Deposit And Sell | 11904620 | 1749 days ago | IN | 0.585 ETH | 0.13461907 | ||||
| Deposit And Sell | 11904324 | 1749 days ago | IN | 0.133 ETH | 0.12789716 | ||||
| Deposit And Sell | 11904048 | 1749 days ago | IN | 0.016 ETH | 0.10301512 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| - | 11904945 | 1749 days ago | 0.42 ETH | ||||
| - | 11904937 | 1749 days ago | 0.457 ETH | ||||
| - | 11904620 | 1749 days ago | 0.585 ETH | ||||
| - | 11904324 | 1749 days ago | 0.133 ETH | ||||
| - | 11904048 | 1749 days ago | 0.016 ETH | ||||
| - | 11902135 | 1750 days ago | 0.001 ETH | ||||
| - | 11846156 | 1758 days ago | 1 ETH | ||||
| - | 11846147 | 1758 days ago | 0.12523853 ETH | ||||
| - | 11793795 | 1766 days ago | 0.001 ETH | ||||
| - | 11707629 | 1779 days ago | 0.001 ETH | ||||
| - | 11637241 | 1790 days ago | 0.419 ETH | ||||
| - | 11636162 | 1790 days ago | 0.534 ETH | ||||
| - | 11620866 | 1793 days ago | 0.001 ETH | ||||
| - | 11603447 | 1795 days ago | 0.281 ETH | ||||
| - | 11583328 | 1799 days ago | 0.115 ETH | ||||
| - | 11572769 | 1800 days ago | 0.008 ETH | ||||
| - | 11493061 | 1812 days ago | 0.016 ETH | ||||
| - | 11376532 | 1830 days ago | 0.118 ETH | ||||
| - | 11359532 | 1833 days ago | 0.004 ETH | ||||
| - | 11344823 | 1835 days ago | 0.802 ETH | ||||
| - | 11334044 | 1837 days ago | 0.492 ETH | ||||
| - | 11325532 | 1838 days ago | 0.377 ETH | ||||
| - | 11325423 | 1838 days ago | 0.036 ETH | ||||
| - | 11312952 | 1840 days ago | 1.834 ETH | ||||
| - | 11287449 | 1844 days ago | 0.022 ETH |
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
AMM
Compiler Version
v0.5.15+commit.6a57276f
Contract Source Code (Solidity)
/**
*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
- No Contract Security Audit Submitted- Submit Audit Here
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"}]Contract Creation Code
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
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.