More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 9 from a total of 9 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Clone | 16535197 | 661 days ago | IN | 0 ETH | 0.00627752 | ||||
Clone | 15404048 | 822 days ago | IN | 0 ETH | 0.00459983 | ||||
Clone | 15403990 | 822 days ago | IN | 0 ETH | 0.00443051 | ||||
Clone | 14980403 | 890 days ago | IN | 0 ETH | 0.02435594 | ||||
Clone | 13510052 | 1121 days ago | IN | 0 ETH | 0.03260621 | ||||
Clone | 12909687 | 1215 days ago | IN | 0 ETH | 0.00724845 | ||||
Clone | 12867134 | 1221 days ago | IN | 0 ETH | 0.00612479 | ||||
Set Strategist | 12815075 | 1230 days ago | IN | 0 ETH | 0.00076032 | ||||
0x60806040 | 12812437 | 1230 days ago | IN | 0 ETH | 0.10195574 |
Latest 11 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
16535197 | 661 days ago | Contract Creation | 0 ETH | |||
15849936 | 757 days ago | Contract Creation | 0 ETH | |||
15404048 | 822 days ago | Contract Creation | 0 ETH | |||
15403990 | 822 days ago | Contract Creation | 0 ETH | |||
14980403 | 890 days ago | Contract Creation | 0 ETH | |||
14627575 | 947 days ago | Contract Creation | 0 ETH | |||
14329261 | 994 days ago | Contract Creation | 0 ETH | |||
13513457 | 1121 days ago | Contract Creation | 0 ETH | |||
13510052 | 1121 days ago | Contract Creation | 0 ETH | |||
12909687 | 1215 days ago | Contract Creation | 0 ETH | |||
12867134 | 1221 days ago | Contract Creation | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Strategy
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-07-12 */ // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.6.12; pragma experimental ABIEncoderV2; // Global Enums and Structs struct StrategyParams { uint256 performanceFee; uint256 activation; uint256 debtRatio; uint256 minDebtPerHarvest; uint256 maxDebtPerHarvest; uint256 lastReport; uint256 totalDebt; uint256 totalGain; uint256 totalLoss; } // Part: IGenericLender interface IGenericLender { function lenderName() external view returns (string memory); function nav() external view returns (uint256); function strategy() external view returns (address); function apr() external view returns (uint256); function weightedApr() external view returns (uint256); function withdraw(uint256 amount) external returns (uint256); function emergencyWithdraw(uint256 amount) external; function deposit() external; function withdrawAll() external returns (bool); function hasAssets() external view returns (bool); function aprAfterDeposit(uint256 amount) external view returns (uint256); function setDust(uint256 _dust) external; function sweep(address _token) external; } // Part: IUni interface IUni { function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); } // Part: IWantToEth interface IWantToEth { function wantToEth(uint256 input) external view returns (uint256); function ethToWant(uint256 input) external view returns (uint256); } // Part: OpenZeppelin/[email protected]/Address /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // 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 Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // Part: OpenZeppelin/[email protected]/IERC20 /** * @dev Interface of the ERC20 standard as defined in the EIP. */ 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); } // Part: OpenZeppelin/[email protected]/Math /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } } // Part: OpenZeppelin/[email protected]/SafeMath /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ 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. */ 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. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 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. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // Part: iearn-finance/[email protected]/HealthCheck interface HealthCheck { function check( uint256 profit, uint256 loss, uint256 debtPayment, uint256 debtOutstanding, uint256 totalDebt ) external view returns (bool); } // Part: OpenZeppelin/[email protected]/SafeERC20 /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // Part: iearn-finance/[email protected]/VaultAPI interface VaultAPI is IERC20 { function name() external view returns (string calldata); function symbol() external view returns (string calldata); function decimals() external view returns (uint256); function apiVersion() external pure returns (string memory); function permit( address owner, address spender, uint256 amount, uint256 expiry, bytes calldata signature ) external returns (bool); // NOTE: Vyper produces multiple signatures for a given function with "default" args function deposit() external returns (uint256); function deposit(uint256 amount) external returns (uint256); function deposit(uint256 amount, address recipient) external returns (uint256); // NOTE: Vyper produces multiple signatures for a given function with "default" args function withdraw() external returns (uint256); function withdraw(uint256 maxShares) external returns (uint256); function withdraw(uint256 maxShares, address recipient) external returns (uint256); function token() external view returns (address); function strategies(address _strategy) external view returns (StrategyParams memory); function pricePerShare() external view returns (uint256); function totalAssets() external view returns (uint256); function depositLimit() external view returns (uint256); function maxAvailableShares() external view returns (uint256); /** * View how much the Vault would increase this Strategy's borrow limit, * based on its present performance (since its last report). Can be used to * determine expectedReturn in your Strategy. */ function creditAvailable() external view returns (uint256); /** * View how much the Vault would like to pull back from the Strategy, * based on its present performance (since its last report). Can be used to * determine expectedReturn in your Strategy. */ function debtOutstanding() external view returns (uint256); /** * View how much the Vault expect this Strategy to return at the current * block, based on its present performance (since its last report). Can be * used to determine expectedReturn in your Strategy. */ function expectedReturn() external view returns (uint256); /** * This is the main contact point where the Strategy interacts with the * Vault. It is critical that this call is handled as intended by the * Strategy. Therefore, this function will be called by BaseStrategy to * make sure the integration is correct. */ function report( uint256 _gain, uint256 _loss, uint256 _debtPayment ) external returns (uint256); /** * This function should only be used in the scenario where the Strategy is * being retired but no migration of the positions are possible, or in the * extreme scenario that the Strategy needs to be put into "Emergency Exit" * mode in order for it to exit as quickly as possible. The latter scenario * could be for any reason that is considered "critical" that the Strategy * exits its position as fast as possible, such as a sudden change in * market conditions leading to losses, or an imminent failure in an * external dependency. */ function revokeStrategy() external; /** * View the governance address of the Vault to assert privileged functions * can only be called by governance. The Strategy serves the Vault, so it * is subject to governance defined by the Vault. */ function governance() external view returns (address); /** * View the management address of the Vault to assert privileged functions * can only be called by management. The Strategy serves the Vault, so it * is subject to management defined by the Vault. */ function management() external view returns (address); /** * View the guardian address of the Vault to assert privileged functions * can only be called by guardian. The Strategy serves the Vault, so it * is subject to guardian defined by the Vault. */ function guardian() external view returns (address); } // Part: iearn-finance/[email protected]/BaseStrategy /** * @title Yearn Base Strategy * @author yearn.finance * @notice * BaseStrategy implements all of the required functionality to interoperate * closely with the Vault contract. This contract should be inherited and the * abstract methods implemented to adapt the Strategy to the particular needs * it has to create a return. * * Of special interest is the relationship between `harvest()` and * `vault.report()'. `harvest()` may be called simply because enough time has * elapsed since the last report, and not because any funds need to be moved * or positions adjusted. This is critical so that the Vault may maintain an * accurate picture of the Strategy's performance. See `vault.report()`, * `harvest()`, and `harvestTrigger()` for further details. */ abstract contract BaseStrategy { using SafeMath for uint256; using SafeERC20 for IERC20; string public metadataURI; // health checks bool public doHealthCheck; address public healthCheck; /** * @notice * Used to track which version of `StrategyAPI` this Strategy * implements. * @dev The Strategy's version must match the Vault's `API_VERSION`. * @return A string which holds the current API version of this contract. */ function apiVersion() public pure returns (string memory) { return "0.4.3"; } /** * @notice This Strategy's name. * @dev * You can use this field to manage the "version" of this Strategy, e.g. * `StrategySomethingOrOtherV1`. However, "API Version" is managed by * `apiVersion()` function above. * @return This Strategy's name. */ function name() external view virtual returns (string memory); /** * @notice * The amount (priced in want) of the total assets managed by this strategy should not count * towards Yearn's TVL calculations. * @dev * You can override this field to set it to a non-zero value if some of the assets of this * Strategy is somehow delegated inside another part of of Yearn's ecosystem e.g. another Vault. * Note that this value must be strictly less than or equal to the amount provided by * `estimatedTotalAssets()` below, as the TVL calc will be total assets minus delegated assets. * Also note that this value is used to determine the total assets under management by this * strategy, for the purposes of computing the management fee in `Vault` * @return * The amount of assets this strategy manages that should not be included in Yearn's Total Value * Locked (TVL) calculation across it's ecosystem. */ function delegatedAssets() external view virtual returns (uint256) { return 0; } VaultAPI public vault; address public strategist; address public rewards; address public keeper; IERC20 public want; // So indexers can keep track of this event Harvested(uint256 profit, uint256 loss, uint256 debtPayment, uint256 debtOutstanding); event UpdatedStrategist(address newStrategist); event UpdatedKeeper(address newKeeper); event UpdatedRewards(address rewards); event UpdatedMinReportDelay(uint256 delay); event UpdatedMaxReportDelay(uint256 delay); event UpdatedProfitFactor(uint256 profitFactor); event UpdatedDebtThreshold(uint256 debtThreshold); event EmergencyExitEnabled(); event UpdatedMetadataURI(string metadataURI); // The minimum number of seconds between harvest calls. See // `setMinReportDelay()` for more details. uint256 public minReportDelay; // The maximum number of seconds between harvest calls. See // `setMaxReportDelay()` for more details. uint256 public maxReportDelay; // The minimum multiple that `callCost` must be above the credit/profit to // be "justifiable". See `setProfitFactor()` for more details. uint256 public profitFactor; // Use this to adjust the threshold at which running a debt causes a // harvest trigger. See `setDebtThreshold()` for more details. uint256 public debtThreshold; // See note on `setEmergencyExit()`. bool public emergencyExit; // modifiers modifier onlyAuthorized() { require(msg.sender == strategist || msg.sender == governance(), "!authorized"); _; } modifier onlyEmergencyAuthorized() { require( msg.sender == strategist || msg.sender == governance() || msg.sender == vault.guardian() || msg.sender == vault.management(), "!authorized" ); _; } modifier onlyStrategist() { require(msg.sender == strategist, "!strategist"); _; } modifier onlyGovernance() { require(msg.sender == governance(), "!authorized"); _; } modifier onlyKeepers() { require( msg.sender == keeper || msg.sender == strategist || msg.sender == governance() || msg.sender == vault.guardian() || msg.sender == vault.management(), "!authorized" ); _; } modifier onlyVaultManagers() { require(msg.sender == vault.management() || msg.sender == governance(), "!authorized"); _; } constructor(address _vault) public { _initialize(_vault, msg.sender, msg.sender, msg.sender); } /** * @notice * Initializes the Strategy, this is called only once, when the * contract is deployed. * @dev `_vault` should implement `VaultAPI`. * @param _vault The address of the Vault responsible for this Strategy. * @param _strategist The address to assign as `strategist`. * The strategist is able to change the reward address * @param _rewards The address to use for pulling rewards. * @param _keeper The adddress of the _keeper. _keeper * can harvest and tend a strategy. */ function _initialize( address _vault, address _strategist, address _rewards, address _keeper ) internal { require(address(want) == address(0), "Strategy already initialized"); vault = VaultAPI(_vault); want = IERC20(vault.token()); want.safeApprove(_vault, uint256(-1)); // Give Vault unlimited access (might save gas) strategist = _strategist; rewards = _rewards; keeper = _keeper; // initialize variables minReportDelay = 0; maxReportDelay = 86400; profitFactor = 100; debtThreshold = 0; vault.approve(rewards, uint256(-1)); // Allow rewards to be pulled } function setHealthCheck(address _healthCheck) external onlyVaultManagers { healthCheck = _healthCheck; } function setDoHealthCheck(bool _doHealthCheck) external onlyVaultManagers { doHealthCheck = _doHealthCheck; } /** * @notice * Used to change `strategist`. * * This may only be called by governance or the existing strategist. * @param _strategist The new address to assign as `strategist`. */ function setStrategist(address _strategist) external onlyAuthorized { require(_strategist != address(0)); strategist = _strategist; emit UpdatedStrategist(_strategist); } /** * @notice * Used to change `keeper`. * * `keeper` is the only address that may call `tend()` or `harvest()`, * other than `governance()` or `strategist`. However, unlike * `governance()` or `strategist`, `keeper` may *only* call `tend()` * and `harvest()`, and no other authorized functions, following the * principle of least privilege. * * This may only be called by governance or the strategist. * @param _keeper The new address to assign as `keeper`. */ function setKeeper(address _keeper) external onlyAuthorized { require(_keeper != address(0)); keeper = _keeper; emit UpdatedKeeper(_keeper); } /** * @notice * Used to change `rewards`. EOA or smart contract which has the permission * to pull rewards from the vault. * * This may only be called by the strategist. * @param _rewards The address to use for pulling rewards. */ function setRewards(address _rewards) external onlyStrategist { require(_rewards != address(0)); vault.approve(rewards, 0); rewards = _rewards; vault.approve(rewards, uint256(-1)); emit UpdatedRewards(_rewards); } /** * @notice * Used to change `minReportDelay`. `minReportDelay` is the minimum number * of blocks that should pass for `harvest()` to be called. * * For external keepers (such as the Keep3r network), this is the minimum * time between jobs to wait. (see `harvestTrigger()` * for more details.) * * This may only be called by governance or the strategist. * @param _delay The minimum number of seconds to wait between harvests. */ function setMinReportDelay(uint256 _delay) external onlyAuthorized { minReportDelay = _delay; emit UpdatedMinReportDelay(_delay); } /** * @notice * Used to change `maxReportDelay`. `maxReportDelay` is the maximum number * of blocks that should pass for `harvest()` to be called. * * For external keepers (such as the Keep3r network), this is the maximum * time between jobs to wait. (see `harvestTrigger()` * for more details.) * * This may only be called by governance or the strategist. * @param _delay The maximum number of seconds to wait between harvests. */ function setMaxReportDelay(uint256 _delay) external onlyAuthorized { maxReportDelay = _delay; emit UpdatedMaxReportDelay(_delay); } /** * @notice * Used to change `profitFactor`. `profitFactor` is used to determine * if it's worthwhile to harvest, given gas costs. (See `harvestTrigger()` * for more details.) * * This may only be called by governance or the strategist. * @param _profitFactor A ratio to multiply anticipated * `harvest()` gas cost against. */ function setProfitFactor(uint256 _profitFactor) external onlyAuthorized { profitFactor = _profitFactor; emit UpdatedProfitFactor(_profitFactor); } /** * @notice * Sets how far the Strategy can go into loss without a harvest and report * being required. * * By default this is 0, meaning any losses would cause a harvest which * will subsequently report the loss to the Vault for tracking. (See * `harvestTrigger()` for more details.) * * This may only be called by governance or the strategist. * @param _debtThreshold How big of a loss this Strategy may carry without * being required to report to the Vault. */ function setDebtThreshold(uint256 _debtThreshold) external onlyAuthorized { debtThreshold = _debtThreshold; emit UpdatedDebtThreshold(_debtThreshold); } /** * @notice * Used to change `metadataURI`. `metadataURI` is used to store the URI * of the file describing the strategy. * * This may only be called by governance or the strategist. * @param _metadataURI The URI that describe the strategy. */ function setMetadataURI(string calldata _metadataURI) external onlyAuthorized { metadataURI = _metadataURI; emit UpdatedMetadataURI(_metadataURI); } /** * Resolve governance address from Vault contract, used to make assertions * on protected functions in the Strategy. */ function governance() internal view returns (address) { return vault.governance(); } /** * @notice * Provide an accurate conversion from `_amtInWei` (denominated in wei) * to `want` (using the native decimal characteristics of `want`). * @dev * Care must be taken when working with decimals to assure that the conversion * is compatible. As an example: * * given 1e17 wei (0.1 ETH) as input, and want is USDC (6 decimals), * with USDC/ETH = 1800, this should give back 1800000000 (180 USDC) * * @param _amtInWei The amount (in wei/1e-18 ETH) to convert to `want` * @return The amount in `want` of `_amtInEth` converted to `want` **/ function ethToWant(uint256 _amtInWei) public view virtual returns (uint256); /** * @notice * Provide an accurate estimate for the total amount of assets * (principle + return) that this Strategy is currently managing, * denominated in terms of `want` tokens. * * This total should be "realizable" e.g. the total value that could * *actually* be obtained from this Strategy if it were to divest its * entire position based on current on-chain conditions. * @dev * Care must be taken in using this function, since it relies on external * systems, which could be manipulated by the attacker to give an inflated * (or reduced) value produced by this function, based on current on-chain * conditions (e.g. this function is possible to influence through * flashloan attacks, oracle manipulations, or other DeFi attack * mechanisms). * * It is up to governance to use this function to correctly order this * Strategy relative to its peers in the withdrawal queue to minimize * losses for the Vault based on sudden withdrawals. This value should be * higher than the total debt of the Strategy and higher than its expected * value to be "safe". * @return The estimated total assets in this Strategy. */ function estimatedTotalAssets() public view virtual returns (uint256); /* * @notice * Provide an indication of whether this strategy is currently "active" * in that it is managing an active position, or will manage a position in * the future. This should correlate to `harvest()` activity, so that Harvest * events can be tracked externally by indexing agents. * @return True if the strategy is actively managing a position. */ function isActive() public view returns (bool) { return vault.strategies(address(this)).debtRatio > 0 || estimatedTotalAssets() > 0; } /** * Perform any Strategy unwinding or other calls necessary to capture the * "free return" this Strategy has generated since the last time its core * position(s) were adjusted. Examples include unwrapping extra rewards. * This call is only used during "normal operation" of a Strategy, and * should be optimized to minimize losses as much as possible. * * This method returns any realized profits and/or realized losses * incurred, and should return the total amounts of profits/losses/debt * payments (in `want` tokens) for the Vault's accounting (e.g. * `want.balanceOf(this) >= _debtPayment + _profit`). * * `_debtOutstanding` will be 0 if the Strategy is not past the configured * debt limit, otherwise its value will be how far past the debt limit * the Strategy is. The Strategy's debt limit is configured in the Vault. * * NOTE: `_debtPayment` should be less than or equal to `_debtOutstanding`. * It is okay for it to be less than `_debtOutstanding`, as that * should only used as a guide for how much is left to pay back. * Payments should be made to minimize loss from slippage, debt, * withdrawal fees, etc. * * See `vault.debtOutstanding()`. */ function prepareReturn(uint256 _debtOutstanding) internal virtual returns ( uint256 _profit, uint256 _loss, uint256 _debtPayment ); /** * Perform any adjustments to the core position(s) of this Strategy given * what change the Vault made in the "investable capital" available to the * Strategy. Note that all "free capital" in the Strategy after the report * was made is available for reinvestment. Also note that this number * could be 0, and you should handle that scenario accordingly. * * See comments regarding `_debtOutstanding` on `prepareReturn()`. */ function adjustPosition(uint256 _debtOutstanding) internal virtual; /** * Liquidate up to `_amountNeeded` of `want` of this strategy's positions, * irregardless of slippage. Any excess will be re-invested with `adjustPosition()`. * This function should return the amount of `want` tokens made available by the * liquidation. If there is a difference between them, `_loss` indicates whether the * difference is due to a realized loss, or if there is some other sitution at play * (e.g. locked funds) where the amount made available is less than what is needed. * * NOTE: The invariant `_liquidatedAmount + _loss <= _amountNeeded` should always be maintained */ function liquidatePosition(uint256 _amountNeeded) internal virtual returns (uint256 _liquidatedAmount, uint256 _loss); /** * Liquidate everything and returns the amount that got freed. * This function is used during emergency exit instead of `prepareReturn()` to * liquidate all of the Strategy's positions back to the Vault. */ function liquidateAllPositions() internal virtual returns (uint256 _amountFreed); /** * @notice * Provide a signal to the keeper that `tend()` should be called. The * keeper will provide the estimated gas cost that they would pay to call * `tend()`, and this function should use that estimate to make a * determination if calling it is "worth it" for the keeper. This is not * the only consideration into issuing this trigger, for example if the * position would be negatively affected if `tend()` is not called * shortly, then this can return `true` even if the keeper might be * "at a loss" (keepers are always reimbursed by Yearn). * @dev * `callCostInWei` must be priced in terms of `wei` (1e-18 ETH). * * This call and `harvestTrigger()` should never return `true` at the same * time. * @param callCostInWei The keeper's estimated gas cost to call `tend()` (in wei). * @return `true` if `tend()` should be called, `false` otherwise. */ function tendTrigger(uint256 callCostInWei) public view virtual returns (bool) { // We usually don't need tend, but if there are positions that need // active maintainence, overriding this function is how you would // signal for that. // If your implementation uses the cost of the call in want, you can // use uint256 callCost = ethToWant(callCostInWei); return false; } /** * @notice * Adjust the Strategy's position. The purpose of tending isn't to * realize gains, but to maximize yield by reinvesting any returns. * * See comments on `adjustPosition()`. * * This may only be called by governance, the strategist, or the keeper. */ function tend() external onlyKeepers { // Don't take profits with this call, but adjust for better gains adjustPosition(vault.debtOutstanding()); } /** * @notice * Provide a signal to the keeper that `harvest()` should be called. The * keeper will provide the estimated gas cost that they would pay to call * `harvest()`, and this function should use that estimate to make a * determination if calling it is "worth it" for the keeper. This is not * the only consideration into issuing this trigger, for example if the * position would be negatively affected if `harvest()` is not called * shortly, then this can return `true` even if the keeper might be "at a * loss" (keepers are always reimbursed by Yearn). * @dev * `callCostInWei` must be priced in terms of `wei` (1e-18 ETH). * * This call and `tendTrigger` should never return `true` at the * same time. * * See `min/maxReportDelay`, `profitFactor`, `debtThreshold` to adjust the * strategist-controlled parameters that will influence whether this call * returns `true` or not. These parameters will be used in conjunction * with the parameters reported to the Vault (see `params`) to determine * if calling `harvest()` is merited. * * It is expected that an external system will check `harvestTrigger()`. * This could be a script run off a desktop or cloud bot (e.g. * https://github.com/iearn-finance/yearn-vaults/blob/main/scripts/keep.py), * or via an integration with the Keep3r network (e.g. * https://github.com/Macarse/GenericKeep3rV2/blob/master/contracts/keep3r/GenericKeep3rV2.sol). * @param callCostInWei The keeper's estimated gas cost to call `harvest()` (in wei). * @return `true` if `harvest()` should be called, `false` otherwise. */ function harvestTrigger(uint256 callCostInWei) public view virtual returns (bool) { uint256 callCost = ethToWant(callCostInWei); StrategyParams memory params = vault.strategies(address(this)); // Should not trigger if Strategy is not activated if (params.activation == 0) return false; // Should not trigger if we haven't waited long enough since previous harvest if (block.timestamp.sub(params.lastReport) < minReportDelay) return false; // Should trigger if hasn't been called in a while if (block.timestamp.sub(params.lastReport) >= maxReportDelay) return true; // If some amount is owed, pay it back // NOTE: Since debt is based on deposits, it makes sense to guard against large // changes to the value from triggering a harvest directly through user // behavior. This should ensure reasonable resistance to manipulation // from user-initiated withdrawals as the outstanding debt fluctuates. uint256 outstanding = vault.debtOutstanding(); if (outstanding > debtThreshold) return true; // Check for profits and losses uint256 total = estimatedTotalAssets(); // Trigger if we have a loss to report if (total.add(debtThreshold) < params.totalDebt) return true; uint256 profit = 0; if (total > params.totalDebt) profit = total.sub(params.totalDebt); // We've earned a profit! // Otherwise, only trigger if it "makes sense" economically (gas cost // is <N% of value moved) uint256 credit = vault.creditAvailable(); return (profitFactor.mul(callCost) < credit.add(profit)); } /** * @notice * Harvests the Strategy, recognizing any profits or losses and adjusting * the Strategy's position. * * In the rare case the Strategy is in emergency shutdown, this will exit * the Strategy's position. * * This may only be called by governance, the strategist, or the keeper. * @dev * When `harvest()` is called, the Strategy reports to the Vault (via * `vault.report()`), so in some cases `harvest()` must be called in order * to take in profits, to borrow newly available funds from the Vault, or * otherwise adjust its position. In other cases `harvest()` must be * called to report to the Vault on the Strategy's position, especially if * any losses have occurred. */ function harvest() external onlyKeepers { uint256 profit = 0; uint256 loss = 0; uint256 debtOutstanding = vault.debtOutstanding(); uint256 debtPayment = 0; if (emergencyExit) { // Free up as much capital as possible uint256 amountFreed = liquidateAllPositions(); if (amountFreed < debtOutstanding) { loss = debtOutstanding.sub(amountFreed); } else if (amountFreed > debtOutstanding) { profit = amountFreed.sub(debtOutstanding); } debtPayment = debtOutstanding.sub(loss); } else { // Free up returns for Vault to pull (profit, loss, debtPayment) = prepareReturn(debtOutstanding); } // Allow Vault to take up to the "harvested" balance of this contract, // which is the amount it has earned since the last time it reported to // the Vault. uint256 totalDebt = vault.strategies(address(this)).totalDebt; debtOutstanding = vault.report(profit, loss, debtPayment); // Check if free returns are left, and re-invest them adjustPosition(debtOutstanding); // call healthCheck contract if (doHealthCheck && healthCheck != address(0)) { require(HealthCheck(healthCheck).check(profit, loss, debtPayment, debtOutstanding, totalDebt), "!healthcheck"); } else { doHealthCheck = true; } emit Harvested(profit, loss, debtPayment, debtOutstanding); } /** * @notice * Withdraws `_amountNeeded` to `vault`. * * This may only be called by the Vault. * @param _amountNeeded How much `want` to withdraw. * @return _loss Any realized losses */ function withdraw(uint256 _amountNeeded) external returns (uint256 _loss) { require(msg.sender == address(vault), "!vault"); // Liquidate as much as possible to `want`, up to `_amountNeeded` uint256 amountFreed; (amountFreed, _loss) = liquidatePosition(_amountNeeded); // Send it directly back (NOTE: Using `msg.sender` saves some gas here) want.safeTransfer(msg.sender, amountFreed); // NOTE: Reinvest anything leftover on next `tend`/`harvest` } /** * Do anything necessary to prepare this Strategy for migration, such as * transferring any reserve or LP tokens, CDPs, or other tokens or stores of * value. */ function prepareMigration(address _newStrategy) internal virtual; /** * @notice * Transfers all `want` from this Strategy to `_newStrategy`. * * This may only be called by the Vault. * @dev * The new Strategy's Vault must be the same as this Strategy's Vault. * The migration process should be carefully performed to make sure all * the assets are migrated to the new address, which should have never * interacted with the vault before. * @param _newStrategy The Strategy to migrate to. */ function migrate(address _newStrategy) external { require(msg.sender == address(vault)); require(BaseStrategy(_newStrategy).vault() == vault); prepareMigration(_newStrategy); want.safeTransfer(_newStrategy, want.balanceOf(address(this))); } /** * @notice * Activates emergency exit. Once activated, the Strategy will exit its * position upon the next harvest, depositing all funds into the Vault as * quickly as is reasonable given on-chain conditions. * * This may only be called by governance or the strategist. * @dev * See `vault.setEmergencyShutdown()` and `harvest()` for further details. */ function setEmergencyExit() external onlyEmergencyAuthorized { emergencyExit = true; vault.revokeStrategy(); emit EmergencyExitEnabled(); } /** * Override this to add all tokens/tokenized positions this contract * manages on a *persistent* basis (e.g. not just for swapping back to * want ephemerally). * * NOTE: Do *not* include `want`, already included in `sweep` below. * * Example: * ``` * function protectedTokens() internal override view returns (address[] memory) { * address[] memory protected = new address[](3); * protected[0] = tokenA; * protected[1] = tokenB; * protected[2] = tokenC; * return protected; * } * ``` */ function protectedTokens() internal view virtual returns (address[] memory); /** * @notice * Removes tokens from this Strategy that are not the type of tokens * managed by this Strategy. This may be used in case of accidentally * sending the wrong kind of token to this Strategy. * * Tokens will be sent to `governance()`. * * This will fail if an attempt is made to sweep `want`, or any tokens * that are protected by this Strategy. * * This may only be called by governance. * @dev * Implement `protectedTokens()` to specify any additional tokens that * should be protected from sweeping in addition to `want`. * @param _token The token to transfer out of this vault. */ function sweep(address _token) external onlyGovernance { require(_token != address(want), "!want"); require(_token != address(vault), "!shares"); address[] memory _protectedTokens = protectedTokens(); for (uint256 i; i < _protectedTokens.length; i++) require(_token != _protectedTokens[i], "!protected"); IERC20(_token).safeTransfer(governance(), IERC20(_token).balanceOf(address(this))); } } // File: Strategy.sol /******************** * * A lender optimisation strategy for any erc20 asset * https://github.com/Grandthrax/yearnV2-generic-lender-strat * v0.3.1 * * This strategy works by taking plugins designed for standard lending platforms * It automatically chooses the best yield generating platform and adjusts accordingly * The adjustment is sub optimal so there is an additional option to manually set position * ********************* */ contract Strategy is BaseStrategy { using SafeERC20 for IERC20; using Address for address; using SafeMath for uint256; address public constant uniswapRouter = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; address public constant weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; uint256 public withdrawalThreshold = 1e16; uint256 public constant SECONDSPERYEAR = 31556952; IGenericLender[] public lenders; bool public externalOracle; // default is false address public wantToEthOracle; event Cloned(address indexed clone); constructor(address _vault) public BaseStrategy(_vault) { debtThreshold = 100 * 1e18; } function clone(address _vault) external returns (address newStrategy) { newStrategy = this.clone(_vault, msg.sender, msg.sender, msg.sender); } function clone( address _vault, address _strategist, address _rewards, address _keeper ) external returns (address newStrategy) { // Copied from https://github.com/optionality/clone-factory/blob/master/contracts/CloneFactory.sol bytes20 addressBytes = bytes20(address(this)); assembly { // EIP-1167 bytecode let clone_code := mload(0x40) mstore(clone_code, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) mstore(add(clone_code, 0x14), addressBytes) mstore(add(clone_code, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) newStrategy := create(0, clone_code, 0x37) } Strategy(newStrategy).initialize(_vault, _strategist, _rewards, _keeper); emit Cloned(newStrategy); } function initialize( address _vault, address _strategist, address _rewards, address _keeper ) external virtual { _initialize(_vault, _strategist, _rewards, _keeper); } function setWithdrawalThreshold(uint256 _threshold) external onlyAuthorized { withdrawalThreshold = _threshold; } function setPriceOracle(address _oracle) external onlyAuthorized { wantToEthOracle = _oracle; } function name() external view override returns (string memory) { return "StrategyLenderYieldOptimiser"; } //management functions //add lenders for the strategy to choose between // only governance to stop strategist adding dodgy lender function addLender(address a) public onlyGovernance { IGenericLender n = IGenericLender(a); require(n.strategy() == address(this), "Undocked Lender"); for (uint256 i = 0; i < lenders.length; i++) { require(a != address(lenders[i]), "Already Added"); } lenders.push(n); } //but strategist can remove for safety function safeRemoveLender(address a) public onlyAuthorized { _removeLender(a, false); } function forceRemoveLender(address a) public onlyAuthorized { _removeLender(a, true); } //force removes the lender even if it still has a balance function _removeLender(address a, bool force) internal { for (uint256 i = 0; i < lenders.length; i++) { if (a == address(lenders[i])) { bool allWithdrawn = lenders[i].withdrawAll(); if (!force) { require(allWithdrawn, "WITHDRAW FAILED"); } //put the last index here //remove last index if (i != lenders.length - 1) { lenders[i] = lenders[lenders.length - 1]; } //pop shortens array by 1 thereby deleting the last index lenders.pop(); //if balance to spend we might as well put it into the best lender if (want.balanceOf(address(this)) > 0) { adjustPosition(0); } return; } } require(false, "NOT LENDER"); } //we could make this more gas efficient but it is only used by a view function struct lendStatus { string name; uint256 assets; uint256 rate; address add; } //Returns the status of all lenders attached the strategy function lendStatuses() public view returns (lendStatus[] memory) { lendStatus[] memory statuses = new lendStatus[](lenders.length); for (uint256 i = 0; i < lenders.length; i++) { lendStatus memory s; s.name = lenders[i].lenderName(); s.add = address(lenders[i]); s.assets = lenders[i].nav(); s.rate = lenders[i].apr(); statuses[i] = s; } return statuses; } // lent assets plus loose assets function estimatedTotalAssets() public view override returns (uint256) { uint256 nav = lentTotalAssets(); nav = nav.add(want.balanceOf(address(this))); return nav; } function numLenders() public view returns (uint256) { return lenders.length; } //the weighted apr of all lenders. sum(nav * apr)/totalNav function estimatedAPR() public view returns (uint256) { uint256 bal = estimatedTotalAssets(); if (bal == 0) { return 0; } uint256 weightedAPR = 0; for (uint256 i = 0; i < lenders.length; i++) { weightedAPR = weightedAPR.add(lenders[i].weightedApr()); } return weightedAPR.div(bal); } //Estimates the impact on APR if we add more money. It does not take into account adjusting position function _estimateDebtLimitIncrease(uint256 change) internal view returns (uint256) { uint256 highestAPR = 0; uint256 aprChoice = 0; uint256 assets = 0; for (uint256 i = 0; i < lenders.length; i++) { uint256 apr = lenders[i].aprAfterDeposit(change); if (apr > highestAPR) { aprChoice = i; highestAPR = apr; assets = lenders[i].nav(); } } uint256 weightedAPR = highestAPR.mul(assets.add(change)); for (uint256 i = 0; i < lenders.length; i++) { if (i != aprChoice) { weightedAPR = weightedAPR.add(lenders[i].weightedApr()); } } uint256 bal = estimatedTotalAssets().add(change); return weightedAPR.div(bal); } //Estimates debt limit decrease. It is not accurate and should only be used for very broad decision making function _estimateDebtLimitDecrease(uint256 change) internal view returns (uint256) { uint256 lowestApr = uint256(-1); uint256 aprChoice = 0; for (uint256 i = 0; i < lenders.length; i++) { uint256 apr = lenders[i].aprAfterDeposit(change); if (apr < lowestApr) { aprChoice = i; lowestApr = apr; } } uint256 weightedAPR = 0; for (uint256 i = 0; i < lenders.length; i++) { if (i != aprChoice) { weightedAPR = weightedAPR.add(lenders[i].weightedApr()); } else { uint256 asset = lenders[i].nav(); if (asset < change) { //simplistic. not accurate change = asset; } weightedAPR = weightedAPR.add(lowestApr.mul(change)); } } uint256 bal = estimatedTotalAssets().add(change); return weightedAPR.div(bal); } //estimates highest and lowest apr lenders. Public for debugging purposes but not much use to general public function estimateAdjustPosition() public view returns ( uint256 _lowest, uint256 _lowestApr, uint256 _highest, uint256 _potential ) { //all loose assets are to be invested uint256 looseAssets = want.balanceOf(address(this)); // our simple algo // get the lowest apr strat // cycle through and see who could take its funds plus want for the highest apr _lowestApr = uint256(-1); _lowest = 0; uint256 lowestNav = 0; for (uint256 i = 0; i < lenders.length; i++) { if (lenders[i].hasAssets()) { uint256 apr = lenders[i].apr(); if (apr < _lowestApr) { _lowestApr = apr; _lowest = i; lowestNav = lenders[i].nav(); } } } uint256 toAdd = lowestNav.add(looseAssets); uint256 highestApr = 0; _highest = 0; for (uint256 i = 0; i < lenders.length; i++) { uint256 apr; apr = lenders[i].aprAfterDeposit(looseAssets); if (apr > highestApr) { highestApr = apr; _highest = i; } } //if we can improve apr by withdrawing we do so _potential = lenders[_highest].aprAfterDeposit(toAdd); } //gives estiomate of future APR with a change of debt limit. Useful for governance to decide debt limits function estimatedFutureAPR(uint256 newDebtLimit) public view returns (uint256) { uint256 oldDebtLimit = vault.strategies(address(this)).totalDebt; uint256 change; if (oldDebtLimit < newDebtLimit) { change = newDebtLimit - oldDebtLimit; return _estimateDebtLimitIncrease(change); } else { change = oldDebtLimit - newDebtLimit; return _estimateDebtLimitDecrease(change); } } //cycle all lenders and collect balances function lentTotalAssets() public view returns (uint256) { uint256 nav = 0; for (uint256 i = 0; i < lenders.length; i++) { nav = nav.add(lenders[i].nav()); } return nav; } // we need to free up profit plus _debtOutstanding. // If _debtOutstanding is more than we can free we get as much as possible // should be no way for there to be a loss. we hope... function prepareReturn(uint256 _debtOutstanding) internal override returns ( uint256 _profit, uint256 _loss, uint256 _debtPayment ) { _profit = 0; _loss = 0; //for clarity _debtPayment = _debtOutstanding; uint256 lentAssets = lentTotalAssets(); uint256 looseAssets = want.balanceOf(address(this)); uint256 total = looseAssets.add(lentAssets); if (lentAssets == 0) { //no position to harvest or profit to report if (_debtPayment > looseAssets) { //we can only return looseAssets _debtPayment = looseAssets; } return (_profit, _loss, _debtPayment); } uint256 debt = vault.strategies(address(this)).totalDebt; if (total > debt) { _profit = total - debt; uint256 amountToFree = _profit.add(_debtPayment); //we need to add outstanding to our profit //dont need to do logic if there is nothiing to free if (amountToFree > 0 && looseAssets < amountToFree) { //withdraw what we can withdraw _withdrawSome(amountToFree.sub(looseAssets)); uint256 newLoose = want.balanceOf(address(this)); //if we dont have enough money adjust _debtOutstanding and only change profit if needed if (newLoose < amountToFree) { if (_profit > newLoose) { _profit = newLoose; _debtPayment = 0; } else { _debtPayment = Math.min(newLoose - _profit, _debtPayment); } } } } else { //serious loss should never happen but if it does lets record it accurately _loss = debt - total; uint256 amountToFree = _loss.add(_debtPayment); if (amountToFree > 0 && looseAssets < amountToFree) { //withdraw what we can withdraw _withdrawSome(amountToFree.sub(looseAssets)); uint256 newLoose = want.balanceOf(address(this)); //if we dont have enough money adjust _debtOutstanding and only change profit if needed if (newLoose < amountToFree) { if (_loss > newLoose) { _loss = newLoose; _debtPayment = 0; } else { _debtPayment = Math.min(newLoose - _loss, _debtPayment); } } } } } /* * Key logic. * The algorithm moves assets from lowest return to highest * like a very slow idiots bubble sort * we ignore debt outstanding for an easy life */ function adjustPosition(uint256 _debtOutstanding) internal override { _debtOutstanding; //ignored. we handle it in prepare return //emergency exit is dealt with at beginning of harvest if (emergencyExit) { return; } //we just keep all money in want if we dont have any lenders if (lenders.length == 0) { return; } (uint256 lowest, uint256 lowestApr, uint256 highest, uint256 potential) = estimateAdjustPosition(); if (potential > lowestApr) { //apr should go down after deposit so wont be withdrawing from self lenders[lowest].withdrawAll(); } uint256 bal = want.balanceOf(address(this)); if (bal > 0) { want.safeTransfer(address(lenders[highest]), bal); lenders[highest].deposit(); } } struct lenderRatio { address lender; //share x 1000 uint16 share; } //share must add up to 1000. 500 means 50% etc function manualAllocation(lenderRatio[] memory _newPositions) public onlyAuthorized { uint256 share = 0; for (uint256 i = 0; i < lenders.length; i++) { lenders[i].withdrawAll(); } uint256 assets = want.balanceOf(address(this)); for (uint256 i = 0; i < _newPositions.length; i++) { bool found = false; //might be annoying and expensive to do this second loop but worth it for safety for (uint256 j = 0; j < lenders.length; j++) { if (address(lenders[j]) == _newPositions[i].lender) { found = true; } } require(found, "NOT LENDER"); share = share.add(_newPositions[i].share); uint256 toSend = assets.mul(_newPositions[i].share).div(1000); want.safeTransfer(_newPositions[i].lender, toSend); IGenericLender(_newPositions[i].lender).deposit(); } require(share == 1000, "SHARE!=1000"); } //cycle through withdrawing from worst rate first function _withdrawSome(uint256 _amount) internal returns (uint256 amountWithdrawn) { if (lenders.length == 0) { return 0; } //dont withdraw dust if (_amount < withdrawalThreshold) { return 0; } amountWithdrawn = 0; //most situations this will only run once. Only big withdrawals will be a gas guzzler uint256 j = 0; while (amountWithdrawn < _amount) { uint256 lowestApr = uint256(-1); uint256 lowest = 0; for (uint256 i = 0; i < lenders.length; i++) { if (lenders[i].hasAssets()) { uint256 apr = lenders[i].apr(); if (apr < lowestApr) { lowestApr = apr; lowest = i; } } } if (!lenders[lowest].hasAssets()) { return amountWithdrawn; } amountWithdrawn = amountWithdrawn.add(lenders[lowest].withdraw(_amount - amountWithdrawn)); j++; //dont want infinite loop if (j >= 6) { return amountWithdrawn; } } } /* * Liquidate as many assets as possible to `want`, irregardless of slippage, * up to `_amountNeeded`. Any excess should be re-invested here as well. */ function liquidatePosition(uint256 _amountNeeded) internal override returns (uint256 _amountFreed, uint256 _loss) { uint256 _balance = want.balanceOf(address(this)); if (_balance >= _amountNeeded) { //if we don't set reserve here withdrawer will be sent our full balance return (_amountNeeded, 0); } else { uint256 received = _withdrawSome(_amountNeeded - _balance).add(_balance); if (received >= _amountNeeded) { return (_amountNeeded, 0); } else { return (received, 0); } } } function ethToWant(uint256 _amount) public override view returns (uint256) { address[] memory path = new address[](2); path[0] = weth; path[1] = address(want); uint256[] memory amounts = IUni(uniswapRouter).getAmountsOut(_amount, path); return amounts[amounts.length - 1]; } function _callCostToWant(uint256 callCost) internal view returns (uint256) { uint256 wantCallCost; //three situations //1 currency is eth so no change. //2 we use uniswap swap price //3 we use external oracle if (address(want) == weth) { wantCallCost = callCost; } else if (wantToEthOracle == address(0)) { wantCallCost = ethToWant(callCost); } else { wantCallCost = IWantToEth(wantToEthOracle).ethToWant(callCost); } return wantCallCost; } function tendTrigger(uint256 callCost) public view override returns (bool) { // make sure to call tendtrigger with same callcost as harvestTrigger if (harvestTrigger(callCost)) { return false; } //now let's check if there is better apr somewhere else. //If there is and profit potential is worth changing then lets do it (uint256 lowest, uint256 lowestApr, , uint256 potential) = estimateAdjustPosition(); //if protential > lowestApr it means we are changing horses if (potential > lowestApr) { uint256 nav = lenders[lowest].nav(); //To calculate our potential profit increase we work out how much extra //we would make in a typical harvest interlude. That is maxReportingDelay //then we see if the extra profit is worth more than the gas cost * profitFactor //safe math not needed here //apr is scaled by 1e18 so we downscale here uint256 profitIncrease = (nav.mul(potential) - nav.mul(lowestApr)).div(1e18).mul(maxReportDelay).div(SECONDSPERYEAR); uint256 wantCallCost = _callCostToWant(callCost); return (wantCallCost.mul(profitFactor) < profitIncrease); } } function liquidateAllPositions() internal override returns (uint256 _amountFreed) { _amountFreed = _withdrawSome(lentTotalAssets()); } /* * revert if we can't withdraw full balance */ function prepareMigration(address _newStrategy) internal override { uint256 outstanding = vault.strategies(address(this)).totalDebt; (, uint256 loss, uint256 wantBalance) = prepareReturn(outstanding); } function protectedTokens() internal view override returns (address[] memory) { address[] memory protected = new address[](1); protected[0] = address(want); return protected; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"clone","type":"address"}],"name":"Cloned","type":"event"},{"anonymous":false,"inputs":[],"name":"EmergencyExitEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"profit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"loss","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"debtPayment","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"debtOutstanding","type":"uint256"}],"name":"Harvested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"debtThreshold","type":"uint256"}],"name":"UpdatedDebtThreshold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newKeeper","type":"address"}],"name":"UpdatedKeeper","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"delay","type":"uint256"}],"name":"UpdatedMaxReportDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"metadataURI","type":"string"}],"name":"UpdatedMetadataURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"delay","type":"uint256"}],"name":"UpdatedMinReportDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"profitFactor","type":"uint256"}],"name":"UpdatedProfitFactor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rewards","type":"address"}],"name":"UpdatedRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newStrategist","type":"address"}],"name":"UpdatedStrategist","type":"event"},{"inputs":[],"name":"SECONDSPERYEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"a","type":"address"}],"name":"addLender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"apiVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"clone","outputs":[{"internalType":"address","name":"newStrategy","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_strategist","type":"address"},{"internalType":"address","name":"_rewards","type":"address"},{"internalType":"address","name":"_keeper","type":"address"}],"name":"clone","outputs":[{"internalType":"address","name":"newStrategy","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"debtThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delegatedAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"doHealthCheck","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emergencyExit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"estimateAdjustPosition","outputs":[{"internalType":"uint256","name":"_lowest","type":"uint256"},{"internalType":"uint256","name":"_lowestApr","type":"uint256"},{"internalType":"uint256","name":"_highest","type":"uint256"},{"internalType":"uint256","name":"_potential","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"estimatedAPR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newDebtLimit","type":"uint256"}],"name":"estimatedFutureAPR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"estimatedTotalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"ethToWant","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"externalOracle","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"a","type":"address"}],"name":"forceRemoveLender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"callCostInWei","type":"uint256"}],"name":"harvestTrigger","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"healthCheck","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_strategist","type":"address"},{"internalType":"address","name":"_rewards","type":"address"},{"internalType":"address","name":"_keeper","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"keeper","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lendStatuses","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"uint256","name":"rate","type":"uint256"},{"internalType":"address","name":"add","type":"address"}],"internalType":"struct Strategy.lendStatus[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lenders","outputs":[{"internalType":"contract IGenericLender","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lentTotalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"lender","type":"address"},{"internalType":"uint16","name":"share","type":"uint16"}],"internalType":"struct Strategy.lenderRatio[]","name":"_newPositions","type":"tuple[]"}],"name":"manualAllocation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxReportDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metadataURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newStrategy","type":"address"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minReportDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numLenders","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"profitFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewards","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"a","type":"address"}],"name":"safeRemoveLender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_debtThreshold","type":"uint256"}],"name":"setDebtThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_doHealthCheck","type":"bool"}],"name":"setDoHealthCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setEmergencyExit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_healthCheck","type":"address"}],"name":"setHealthCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_keeper","type":"address"}],"name":"setKeeper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_delay","type":"uint256"}],"name":"setMaxReportDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_metadataURI","type":"string"}],"name":"setMetadataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_delay","type":"uint256"}],"name":"setMinReportDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"}],"name":"setPriceOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_profitFactor","type":"uint256"}],"name":"setProfitFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewards","type":"address"}],"name":"setRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategist","type":"address"}],"name":"setStrategist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_threshold","type":"uint256"}],"name":"setWithdrawalThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"callCost","type":"uint256"}],"name":"tendTrigger","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"contract VaultAPI","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"want","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wantToEthOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountNeeded","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"_loss","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawalThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6080604052662386f26fc10000600c553480156200001c57600080fd5b5060405162005d4738038062005d478339810160408190526200003f9162000516565b806200004e8133808062000063565b505068056bc75e2d63100000600a556200074f565b6006546001600160a01b031615620000985760405162461bcd60e51b81526004016200008f9062000607565b60405180910390fd5b600280546001600160a01b0319166001600160a01b03868116919091179182905560408051637e062a3560e11b81529051929091169163fc0c546a91600480820192602092909190829003018186803b158015620000f557600080fd5b505afa1580156200010a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000130919062000516565b600680546001600160a01b0319166001600160a01b0392831617908190556200016a91168560001962000247602090811b6200337817901c565b600380546001600160a01b038086166001600160a01b03199283161790925560048054858416908316178082556005805486861694169390931790925560006007819055620151806008556064600955600a5560025460405163095ea7b360e01b81529084169363095ea7b393620001ea939116916000199101620005b9565b602060405180830381600087803b1580156200020557600080fd5b505af11580156200021a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000240919062000546565b5050505050565b801580620002d65750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e906200028090309086906004016200059f565b60206040518083038186803b1580156200029957600080fd5b505afa158015620002ae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002d4919062000568565b155b620002f55760405162461bcd60e51b81526004016200008f90620006bf565b620003508363095ea7b360e01b848460405160240162000317929190620005b9565b60408051808303601f190181529190526020810180516001600160e01b0319939093166001600160e01b03938416179052906200035516565b505050565b6060620003b1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316620003f160201b62003472179092919060201c565b805190915015620003505780806020019051810190620003d2919062000546565b620003505760405162461bcd60e51b81526004016200008f9062000675565b60606200040284846000856200040a565b949350505050565b60606200041785620004dc565b620004365760405162461bcd60e51b81526004016200008f906200063e565b60006060866001600160a01b0316858760405162000455919062000581565b60006040518083038185875af1925050503d806000811462000494576040519150601f19603f3d011682016040523d82523d6000602084013e62000499565b606091505b50915091508115620004af579150620004029050565b805115620004c05780518082602001fd5b8360405162461bcd60e51b81526004016200008f9190620005d2565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159062000402575050151592915050565b60006020828403121562000528578081fd5b81516001600160a01b03811681146200053f578182fd5b9392505050565b60006020828403121562000558578081fd5b815180151581146200053f578182fd5b6000602082840312156200057a578081fd5b5051919050565b60008251620005958184602087016200071c565b9190910192915050565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b6000602082528251806020840152620005f38160408501602087016200071c565b601f01601f19169190910160400192915050565b6020808252601c908201527f537472617465677920616c726561647920696e697469616c697a656400000000604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000606082015260800190565b60005b83811015620007395781810151838201526020016200071f565b8381111562000749576000848401525b50505050565b6155e8806200075f6000396000f3fe608060405234801561001057600080fd5b50600436106103995760003560e01c806376ee75d8116101e9578063af306e161161010f578063ec38a862116100ad578063f8c8765e1161007c578063f8c8765e146106c3578063fbfa77cf146106d6578063fcc5f59a146106de578063fcf2d0ad146106f357610399565b8063ec38a86214610682578063ed882c2b14610695578063efbb5cb0146106a8578063f017c92f146106b057610399565b8063c7b9d530116100e9578063c7b9d53014610631578063ce5494bb14610644578063d051184214610657578063d6c382711461066a57610399565b8063af306e1614610619578063b252720b14610621578063bb927c461461062957610399565b80638e6350e21161018757806395e80c501161015657806395e80c50146105ee5780639ec5a894146105f6578063ac00ff26146105fe578063aced16611461061157610399565b80638e6350e2146105ad57806391397ab4146105b5578063929eea21146105c857806393084b34146105db57610399565b80637a4b1c14116101c35780637a4b1c141461056c5780638124b78e1461057f5780638baf2957146105925780638cdfe166146105a557610399565b806376ee75d81461053e578063780022a0146105515780637985fd511461056457610399565b8063397dc149116102ce578063530e784f1161026c5780636718835f1161023b5780636718835f14610508578063735de9f714610510578063748747e614610518578063750521f51461052b57610399565b8063530e784f146104d25780635641ec03146104e55780635a5cd45e146104ed578063650d1880146104f557610399565b8063440368a3116102a8578063440368a3146104a75780634641257d146104af57806346d8cf3f146104b75780634786b0cb146104bf57610399565b8063397dc1491461047957806339a172a81461048c5780633fc8cef31461049f57610399565b80631f1fcd511161033b5780632582941011610315578063258294101461044e57806328b7ccf7146104565780632a5dc8c11461045e5780632e1a7d4d1461046657610399565b80631f1fcd511461041c5780631fe4a6861461043157806322f3e2d41461043957610399565b80630e6e15f0116103775780630e6e15f0146103d95780630f969b87146103ee57806311bc8245146104015780631d12f28b1461041457610399565b806301681a621461039e57806303ee438c146103b357806306fdde03146103d1575b600080fd5b6103b16103ac366004614bef565b6106fb565b005b6103bb61089a565b6040516103c8919061511a565b60405180910390f35b6103bb610928565b6103e1610960565b6040516103c89190615469565b6103b16103fc366004614f64565b610a17565b6103b161040f366004614bef565b610aa4565b6103e1610ba5565b610424610bab565b6040516103c89190614fe9565b610424610bba565b610441610bc9565b6040516103c891906150e0565b6103bb610c6b565b6103e1610c8a565b610424610c90565b6103e1610474366004614f64565b610ca4565b6103e1610487366004614f64565b610cff565b6103b161049a366004614f64565b610dbd565b610424610e3f565b6103b1610e57565b6103b1611080565b610441611559565b6103b16104cd366004614f64565b611562565b6103b16104e0366004614bef565b6115b4565b610441611629565b6103e1611632565b610441610503366004614f64565b6116d1565b61044161181e565b610424611827565b6103b1610526366004614bef565b61183f565b6103b1610539366004614ded565b6118ea565b6103b161054c366004614bef565b611981565b6103e161055f366004614f64565b6119dc565b6103e1611b1a565b6103b161057a366004614c82565b611b20565b61042461058d366004614bef565b611e68565b6103b16105a0366004614bef565b611eec565b6103e1611f44565b6103e1611f4a565b6103b16105c3366004614f64565b611f4f565b6104246105d6366004614f64565b611fd1565b6103b16105e9366004614bef565b611ff8565b6103e1612183565b610424612189565b6103b161060c366004614db5565b612198565b610424612284565b6103e1612293565b61042461229b565b6103e16122af565b6103b161063f366004614bef565b6122b5565b6103b1610652366004614bef565b612360565b610424610665366004614c27565b6124ab565b610672612598565b6040516103c894939291906154de565b6103b1610690366004614bef565b61297e565b6104416106a3366004614f64565b612b11565b6103e1612d9b565b6103b16106be366004614f64565b612e3a565b6103b16106d1366004614c27565b612ebc565b610424612ece565b6106e6612edd565b6040516103c8919061505b565b6103b1613153565b610703613489565b6001600160a01b0316336001600160a01b03161461073c5760405162461bcd60e51b815260040161073390615357565b60405180910390fd5b6006546001600160a01b038281169116141561076a5760405162461bcd60e51b81526004016107339061517b565b6002546001600160a01b03828116911614156107985760405162461bcd60e51b8152600401610733906152d8565b60606107a2613506565b905060005b81518110156107fd578181815181106107bc57fe5b60200260200101516001600160a01b0316836001600160a01b031614156107f55760405162461bcd60e51b8152600401610733906153c6565b6001016107a7565b50610896610809613489565b6040516370a0823160e01b81526001600160a01b038516906370a0823190610835903090600401614fe9565b60206040518083038186803b15801561084d57600080fd5b505afa158015610861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108859190614f7c565b6001600160a01b0385169190613562565b5050565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109205780601f106108f557610100808354040283529160200191610920565b820191906000526020600020905b81548152906001019060200180831161090357829003601f168201915b505050505081565b60408051808201909152601c81527f53747261746567794c656e6465725969656c644f7074696d697365720000000060208201525b90565b600080805b600d54811015610a1157610a07600d828154811061097f57fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b1580156109c857600080fd5b505afa1580156109dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a009190614f7c565b8390613581565b9150600101610965565b50905090565b6003546001600160a01b0316331480610a485750610a33613489565b6001600160a01b0316336001600160a01b0316145b610a645760405162461bcd60e51b815260040161073390615357565b600a8190556040517fa68ba126373d04c004c5748c300c9fca12bd444b3d4332e261f3bd2bac4a860090610a99908390615469565b60405180910390a150565b600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b158015610af257600080fd5b505afa158015610b06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2a9190614c0b565b6001600160a01b0316336001600160a01b03161480610b615750610b4c613489565b6001600160a01b0316336001600160a01b0316145b610b7d5760405162461bcd60e51b815260040161073390615357565b600180546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600a5481565b6006546001600160a01b031681565b6003546001600160a01b031681565b6002546040516339ebf82360e01b815260009182916001600160a01b03909116906339ebf82390610bfe903090600401614fe9565b6101206040518083038186803b158015610c1757600080fd5b505afa158015610c2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4f9190614ee6565b604001511180610c6657506000610c64612d9b565b115b905090565b604080518082019091526005815264302e342e3360d81b602082015290565b60085481565b600e5461010090046001600160a01b031681565b6002546000906001600160a01b03163314610cd15760405162461bcd60e51b8152600401610733906152b8565b6000610cdc836135ad565b600654909350909150610cf9906001600160a01b03163383613562565b50919050565b6002546040516339ebf82360e01b815260009182916001600160a01b03909116906339ebf82390610d34903090600401614fe9565b6101206040518083038186803b158015610d4d57600080fd5b505afa158015610d61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d859190614ee6565b60c001519050600083821015610dab5750808303610da281613688565b92505050610db8565b50828103610da281613849565b919050565b6003546001600160a01b0316331480610dee5750610dd9613489565b6001600160a01b0316336001600160a01b0316145b610e0a5760405162461bcd60e51b815260040161073390615357565b60078190556040517fbb2c369a0355a34b02ab5fce0643150c87e1c8dfe7c918d465591879f57948b190610a99908390615469565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6005546001600160a01b0316331480610e7a57506003546001600160a01b031633145b80610e9d5750610e88613489565b6001600160a01b0316336001600160a01b0316145b80610f3e5750600260009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b158015610ef157600080fd5b505afa158015610f05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f299190614c0b565b6001600160a01b0316336001600160a01b0316145b80610fdf5750600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b158015610f9257600080fd5b505afa158015610fa6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fca9190614c0b565b6001600160a01b0316336001600160a01b0316145b610ffb5760405162461bcd60e51b815260040161073390615357565b6002546040805163bf3759b560e01b8152905161107e926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110799190614f7c565b613a1d565b565b6005546001600160a01b03163314806110a357506003546001600160a01b031633145b806110c657506110b1613489565b6001600160a01b0316336001600160a01b0316145b806111675750600260009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b15801561111a57600080fd5b505afa15801561112e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111529190614c0b565b6001600160a01b0316336001600160a01b0316145b806112085750600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b1580156111bb57600080fd5b505afa1580156111cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f39190614c0b565b6001600160a01b0316336001600160a01b0316145b6112245760405162461bcd60e51b815260040161073390615357565b6000806000600260009054906101000a90046001600160a01b03166001600160a01b031663bf3759b56040518163ffffffff1660e01b815260040160206040518083038186803b15801561127757600080fd5b505afa15801561128b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112af9190614f7c565b600b5490915060009060ff161561130c5760006112ca613c27565b9050828110156112e5576112de8382613c39565b93506112fa565b828111156112fa576112f78184613c39565b94505b6113048385613c39565b91505061131d565b61131582613c7b565b919550935090505b6002546040516339ebf82360e01b81526000916001600160a01b0316906339ebf8239061134e903090600401614fe9565b6101206040518083038186803b15801561136757600080fd5b505afa15801561137b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139f9190614ee6565b60c001516002546040516328766ebf60e21b81529192506001600160a01b03169063a1d9bafc906113d8908890889087906004016154c8565b602060405180830381600087803b1580156113f257600080fd5b505af1158015611406573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142a9190614f7c565b925061143583613a1d565b60015460ff168015611456575060015461010090046001600160a01b031615155b156115085760015460405163c70fa00b60e01b81526101009091046001600160a01b03169063c70fa00b9061149790889088908790899088906004016154f9565b60206040518083038186803b1580156114af57600080fd5b505afa1580156114c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e79190614dd1565b6115035760405162461bcd60e51b81526004016107339061521a565b611515565b6001805460ff1916811790555b7f4c0f499ffe6befa0ca7c826b0916cf87bea98de658013e76938489368d60d5098585848660405161154a94939291906154de565b60405180910390a15050505050565b600e5460ff1681565b6003546001600160a01b0316331480611593575061157e613489565b6001600160a01b0316336001600160a01b0316145b6115af5760405162461bcd60e51b815260040161073390615357565b600c55565b6003546001600160a01b03163314806115e557506115d0613489565b6001600160a01b0316336001600160a01b0316145b6116015760405162461bcd60e51b815260040161073390615357565b600e80546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600b5460ff1681565b60008061163d612d9b565b90508061164e57600091505061095d565b6000805b600d548110156116bf576116b5600d828154811061166c57fe5b600091825260209182902001546040805163116ac4a360e01b815290516001600160a01b039092169263116ac4a392600480840193829003018186803b1580156109c857600080fd5b9150600101611652565b506116ca8183613fa5565b9250505090565b60006116dc82612b11565b156116e957506000610db8565b60008060006116f6612598565b9350509250925081811115611816576000600d848154811061171457fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b15801561175d57600080fd5b505afa158015611771573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117959190614f7c565b905060006117e36301e185586117dd6008546117d7670de0b6b3a76400006117c68a89613fe790919063ffffffff16565b6117d0898b613fe7565b0390613fa5565b90613fe7565b90613fa5565b905060006117f088614021565b90508161180860095483613fe790919063ffffffff16565b109650505050505050610db8565b505050919050565b60015460ff1681565b737a250d5630b4cf539739df2c5dacb4c659f2488d81565b6003546001600160a01b0316331480611870575061185b613489565b6001600160a01b0316336001600160a01b0316145b61188c5760405162461bcd60e51b815260040161073390615357565b6001600160a01b03811661189f57600080fd5b600580546001600160a01b0319166001600160a01b0383161790556040517f2f202ddb4a2e345f6323ed90f8fc8559d770a7abbbeee84dde8aca3351fe715490610a99908390614fe9565b6003546001600160a01b031633148061191b5750611906613489565b6001600160a01b0316336001600160a01b0316145b6119375760405162461bcd60e51b815260040161073390615357565b61194360008383614a95565b507f300e67d5a415b6d015a471d9c7b95dd58f3e8290af965e84e0f845de2996dda682826040516119759291906150eb565b60405180910390a15050565b6003546001600160a01b03163314806119b2575061199d613489565b6001600160a01b0316336001600160a01b0316145b6119ce5760405162461bcd60e51b815260040161073390615357565b6119d98160016140fd565b50565b604080516002808252606080830184526000939092919060208301908036833701905050905073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281600081518110611a2457fe5b6001600160a01b039283166020918202929092010152600654825191169082906001908110611a4f57fe5b6001600160a01b039092166020928302919091019091015260405163d06ca61f60e01b8152606090737a250d5630b4cf539739df2c5dacb4c659f2488d9063d06ca61f90611aa39087908690600401615472565b60006040518083038186803b158015611abb57600080fd5b505afa158015611acf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611af79190810190614d25565b905080600182510381518110611b0957fe5b602002602001015192505050919050565b600c5481565b6003546001600160a01b0316331480611b515750611b3c613489565b6001600160a01b0316336001600160a01b0316145b611b6d5760405162461bcd60e51b815260040161073390615357565b6000805b600d54811015611c2157600d8181548110611b8857fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b158015611be057600080fd5b505af1158015611bf4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c189190614dd1565b50600101611b71565b506006546040516370a0823160e01b81526000916001600160a01b0316906370a0823190611c53903090600401614fe9565b60206040518083038186803b158015611c6b57600080fd5b505afa158015611c7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca39190614f7c565b905060005b8351811015611e41576000805b600d54811015611d1557858381518110611ccb57fe5b6020026020010151600001516001600160a01b0316600d8281548110611ced57fe5b6000918252602090912001546001600160a01b03161415611d0d57600191505b600101611cb5565b5080611d335760405162461bcd60e51b8152600401610733906151f6565b611d61858381518110611d4257fe5b60200260200101516020015161ffff168561358190919063ffffffff16565b93506000611d996103e86117dd888681518110611d7a57fe5b60200260200101516020015161ffff1687613fe790919063ffffffff16565b9050611dc9868481518110611daa57fe5b6020908102919091010151516006546001600160a01b03169083613562565b858381518110611dd557fe5b6020026020010151600001516001600160a01b031663d0e30db06040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611e1b57600080fd5b505af1158015611e2f573d6000803e3d6000fd5b505060019094019350611ca892505050565b50816103e814611e635760405162461bcd60e51b81526004016107339061519a565b505050565b6040516368288c2160e11b8152600090309063d051184290611e94908590339081908190600401615017565b602060405180830381600087803b158015611eae57600080fd5b505af1158015611ec2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee69190614c0b565b92915050565b6003546001600160a01b0316331480611f1d5750611f08613489565b6001600160a01b0316336001600160a01b0316145b611f395760405162461bcd60e51b815260040161073390615357565b6119d98160006140fd565b60095481565b600090565b6003546001600160a01b0316331480611f805750611f6b613489565b6001600160a01b0316336001600160a01b0316145b611f9c5760405162461bcd60e51b815260040161073390615357565b60098190556040517fd94596337df4c2f0f44d30a7fc5db1c7bb60d9aca4185ed77c6fd96eb45ec29890610a99908390615469565b600d8181548110611fde57fe5b6000918252602090912001546001600160a01b0316905081565b612000613489565b6001600160a01b0316336001600160a01b0316146120305760405162461bcd60e51b815260040161073390615357565b6000819050306001600160a01b0316816001600160a01b031663a8c62e766040518163ffffffff1660e01b815260040160206040518083038186803b15801561207857600080fd5b505afa15801561208c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120b09190614c0b565b6001600160a01b0316146120d65760405162461bcd60e51b815260040161073390615152565b60005b600d5481101561212f57600d81815481106120f057fe5b6000918252602090912001546001600160a01b03848116911614156121275760405162461bcd60e51b8152600401610733906152f9565b6001016120d9565b50600d80546001810182556000919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b0319166001600160a01b039290921691909117905550565b60075481565b6004546001600160a01b031681565b600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b1580156121e657600080fd5b505afa1580156121fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221e9190614c0b565b6001600160a01b0316336001600160a01b031614806122555750612240613489565b6001600160a01b0316336001600160a01b0316145b6122715760405162461bcd60e51b815260040161073390615357565b6001805460ff1916911515919091179055565b6005546001600160a01b031681565b6301e1855881565b60015461010090046001600160a01b031681565b600d5490565b6003546001600160a01b03163314806122e657506122d1613489565b6001600160a01b0316336001600160a01b0316145b6123025760405162461bcd60e51b815260040161073390615357565b6001600160a01b03811661231557600080fd5b600380546001600160a01b0319166001600160a01b0383161790556040517f352ececae6d7d1e6d26bcf2c549dfd55be1637e9b22dc0cf3b71ddb36097a6b490610a99908390614fe9565b6002546001600160a01b0316331461237757600080fd5b6002546040805163fbfa77cf60e01b815290516001600160a01b039283169284169163fbfa77cf916004808301926020929190829003018186803b1580156123be57600080fd5b505afa1580156123d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123f69190614c0b565b6001600160a01b03161461240957600080fd5b61241281614355565b6006546040516370a0823160e01b81526119d99183916001600160a01b03909116906370a0823190612448903090600401614fe9565b60206040518083038186803b15801561246057600080fd5b505afa158015612474573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124989190614f7c565b6006546001600160a01b03169190613562565b604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81523060601b601482018190526e5af43d82803e903d91602b57fd5bf360881b602883015260009160378184f0604051637c643b2f60e11b81529093506001600160a01b038416915063f8c8765e90612529908990899089908990600401615017565b600060405180830381600087803b15801561254357600080fd5b505af1158015612557573d6000803e3d6000fd5b50506040516001600160a01b03851692507f783540fb4221a3238720dc7038937d0d79982bcf895274aa6ad179f82cf0d53c9150600090a250949350505050565b6006546040516370a0823160e01b815260009182918291829182916001600160a01b0316906370a08231906125d1903090600401614fe9565b60206040518083038186803b1580156125e957600080fd5b505afa1580156125fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126219190614f7c565b90506000199350600094506000805b600d5481101561280857600d818154811061264757fe5b6000918252602091829020015460408051635be9b2d360e01b815290516001600160a01b0390921692635be9b2d392600480840193829003018186803b15801561269057600080fd5b505afa1580156126a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c89190614dd1565b15612800576000600d82815481106126dc57fe5b60009182526020918290200154604080516357ded9c960e01b815290516001600160a01b03909216926357ded9c992600480840193829003018186803b15801561272557600080fd5b505afa158015612739573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061275d9190614f7c565b9050868110156127fe57809650819750600d828154811061277a57fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b1580156127c357600080fd5b505afa1580156127d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127fb9190614f7c565b92505b505b600101612630565b5060006128158284613581565b9050600080955060005b600d548110156128db576000600d828154811061283857fe5b60009182526020909120015460405163052692b960e21b81526001600160a01b039091169063149a4ae490612871908990600401615469565b60206040518083038186803b15801561288957600080fd5b505afa15801561289d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128c19190614f7c565b9050828111156128d2578092508197505b5060010161281f565b50600d86815481106128e957fe5b60009182526020909120015460405163052692b960e21b81526001600160a01b039091169063149a4ae490612922908590600401615469565b60206040518083038186803b15801561293a57600080fd5b505afa15801561294e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129729190614f7c565b94505050505090919293565b6003546001600160a01b031633146129a85760405162461bcd60e51b81526004016107339061512d565b6001600160a01b0381166129bb57600080fd5b6002546004805460405163095ea7b360e01b81526001600160a01b039384169363095ea7b3936129f2939091169160009101615042565b602060405180830381600087803b158015612a0c57600080fd5b505af1158015612a20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a449190614dd1565b50600480546001600160a01b0319166001600160a01b038381169190911780835560025460405163095ea7b360e01b81529083169363095ea7b393612a8f9316916000199101615042565b602060405180830381600087803b158015612aa957600080fd5b505af1158015612abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ae19190614dd1565b507fafbb66abf8f3b719799940473a4052a3717cdd8e40fb6c8a3faadab316b1a06981604051610a999190614fe9565b600080612b1d836119dc565b9050612b27614b13565b6002546040516339ebf82360e01b81526001600160a01b03909116906339ebf82390612b57903090600401614fe9565b6101206040518083038186803b158015612b7057600080fd5b505afa158015612b84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ba89190614ee6565b9050806020015160001415612bc257600092505050610db8565b60075460a0820151612bd5904290613c39565b1015612be657600092505050610db8565b60085460a0820151612bf9904290613c39565b10612c0957600192505050610db8565b6002546040805163bf3759b560e01b815290516000926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b158015612c4e57600080fd5b505afa158015612c62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c869190614f7c565b9050600a54811115612c9e5760019350505050610db8565b6000612ca8612d9b565b90508260c00151612cc4600a548361358190919063ffffffff16565b1015612cd7576001945050505050610db8565b60008360c00151821115612cf85760c0840151612cf5908390613c39565b90505b6002546040805163112c1f9b60e01b815290516000926001600160a01b03169163112c1f9b916004808301926020929190829003018186803b158015612d3d57600080fd5b505afa158015612d51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d759190614f7c565b9050612d818183613581565b600954612d8e9088613fe7565b1098975050505050505050565b600080612da6610960565b6006546040516370a0823160e01b8152919250612e34916001600160a01b03909116906370a0823190612ddd903090600401614fe9565b60206040518083038186803b158015612df557600080fd5b505afa158015612e09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e2d9190614f7c565b8290613581565b91505090565b6003546001600160a01b0316331480612e6b5750612e56613489565b6001600160a01b0316336001600160a01b0316145b612e875760405162461bcd60e51b815260040161073390615357565b60088190556040517f5430e11864ad7aa9775b07d12657fe52df9aa2ba734355bd8ef8747be2c800c590610a99908390615469565b612ec8848484846143f2565b50505050565b6002546001600160a01b031681565b600d54606090819067ffffffffffffffff81118015612efb57600080fd5b50604051908082528060200260200182016040528015612f3557816020015b612f22614b5f565b815260200190600190039081612f1a5790505b50905060005b600d54811015610a1157612f4d614b5f565b600d8281548110612f5a57fe5b60009182526020822001546040805163459010bb60e11b815290516001600160a01b0390921692638b20217692600480840193829003018186803b158015612fa157600080fd5b505afa158015612fb5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612fdd9190810190614e5a565b8152600d805483908110612fed57fe5b6000918252602090912001546001600160a01b03166060820152600d80548390811061301557fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b15801561305e57600080fd5b505afa158015613072573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130969190614f7c565b6020820152600d8054839081106130a957fe5b60009182526020918290200154604080516357ded9c960e01b815290516001600160a01b03909216926357ded9c992600480840193829003018186803b1580156130f257600080fd5b505afa158015613106573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061312a9190614f7c565b60408201528251819084908490811061313f57fe5b602090810291909101015250600101612f3b565b6003546001600160a01b0316331480613184575061316f613489565b6001600160a01b0316336001600160a01b0316145b806132255750600260009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b1580156131d857600080fd5b505afa1580156131ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132109190614c0b565b6001600160a01b0316336001600160a01b0316145b806132c65750600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b15801561327957600080fd5b505afa15801561328d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132b19190614c0b565b6001600160a01b0316336001600160a01b0316145b6132e25760405162461bcd60e51b815260040161073390615357565b600b805460ff191660011790556002546040805163507257cd60e11b815290516001600160a01b039092169163a0e4af9a9160048082019260009290919082900301818387803b15801561333557600080fd5b505af1158015613349573d6000803e3d6000fd5b50506040517f97e963041e952738788b9d4871d854d282065b8f90a464928d6528f2e9a4fd0b925060009150a1565b8015806134005750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e906133ae9030908690600401614ffd565b60206040518083038186803b1580156133c657600080fd5b505afa1580156133da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133fe9190614f7c565b155b61341c5760405162461bcd60e51b815260040161073390615413565b611e638363095ea7b360e01b848460405160240161343b929190615042565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526145b2565b60606134818484600085614641565b949350505050565b60025460408051635aa6e67560e01b815290516000926001600160a01b031691635aa6e675916004808301926020929190829003018186803b1580156134ce57600080fd5b505afa1580156134e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c669190614c0b565b60408051600180825281830190925260609182919060208083019080368337505060065482519293506001600160a01b03169183915060009061354557fe5b6001600160a01b0390921660209283029190910190910152905090565b611e638363a9059cbb60e01b848460405160240161343b929190615042565b6000828201838110156135a65760405162461bcd60e51b8152600401610733906151bf565b9392505050565b6006546040516370a0823160e01b8152600091829182916001600160a01b0316906370a08231906135e2903090600401614fe9565b60206040518083038186803b1580156135fa57600080fd5b505afa15801561360e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136329190614f7c565b9050838110613648578360009250925050613683565b600061365f82613659848803614705565b90613581565b905084811061367657846000935093505050613683565b9250600091506136839050565b915091565b6000808080805b600d548110156137db576000600d82815481106136a857fe5b60009182526020909120015460405163052692b960e21b81526001600160a01b039091169063149a4ae4906136e1908a90600401615469565b60206040518083038186803b1580156136f957600080fd5b505afa15801561370d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137319190614f7c565b9050848111156137d257819350809450600d828154811061374e57fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b15801561379757600080fd5b505afa1580156137ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137cf9190614f7c565b92505b5060010161368f565b5060006137f26137eb8388613581565b8590613fe7565b905060005b600d548110156138235783811461381b57613818600d828154811061166c57fe5b91505b6001016137f7565b50600061383287613659612d9b565b905061383e8282613fa5565b979650505050505050565b600060001981805b600d5481101561390d576000600d828154811061386a57fe5b60009182526020909120015460405163052692b960e21b81526001600160a01b039091169063149a4ae4906138a3908990600401615469565b60206040518083038186803b1580156138bb57600080fd5b505afa1580156138cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f39190614f7c565b905083811015613904578192508093505b50600101613851565b506000805b600d548110156139f85782811461393a57613933600d828154811061166c57fe5b91506139f0565b6000600d828154811061394957fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b15801561399257600080fd5b505afa1580156139a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139ca9190614f7c565b9050868110156139d8578096505b6139ec6139e58689613fe7565b8490613581565b9250505b600101613912565b506000613a0786613659612d9b565b9050613a138282613fa5565b9695505050505050565b600b5460ff1615613a2d576119d9565b600d54613a39576119d9565b600080600080613a47612598565b935093509350935082811115613af657600d8481548110613a6457fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b158015613abc57600080fd5b505af1158015613ad0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613af49190614dd1565b505b6006546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613b27903090600401614fe9565b60206040518083038186803b158015613b3f57600080fd5b505afa158015613b53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b779190614f7c565b90508015613c1f57613bb1600d8481548110613b8f57fe5b6000918252602090912001546006546001600160a01b03908116911683613562565b600d8381548110613bbe57fe5b600091825260208220015460408051630d0e30db60e41b815290516001600160a01b039092169263d0e30db09260048084019382900301818387803b158015613c0657600080fd5b505af1158015613c1a573d6000803e3d6000fd5b505050505b505050505050565b6000610c66613c34610960565b614705565b60006135a683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506149e3565b6000808281613c88610960565b6006546040516370a0823160e01b81529192506000916001600160a01b03909116906370a0823190613cbe903090600401614fe9565b60206040518083038186803b158015613cd657600080fd5b505afa158015613cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d0e9190614f7c565b90506000613d1c8284613581565b905082613d375781841115613d2f578193505b505050613f9e565b6002546040516339ebf82360e01b81526000916001600160a01b0316906339ebf82390613d68903090600401614fe9565b6101206040518083038186803b158015613d8157600080fd5b505afa158015613d95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613db99190614ee6565b60c00151905080821115613eb25780820396506000613dd88887613581565b9050600081118015613de957508084105b15613eac57613dfb613c348286613c39565b506006546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613e2d903090600401614fe9565b60206040518083038186803b158015613e4557600080fd5b505afa158015613e59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e7d9190614f7c565b905081811015613eaa5780891115613e9b5780985060009650613eaa565b613ea789820388614a0f565b96505b505b50613f99565b81810395506000613ec38787613581565b9050600081118015613ed457508084105b15613f9757613ee6613c348286613c39565b506006546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613f18903090600401614fe9565b60206040518083038186803b158015613f3057600080fd5b505afa158015613f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f689190614f7c565b905081811015613f955780881115613f865780975060009650613f95565b613f9288820388614a0f565b96505b505b505b505050505b9193909250565b60006135a683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614a25565b600082613ff657506000611ee6565b8282028284828161400357fe5b04146135a65760405162461bcd60e51b815260040161073390615277565b60065460009081906001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21415614054575081611ee6565b600e5461010090046001600160a01b031661407957614072836119dc565b9050611ee6565b600e546040516303c0011560e51b81526101009091046001600160a01b03169063780022a0906140ad908690600401615469565b60206040518083038186803b1580156140c557600080fd5b505afa1580156140d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135a69190614f7c565b60005b600d5481101561433c57600d818154811061411757fe5b6000918252602090912001546001600160a01b0384811691161415614334576000600d828154811061414557fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561419d57600080fd5b505af11580156141b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141d59190614dd1565b9050826141f957806141f95760405162461bcd60e51b8152600401610733906153ea565b600d5460001901821461426d57600d8054600019810190811061421857fe5b600091825260209091200154600d80546001600160a01b03909216918490811061423e57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b600d80548061427857fe5b600082815260208120600019908301810180546001600160a01b03191690559091019091556006546040516370a0823160e01b81526001600160a01b03909116906370a08231906142cd903090600401614fe9565b60206040518083038186803b1580156142e557600080fd5b505afa1580156142f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061431d9190614f7c565b111561432d5761432d6000613a1d565b5050610896565b600101614100565b5060405162461bcd60e51b8152600401610733906151f6565b6002546040516339ebf82360e01b81526000916001600160a01b0316906339ebf82390614386903090600401614fe9565b6101206040518083038186803b15801561439f57600080fd5b505afa1580156143b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143d79190614ee6565b60c0015190506000806143e983613c7b565b50505050505050565b6006546001600160a01b03161561441b5760405162461bcd60e51b815260040161073390615240565b600280546001600160a01b0319166001600160a01b03868116919091179182905560408051637e062a3560e11b81529051929091169163fc0c546a91600480820192602092909190829003018186803b15801561447757600080fd5b505afa15801561448b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144af9190614c0b565b600680546001600160a01b0319166001600160a01b0392831617908190556144db911685600019613378565b600380546001600160a01b038086166001600160a01b03199283161790925560048054858416908316178082556005805486861694169390931790925560006007819055620151806008556064600955600a5560025460405163095ea7b360e01b81529084169363095ea7b393614559939116916000199101615042565b602060405180830381600087803b15801561457357600080fd5b505af1158015614587573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145ab9190614dd1565b5050505050565b6060614607826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166134729092919063ffffffff16565b805190915015611e6357808060200190518101906146259190614dd1565b611e635760405162461bcd60e51b81526004016107339061537c565b606061464c85614a5c565b6146685760405162461bcd60e51b815260040161073390615320565b60006060866001600160a01b031685876040516146859190614fcd565b60006040518083038185875af1925050503d80600081146146c2576040519150601f19603f3d011682016040523d82523d6000602084013e6146c7565b606091505b509150915081156146db5791506134819050565b8051156146eb5780518082602001fd5b8360405162461bcd60e51b8152600401610733919061511a565b600d5460009061471757506000610db8565b600c5482101561472957506000610db8565b506000805b82821015610cf9576000196000805b600d5481101561488557600d818154811061475457fe5b6000918252602091829020015460408051635be9b2d360e01b815290516001600160a01b0390921692635be9b2d392600480840193829003018186803b15801561479d57600080fd5b505afa1580156147b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147d59190614dd1565b1561487d576000600d82815481106147e957fe5b60009182526020918290200154604080516357ded9c960e01b815290516001600160a01b03909216926357ded9c992600480840193829003018186803b15801561483257600080fd5b505afa158015614846573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061486a9190614f7c565b90508381101561487b578093508192505b505b60010161473d565b50600d818154811061489357fe5b6000918252602091829020015460408051635be9b2d360e01b815290516001600160a01b0390921692635be9b2d392600480840193829003018186803b1580156148dc57600080fd5b505afa1580156148f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149149190614dd1565b61492057505050610db8565b6149c4600d828154811061493057fe5b600091825260209091200154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d9061496b90888a0390600401615469565b602060405180830381600087803b15801561498557600080fd5b505af1158015614999573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149bd9190614f7c565b8590613581565b9350600190920191600683106149dc57505050610db8565b505061472e565b60008184841115614a075760405162461bcd60e51b8152600401610733919061511a565b505050900390565b6000818310614a1e57816135a6565b5090919050565b60008183614a465760405162461bcd60e51b8152600401610733919061511a565b506000838581614a5257fe5b0495945050505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590613481575050151592915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614ad65782800160ff19823516178555614b03565b82800160010185558215614b03579182015b82811115614b03578235825591602001919060010190614ae8565b50614b0f929150614b90565b5090565b6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604051806080016040528060608152602001600081526020016000815260200160006001600160a01b031681525090565b5b80821115614b0f5760008155600101614b91565b600060408284031215614bb6578081fd5b614bc0604061551c565b90508135614bcd8161558f565b8152602082013561ffff81168114614be457600080fd5b602082015292915050565b600060208284031215614c00578081fd5b81356135a68161558f565b600060208284031215614c1c578081fd5b81516135a68161558f565b60008060008060808587031215614c3c578283fd5b8435614c478161558f565b93506020850135614c578161558f565b92506040850135614c678161558f565b91506060850135614c778161558f565b939692955090935050565b60006020808385031215614c94578182fd5b823567ffffffffffffffff811115614caa578283fd5b8301601f81018513614cba578283fd5b8035614ccd614cc882615543565b61551c565b818152838101908385016040808502860187018a1015614ceb578788fd5b8795505b84861015614d1757614d018a83614ba5565b8452600195909501949286019290810190614cef565b509098975050505050505050565b60006020808385031215614d37578182fd5b825167ffffffffffffffff811115614d4d578283fd5b8301601f81018513614d5d578283fd5b8051614d6b614cc882615543565b8181528381019083850185840285018601891015614d87578687fd5b8694505b83851015614da9578051835260019490940193918501918501614d8b565b50979650505050505050565b600060208284031215614dc6578081fd5b81356135a6816155a4565b600060208284031215614de2578081fd5b81516135a6816155a4565b60008060208385031215614dff578182fd5b823567ffffffffffffffff80821115614e16578384fd5b818501915085601f830112614e29578384fd5b813581811115614e37578485fd5b866020828501011115614e48578485fd5b60209290920196919550909350505050565b600060208284031215614e6b578081fd5b815167ffffffffffffffff80821115614e82578283fd5b818401915084601f830112614e95578283fd5b815181811115614ea3578384fd5b614eb6601f8201601f191660200161551c565b9150808252856020828501011115614ecc578384fd5b614edd816020840160208601615563565b50949350505050565b6000610120808385031215614ef9578182fd5b614f028161551c565b9050825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152508091505092915050565b600060208284031215614f75578081fd5b5035919050565b600060208284031215614f8d578081fd5b5051919050565b6001600160a01b03169052565b60008151808452614fb9816020860160208601615563565b601f01601f19169290920160200192915050565b60008251614fdf818460208701615563565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03948516815292841660208401529083166040830152909116606082015260800190565b6001600160a01b03929092168252602082015260400190565b60208082528251828201819052600091906040908185019080840286018301878501865b83811015614d1757603f198984030185528151608081518186526150a582870182614fa1565b9150508882015189860152878201518886015260608083015192506150cc81870184614f94565b50958801959350509086019060010161507f565b901515815260200190565b60006020825282602083015282846040840137818301604090810191909152601f909201601f19160101919050565b6000602082526135a66020830184614fa1565b6020808252600b908201526a085cdd1c985d1959da5cdd60aa1b604082015260600190565b6020808252600f908201526e2ab73237b1b5b2b2102632b73232b960891b604082015260600190565b602080825260059082015264085dd85b9d60da1b604082015260600190565b6020808252600b908201526a05348415245213d313030360ac1b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600a90820152692727aa102622a72222a960b11b604082015260600190565b6020808252600c908201526b216865616c7468636865636b60a01b604082015260600190565b6020808252601c908201527f537472617465677920616c726561647920696e697469616c697a656400000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260069082015265085d985d5b1d60d21b604082015260600190565b6020808252600790820152662173686172657360c81b604082015260600190565b6020808252600d908201526c105b1c9958591e481059191959609a1b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600b908201526a08585d5d1a1bdc9a5e995960aa1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600a9082015269085c1c9bdd1958dd195960b21b604082015260600190565b6020808252600f908201526e15d2551211149055c8119052531151608a1b604082015260600190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b90815260200190565b60006040820184835260206040818501528185518084526060860191508287019350845b818110156154bb5784516001600160a01b031683529383019391830191600101615496565b5090979650505050505050565b9283526020830191909152604082015260600190565b93845260208401929092526040830152606082015260800190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff8111828210171561553b57600080fd5b604052919050565b600067ffffffffffffffff821115615559578081fd5b5060209081020190565b60005b8381101561557e578181015183820152602001615566565b83811115612ec85750506000910152565b6001600160a01b03811681146119d957600080fd5b80151581146119d957600080fdfea26469706673582212207a224399c14c11ec8e7f566fabefc939a638034f3ad5dd97286939b9860a8e5f64736f6c634300060c0033000000000000000000000000da816459f1ab5631232fe5e97a05bbbb94970c95
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103995760003560e01c806376ee75d8116101e9578063af306e161161010f578063ec38a862116100ad578063f8c8765e1161007c578063f8c8765e146106c3578063fbfa77cf146106d6578063fcc5f59a146106de578063fcf2d0ad146106f357610399565b8063ec38a86214610682578063ed882c2b14610695578063efbb5cb0146106a8578063f017c92f146106b057610399565b8063c7b9d530116100e9578063c7b9d53014610631578063ce5494bb14610644578063d051184214610657578063d6c382711461066a57610399565b8063af306e1614610619578063b252720b14610621578063bb927c461461062957610399565b80638e6350e21161018757806395e80c501161015657806395e80c50146105ee5780639ec5a894146105f6578063ac00ff26146105fe578063aced16611461061157610399565b80638e6350e2146105ad57806391397ab4146105b5578063929eea21146105c857806393084b34146105db57610399565b80637a4b1c14116101c35780637a4b1c141461056c5780638124b78e1461057f5780638baf2957146105925780638cdfe166146105a557610399565b806376ee75d81461053e578063780022a0146105515780637985fd511461056457610399565b8063397dc149116102ce578063530e784f1161026c5780636718835f1161023b5780636718835f14610508578063735de9f714610510578063748747e614610518578063750521f51461052b57610399565b8063530e784f146104d25780635641ec03146104e55780635a5cd45e146104ed578063650d1880146104f557610399565b8063440368a3116102a8578063440368a3146104a75780634641257d146104af57806346d8cf3f146104b75780634786b0cb146104bf57610399565b8063397dc1491461047957806339a172a81461048c5780633fc8cef31461049f57610399565b80631f1fcd511161033b5780632582941011610315578063258294101461044e57806328b7ccf7146104565780632a5dc8c11461045e5780632e1a7d4d1461046657610399565b80631f1fcd511461041c5780631fe4a6861461043157806322f3e2d41461043957610399565b80630e6e15f0116103775780630e6e15f0146103d95780630f969b87146103ee57806311bc8245146104015780631d12f28b1461041457610399565b806301681a621461039e57806303ee438c146103b357806306fdde03146103d1575b600080fd5b6103b16103ac366004614bef565b6106fb565b005b6103bb61089a565b6040516103c8919061511a565b60405180910390f35b6103bb610928565b6103e1610960565b6040516103c89190615469565b6103b16103fc366004614f64565b610a17565b6103b161040f366004614bef565b610aa4565b6103e1610ba5565b610424610bab565b6040516103c89190614fe9565b610424610bba565b610441610bc9565b6040516103c891906150e0565b6103bb610c6b565b6103e1610c8a565b610424610c90565b6103e1610474366004614f64565b610ca4565b6103e1610487366004614f64565b610cff565b6103b161049a366004614f64565b610dbd565b610424610e3f565b6103b1610e57565b6103b1611080565b610441611559565b6103b16104cd366004614f64565b611562565b6103b16104e0366004614bef565b6115b4565b610441611629565b6103e1611632565b610441610503366004614f64565b6116d1565b61044161181e565b610424611827565b6103b1610526366004614bef565b61183f565b6103b1610539366004614ded565b6118ea565b6103b161054c366004614bef565b611981565b6103e161055f366004614f64565b6119dc565b6103e1611b1a565b6103b161057a366004614c82565b611b20565b61042461058d366004614bef565b611e68565b6103b16105a0366004614bef565b611eec565b6103e1611f44565b6103e1611f4a565b6103b16105c3366004614f64565b611f4f565b6104246105d6366004614f64565b611fd1565b6103b16105e9366004614bef565b611ff8565b6103e1612183565b610424612189565b6103b161060c366004614db5565b612198565b610424612284565b6103e1612293565b61042461229b565b6103e16122af565b6103b161063f366004614bef565b6122b5565b6103b1610652366004614bef565b612360565b610424610665366004614c27565b6124ab565b610672612598565b6040516103c894939291906154de565b6103b1610690366004614bef565b61297e565b6104416106a3366004614f64565b612b11565b6103e1612d9b565b6103b16106be366004614f64565b612e3a565b6103b16106d1366004614c27565b612ebc565b610424612ece565b6106e6612edd565b6040516103c8919061505b565b6103b1613153565b610703613489565b6001600160a01b0316336001600160a01b03161461073c5760405162461bcd60e51b815260040161073390615357565b60405180910390fd5b6006546001600160a01b038281169116141561076a5760405162461bcd60e51b81526004016107339061517b565b6002546001600160a01b03828116911614156107985760405162461bcd60e51b8152600401610733906152d8565b60606107a2613506565b905060005b81518110156107fd578181815181106107bc57fe5b60200260200101516001600160a01b0316836001600160a01b031614156107f55760405162461bcd60e51b8152600401610733906153c6565b6001016107a7565b50610896610809613489565b6040516370a0823160e01b81526001600160a01b038516906370a0823190610835903090600401614fe9565b60206040518083038186803b15801561084d57600080fd5b505afa158015610861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108859190614f7c565b6001600160a01b0385169190613562565b5050565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109205780601f106108f557610100808354040283529160200191610920565b820191906000526020600020905b81548152906001019060200180831161090357829003601f168201915b505050505081565b60408051808201909152601c81527f53747261746567794c656e6465725969656c644f7074696d697365720000000060208201525b90565b600080805b600d54811015610a1157610a07600d828154811061097f57fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b1580156109c857600080fd5b505afa1580156109dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a009190614f7c565b8390613581565b9150600101610965565b50905090565b6003546001600160a01b0316331480610a485750610a33613489565b6001600160a01b0316336001600160a01b0316145b610a645760405162461bcd60e51b815260040161073390615357565b600a8190556040517fa68ba126373d04c004c5748c300c9fca12bd444b3d4332e261f3bd2bac4a860090610a99908390615469565b60405180910390a150565b600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b158015610af257600080fd5b505afa158015610b06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2a9190614c0b565b6001600160a01b0316336001600160a01b03161480610b615750610b4c613489565b6001600160a01b0316336001600160a01b0316145b610b7d5760405162461bcd60e51b815260040161073390615357565b600180546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600a5481565b6006546001600160a01b031681565b6003546001600160a01b031681565b6002546040516339ebf82360e01b815260009182916001600160a01b03909116906339ebf82390610bfe903090600401614fe9565b6101206040518083038186803b158015610c1757600080fd5b505afa158015610c2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4f9190614ee6565b604001511180610c6657506000610c64612d9b565b115b905090565b604080518082019091526005815264302e342e3360d81b602082015290565b60085481565b600e5461010090046001600160a01b031681565b6002546000906001600160a01b03163314610cd15760405162461bcd60e51b8152600401610733906152b8565b6000610cdc836135ad565b600654909350909150610cf9906001600160a01b03163383613562565b50919050565b6002546040516339ebf82360e01b815260009182916001600160a01b03909116906339ebf82390610d34903090600401614fe9565b6101206040518083038186803b158015610d4d57600080fd5b505afa158015610d61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d859190614ee6565b60c001519050600083821015610dab5750808303610da281613688565b92505050610db8565b50828103610da281613849565b919050565b6003546001600160a01b0316331480610dee5750610dd9613489565b6001600160a01b0316336001600160a01b0316145b610e0a5760405162461bcd60e51b815260040161073390615357565b60078190556040517fbb2c369a0355a34b02ab5fce0643150c87e1c8dfe7c918d465591879f57948b190610a99908390615469565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6005546001600160a01b0316331480610e7a57506003546001600160a01b031633145b80610e9d5750610e88613489565b6001600160a01b0316336001600160a01b0316145b80610f3e5750600260009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b158015610ef157600080fd5b505afa158015610f05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f299190614c0b565b6001600160a01b0316336001600160a01b0316145b80610fdf5750600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b158015610f9257600080fd5b505afa158015610fa6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fca9190614c0b565b6001600160a01b0316336001600160a01b0316145b610ffb5760405162461bcd60e51b815260040161073390615357565b6002546040805163bf3759b560e01b8152905161107e926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110799190614f7c565b613a1d565b565b6005546001600160a01b03163314806110a357506003546001600160a01b031633145b806110c657506110b1613489565b6001600160a01b0316336001600160a01b0316145b806111675750600260009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b15801561111a57600080fd5b505afa15801561112e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111529190614c0b565b6001600160a01b0316336001600160a01b0316145b806112085750600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b1580156111bb57600080fd5b505afa1580156111cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f39190614c0b565b6001600160a01b0316336001600160a01b0316145b6112245760405162461bcd60e51b815260040161073390615357565b6000806000600260009054906101000a90046001600160a01b03166001600160a01b031663bf3759b56040518163ffffffff1660e01b815260040160206040518083038186803b15801561127757600080fd5b505afa15801561128b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112af9190614f7c565b600b5490915060009060ff161561130c5760006112ca613c27565b9050828110156112e5576112de8382613c39565b93506112fa565b828111156112fa576112f78184613c39565b94505b6113048385613c39565b91505061131d565b61131582613c7b565b919550935090505b6002546040516339ebf82360e01b81526000916001600160a01b0316906339ebf8239061134e903090600401614fe9565b6101206040518083038186803b15801561136757600080fd5b505afa15801561137b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139f9190614ee6565b60c001516002546040516328766ebf60e21b81529192506001600160a01b03169063a1d9bafc906113d8908890889087906004016154c8565b602060405180830381600087803b1580156113f257600080fd5b505af1158015611406573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142a9190614f7c565b925061143583613a1d565b60015460ff168015611456575060015461010090046001600160a01b031615155b156115085760015460405163c70fa00b60e01b81526101009091046001600160a01b03169063c70fa00b9061149790889088908790899088906004016154f9565b60206040518083038186803b1580156114af57600080fd5b505afa1580156114c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e79190614dd1565b6115035760405162461bcd60e51b81526004016107339061521a565b611515565b6001805460ff1916811790555b7f4c0f499ffe6befa0ca7c826b0916cf87bea98de658013e76938489368d60d5098585848660405161154a94939291906154de565b60405180910390a15050505050565b600e5460ff1681565b6003546001600160a01b0316331480611593575061157e613489565b6001600160a01b0316336001600160a01b0316145b6115af5760405162461bcd60e51b815260040161073390615357565b600c55565b6003546001600160a01b03163314806115e557506115d0613489565b6001600160a01b0316336001600160a01b0316145b6116015760405162461bcd60e51b815260040161073390615357565b600e80546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600b5460ff1681565b60008061163d612d9b565b90508061164e57600091505061095d565b6000805b600d548110156116bf576116b5600d828154811061166c57fe5b600091825260209182902001546040805163116ac4a360e01b815290516001600160a01b039092169263116ac4a392600480840193829003018186803b1580156109c857600080fd5b9150600101611652565b506116ca8183613fa5565b9250505090565b60006116dc82612b11565b156116e957506000610db8565b60008060006116f6612598565b9350509250925081811115611816576000600d848154811061171457fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b15801561175d57600080fd5b505afa158015611771573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117959190614f7c565b905060006117e36301e185586117dd6008546117d7670de0b6b3a76400006117c68a89613fe790919063ffffffff16565b6117d0898b613fe7565b0390613fa5565b90613fe7565b90613fa5565b905060006117f088614021565b90508161180860095483613fe790919063ffffffff16565b109650505050505050610db8565b505050919050565b60015460ff1681565b737a250d5630b4cf539739df2c5dacb4c659f2488d81565b6003546001600160a01b0316331480611870575061185b613489565b6001600160a01b0316336001600160a01b0316145b61188c5760405162461bcd60e51b815260040161073390615357565b6001600160a01b03811661189f57600080fd5b600580546001600160a01b0319166001600160a01b0383161790556040517f2f202ddb4a2e345f6323ed90f8fc8559d770a7abbbeee84dde8aca3351fe715490610a99908390614fe9565b6003546001600160a01b031633148061191b5750611906613489565b6001600160a01b0316336001600160a01b0316145b6119375760405162461bcd60e51b815260040161073390615357565b61194360008383614a95565b507f300e67d5a415b6d015a471d9c7b95dd58f3e8290af965e84e0f845de2996dda682826040516119759291906150eb565b60405180910390a15050565b6003546001600160a01b03163314806119b2575061199d613489565b6001600160a01b0316336001600160a01b0316145b6119ce5760405162461bcd60e51b815260040161073390615357565b6119d98160016140fd565b50565b604080516002808252606080830184526000939092919060208301908036833701905050905073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281600081518110611a2457fe5b6001600160a01b039283166020918202929092010152600654825191169082906001908110611a4f57fe5b6001600160a01b039092166020928302919091019091015260405163d06ca61f60e01b8152606090737a250d5630b4cf539739df2c5dacb4c659f2488d9063d06ca61f90611aa39087908690600401615472565b60006040518083038186803b158015611abb57600080fd5b505afa158015611acf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611af79190810190614d25565b905080600182510381518110611b0957fe5b602002602001015192505050919050565b600c5481565b6003546001600160a01b0316331480611b515750611b3c613489565b6001600160a01b0316336001600160a01b0316145b611b6d5760405162461bcd60e51b815260040161073390615357565b6000805b600d54811015611c2157600d8181548110611b8857fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b158015611be057600080fd5b505af1158015611bf4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c189190614dd1565b50600101611b71565b506006546040516370a0823160e01b81526000916001600160a01b0316906370a0823190611c53903090600401614fe9565b60206040518083038186803b158015611c6b57600080fd5b505afa158015611c7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca39190614f7c565b905060005b8351811015611e41576000805b600d54811015611d1557858381518110611ccb57fe5b6020026020010151600001516001600160a01b0316600d8281548110611ced57fe5b6000918252602090912001546001600160a01b03161415611d0d57600191505b600101611cb5565b5080611d335760405162461bcd60e51b8152600401610733906151f6565b611d61858381518110611d4257fe5b60200260200101516020015161ffff168561358190919063ffffffff16565b93506000611d996103e86117dd888681518110611d7a57fe5b60200260200101516020015161ffff1687613fe790919063ffffffff16565b9050611dc9868481518110611daa57fe5b6020908102919091010151516006546001600160a01b03169083613562565b858381518110611dd557fe5b6020026020010151600001516001600160a01b031663d0e30db06040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611e1b57600080fd5b505af1158015611e2f573d6000803e3d6000fd5b505060019094019350611ca892505050565b50816103e814611e635760405162461bcd60e51b81526004016107339061519a565b505050565b6040516368288c2160e11b8152600090309063d051184290611e94908590339081908190600401615017565b602060405180830381600087803b158015611eae57600080fd5b505af1158015611ec2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee69190614c0b565b92915050565b6003546001600160a01b0316331480611f1d5750611f08613489565b6001600160a01b0316336001600160a01b0316145b611f395760405162461bcd60e51b815260040161073390615357565b6119d98160006140fd565b60095481565b600090565b6003546001600160a01b0316331480611f805750611f6b613489565b6001600160a01b0316336001600160a01b0316145b611f9c5760405162461bcd60e51b815260040161073390615357565b60098190556040517fd94596337df4c2f0f44d30a7fc5db1c7bb60d9aca4185ed77c6fd96eb45ec29890610a99908390615469565b600d8181548110611fde57fe5b6000918252602090912001546001600160a01b0316905081565b612000613489565b6001600160a01b0316336001600160a01b0316146120305760405162461bcd60e51b815260040161073390615357565b6000819050306001600160a01b0316816001600160a01b031663a8c62e766040518163ffffffff1660e01b815260040160206040518083038186803b15801561207857600080fd5b505afa15801561208c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120b09190614c0b565b6001600160a01b0316146120d65760405162461bcd60e51b815260040161073390615152565b60005b600d5481101561212f57600d81815481106120f057fe5b6000918252602090912001546001600160a01b03848116911614156121275760405162461bcd60e51b8152600401610733906152f9565b6001016120d9565b50600d80546001810182556000919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b0319166001600160a01b039290921691909117905550565b60075481565b6004546001600160a01b031681565b600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b1580156121e657600080fd5b505afa1580156121fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221e9190614c0b565b6001600160a01b0316336001600160a01b031614806122555750612240613489565b6001600160a01b0316336001600160a01b0316145b6122715760405162461bcd60e51b815260040161073390615357565b6001805460ff1916911515919091179055565b6005546001600160a01b031681565b6301e1855881565b60015461010090046001600160a01b031681565b600d5490565b6003546001600160a01b03163314806122e657506122d1613489565b6001600160a01b0316336001600160a01b0316145b6123025760405162461bcd60e51b815260040161073390615357565b6001600160a01b03811661231557600080fd5b600380546001600160a01b0319166001600160a01b0383161790556040517f352ececae6d7d1e6d26bcf2c549dfd55be1637e9b22dc0cf3b71ddb36097a6b490610a99908390614fe9565b6002546001600160a01b0316331461237757600080fd5b6002546040805163fbfa77cf60e01b815290516001600160a01b039283169284169163fbfa77cf916004808301926020929190829003018186803b1580156123be57600080fd5b505afa1580156123d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123f69190614c0b565b6001600160a01b03161461240957600080fd5b61241281614355565b6006546040516370a0823160e01b81526119d99183916001600160a01b03909116906370a0823190612448903090600401614fe9565b60206040518083038186803b15801561246057600080fd5b505afa158015612474573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124989190614f7c565b6006546001600160a01b03169190613562565b604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81523060601b601482018190526e5af43d82803e903d91602b57fd5bf360881b602883015260009160378184f0604051637c643b2f60e11b81529093506001600160a01b038416915063f8c8765e90612529908990899089908990600401615017565b600060405180830381600087803b15801561254357600080fd5b505af1158015612557573d6000803e3d6000fd5b50506040516001600160a01b03851692507f783540fb4221a3238720dc7038937d0d79982bcf895274aa6ad179f82cf0d53c9150600090a250949350505050565b6006546040516370a0823160e01b815260009182918291829182916001600160a01b0316906370a08231906125d1903090600401614fe9565b60206040518083038186803b1580156125e957600080fd5b505afa1580156125fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126219190614f7c565b90506000199350600094506000805b600d5481101561280857600d818154811061264757fe5b6000918252602091829020015460408051635be9b2d360e01b815290516001600160a01b0390921692635be9b2d392600480840193829003018186803b15801561269057600080fd5b505afa1580156126a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c89190614dd1565b15612800576000600d82815481106126dc57fe5b60009182526020918290200154604080516357ded9c960e01b815290516001600160a01b03909216926357ded9c992600480840193829003018186803b15801561272557600080fd5b505afa158015612739573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061275d9190614f7c565b9050868110156127fe57809650819750600d828154811061277a57fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b1580156127c357600080fd5b505afa1580156127d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127fb9190614f7c565b92505b505b600101612630565b5060006128158284613581565b9050600080955060005b600d548110156128db576000600d828154811061283857fe5b60009182526020909120015460405163052692b960e21b81526001600160a01b039091169063149a4ae490612871908990600401615469565b60206040518083038186803b15801561288957600080fd5b505afa15801561289d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128c19190614f7c565b9050828111156128d2578092508197505b5060010161281f565b50600d86815481106128e957fe5b60009182526020909120015460405163052692b960e21b81526001600160a01b039091169063149a4ae490612922908590600401615469565b60206040518083038186803b15801561293a57600080fd5b505afa15801561294e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129729190614f7c565b94505050505090919293565b6003546001600160a01b031633146129a85760405162461bcd60e51b81526004016107339061512d565b6001600160a01b0381166129bb57600080fd5b6002546004805460405163095ea7b360e01b81526001600160a01b039384169363095ea7b3936129f2939091169160009101615042565b602060405180830381600087803b158015612a0c57600080fd5b505af1158015612a20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a449190614dd1565b50600480546001600160a01b0319166001600160a01b038381169190911780835560025460405163095ea7b360e01b81529083169363095ea7b393612a8f9316916000199101615042565b602060405180830381600087803b158015612aa957600080fd5b505af1158015612abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ae19190614dd1565b507fafbb66abf8f3b719799940473a4052a3717cdd8e40fb6c8a3faadab316b1a06981604051610a999190614fe9565b600080612b1d836119dc565b9050612b27614b13565b6002546040516339ebf82360e01b81526001600160a01b03909116906339ebf82390612b57903090600401614fe9565b6101206040518083038186803b158015612b7057600080fd5b505afa158015612b84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ba89190614ee6565b9050806020015160001415612bc257600092505050610db8565b60075460a0820151612bd5904290613c39565b1015612be657600092505050610db8565b60085460a0820151612bf9904290613c39565b10612c0957600192505050610db8565b6002546040805163bf3759b560e01b815290516000926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b158015612c4e57600080fd5b505afa158015612c62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c869190614f7c565b9050600a54811115612c9e5760019350505050610db8565b6000612ca8612d9b565b90508260c00151612cc4600a548361358190919063ffffffff16565b1015612cd7576001945050505050610db8565b60008360c00151821115612cf85760c0840151612cf5908390613c39565b90505b6002546040805163112c1f9b60e01b815290516000926001600160a01b03169163112c1f9b916004808301926020929190829003018186803b158015612d3d57600080fd5b505afa158015612d51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d759190614f7c565b9050612d818183613581565b600954612d8e9088613fe7565b1098975050505050505050565b600080612da6610960565b6006546040516370a0823160e01b8152919250612e34916001600160a01b03909116906370a0823190612ddd903090600401614fe9565b60206040518083038186803b158015612df557600080fd5b505afa158015612e09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e2d9190614f7c565b8290613581565b91505090565b6003546001600160a01b0316331480612e6b5750612e56613489565b6001600160a01b0316336001600160a01b0316145b612e875760405162461bcd60e51b815260040161073390615357565b60088190556040517f5430e11864ad7aa9775b07d12657fe52df9aa2ba734355bd8ef8747be2c800c590610a99908390615469565b612ec8848484846143f2565b50505050565b6002546001600160a01b031681565b600d54606090819067ffffffffffffffff81118015612efb57600080fd5b50604051908082528060200260200182016040528015612f3557816020015b612f22614b5f565b815260200190600190039081612f1a5790505b50905060005b600d54811015610a1157612f4d614b5f565b600d8281548110612f5a57fe5b60009182526020822001546040805163459010bb60e11b815290516001600160a01b0390921692638b20217692600480840193829003018186803b158015612fa157600080fd5b505afa158015612fb5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612fdd9190810190614e5a565b8152600d805483908110612fed57fe5b6000918252602090912001546001600160a01b03166060820152600d80548390811061301557fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b15801561305e57600080fd5b505afa158015613072573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130969190614f7c565b6020820152600d8054839081106130a957fe5b60009182526020918290200154604080516357ded9c960e01b815290516001600160a01b03909216926357ded9c992600480840193829003018186803b1580156130f257600080fd5b505afa158015613106573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061312a9190614f7c565b60408201528251819084908490811061313f57fe5b602090810291909101015250600101612f3b565b6003546001600160a01b0316331480613184575061316f613489565b6001600160a01b0316336001600160a01b0316145b806132255750600260009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b1580156131d857600080fd5b505afa1580156131ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132109190614c0b565b6001600160a01b0316336001600160a01b0316145b806132c65750600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b15801561327957600080fd5b505afa15801561328d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132b19190614c0b565b6001600160a01b0316336001600160a01b0316145b6132e25760405162461bcd60e51b815260040161073390615357565b600b805460ff191660011790556002546040805163507257cd60e11b815290516001600160a01b039092169163a0e4af9a9160048082019260009290919082900301818387803b15801561333557600080fd5b505af1158015613349573d6000803e3d6000fd5b50506040517f97e963041e952738788b9d4871d854d282065b8f90a464928d6528f2e9a4fd0b925060009150a1565b8015806134005750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e906133ae9030908690600401614ffd565b60206040518083038186803b1580156133c657600080fd5b505afa1580156133da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133fe9190614f7c565b155b61341c5760405162461bcd60e51b815260040161073390615413565b611e638363095ea7b360e01b848460405160240161343b929190615042565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526145b2565b60606134818484600085614641565b949350505050565b60025460408051635aa6e67560e01b815290516000926001600160a01b031691635aa6e675916004808301926020929190829003018186803b1580156134ce57600080fd5b505afa1580156134e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c669190614c0b565b60408051600180825281830190925260609182919060208083019080368337505060065482519293506001600160a01b03169183915060009061354557fe5b6001600160a01b0390921660209283029190910190910152905090565b611e638363a9059cbb60e01b848460405160240161343b929190615042565b6000828201838110156135a65760405162461bcd60e51b8152600401610733906151bf565b9392505050565b6006546040516370a0823160e01b8152600091829182916001600160a01b0316906370a08231906135e2903090600401614fe9565b60206040518083038186803b1580156135fa57600080fd5b505afa15801561360e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136329190614f7c565b9050838110613648578360009250925050613683565b600061365f82613659848803614705565b90613581565b905084811061367657846000935093505050613683565b9250600091506136839050565b915091565b6000808080805b600d548110156137db576000600d82815481106136a857fe5b60009182526020909120015460405163052692b960e21b81526001600160a01b039091169063149a4ae4906136e1908a90600401615469565b60206040518083038186803b1580156136f957600080fd5b505afa15801561370d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137319190614f7c565b9050848111156137d257819350809450600d828154811061374e57fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b15801561379757600080fd5b505afa1580156137ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137cf9190614f7c565b92505b5060010161368f565b5060006137f26137eb8388613581565b8590613fe7565b905060005b600d548110156138235783811461381b57613818600d828154811061166c57fe5b91505b6001016137f7565b50600061383287613659612d9b565b905061383e8282613fa5565b979650505050505050565b600060001981805b600d5481101561390d576000600d828154811061386a57fe5b60009182526020909120015460405163052692b960e21b81526001600160a01b039091169063149a4ae4906138a3908990600401615469565b60206040518083038186803b1580156138bb57600080fd5b505afa1580156138cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f39190614f7c565b905083811015613904578192508093505b50600101613851565b506000805b600d548110156139f85782811461393a57613933600d828154811061166c57fe5b91506139f0565b6000600d828154811061394957fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b15801561399257600080fd5b505afa1580156139a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139ca9190614f7c565b9050868110156139d8578096505b6139ec6139e58689613fe7565b8490613581565b9250505b600101613912565b506000613a0786613659612d9b565b9050613a138282613fa5565b9695505050505050565b600b5460ff1615613a2d576119d9565b600d54613a39576119d9565b600080600080613a47612598565b935093509350935082811115613af657600d8481548110613a6457fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b158015613abc57600080fd5b505af1158015613ad0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613af49190614dd1565b505b6006546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613b27903090600401614fe9565b60206040518083038186803b158015613b3f57600080fd5b505afa158015613b53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b779190614f7c565b90508015613c1f57613bb1600d8481548110613b8f57fe5b6000918252602090912001546006546001600160a01b03908116911683613562565b600d8381548110613bbe57fe5b600091825260208220015460408051630d0e30db60e41b815290516001600160a01b039092169263d0e30db09260048084019382900301818387803b158015613c0657600080fd5b505af1158015613c1a573d6000803e3d6000fd5b505050505b505050505050565b6000610c66613c34610960565b614705565b60006135a683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506149e3565b6000808281613c88610960565b6006546040516370a0823160e01b81529192506000916001600160a01b03909116906370a0823190613cbe903090600401614fe9565b60206040518083038186803b158015613cd657600080fd5b505afa158015613cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d0e9190614f7c565b90506000613d1c8284613581565b905082613d375781841115613d2f578193505b505050613f9e565b6002546040516339ebf82360e01b81526000916001600160a01b0316906339ebf82390613d68903090600401614fe9565b6101206040518083038186803b158015613d8157600080fd5b505afa158015613d95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613db99190614ee6565b60c00151905080821115613eb25780820396506000613dd88887613581565b9050600081118015613de957508084105b15613eac57613dfb613c348286613c39565b506006546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613e2d903090600401614fe9565b60206040518083038186803b158015613e4557600080fd5b505afa158015613e59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e7d9190614f7c565b905081811015613eaa5780891115613e9b5780985060009650613eaa565b613ea789820388614a0f565b96505b505b50613f99565b81810395506000613ec38787613581565b9050600081118015613ed457508084105b15613f9757613ee6613c348286613c39565b506006546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613f18903090600401614fe9565b60206040518083038186803b158015613f3057600080fd5b505afa158015613f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f689190614f7c565b905081811015613f955780881115613f865780975060009650613f95565b613f9288820388614a0f565b96505b505b505b505050505b9193909250565b60006135a683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614a25565b600082613ff657506000611ee6565b8282028284828161400357fe5b04146135a65760405162461bcd60e51b815260040161073390615277565b60065460009081906001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21415614054575081611ee6565b600e5461010090046001600160a01b031661407957614072836119dc565b9050611ee6565b600e546040516303c0011560e51b81526101009091046001600160a01b03169063780022a0906140ad908690600401615469565b60206040518083038186803b1580156140c557600080fd5b505afa1580156140d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135a69190614f7c565b60005b600d5481101561433c57600d818154811061411757fe5b6000918252602090912001546001600160a01b0384811691161415614334576000600d828154811061414557fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561419d57600080fd5b505af11580156141b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141d59190614dd1565b9050826141f957806141f95760405162461bcd60e51b8152600401610733906153ea565b600d5460001901821461426d57600d8054600019810190811061421857fe5b600091825260209091200154600d80546001600160a01b03909216918490811061423e57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b600d80548061427857fe5b600082815260208120600019908301810180546001600160a01b03191690559091019091556006546040516370a0823160e01b81526001600160a01b03909116906370a08231906142cd903090600401614fe9565b60206040518083038186803b1580156142e557600080fd5b505afa1580156142f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061431d9190614f7c565b111561432d5761432d6000613a1d565b5050610896565b600101614100565b5060405162461bcd60e51b8152600401610733906151f6565b6002546040516339ebf82360e01b81526000916001600160a01b0316906339ebf82390614386903090600401614fe9565b6101206040518083038186803b15801561439f57600080fd5b505afa1580156143b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143d79190614ee6565b60c0015190506000806143e983613c7b565b50505050505050565b6006546001600160a01b03161561441b5760405162461bcd60e51b815260040161073390615240565b600280546001600160a01b0319166001600160a01b03868116919091179182905560408051637e062a3560e11b81529051929091169163fc0c546a91600480820192602092909190829003018186803b15801561447757600080fd5b505afa15801561448b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144af9190614c0b565b600680546001600160a01b0319166001600160a01b0392831617908190556144db911685600019613378565b600380546001600160a01b038086166001600160a01b03199283161790925560048054858416908316178082556005805486861694169390931790925560006007819055620151806008556064600955600a5560025460405163095ea7b360e01b81529084169363095ea7b393614559939116916000199101615042565b602060405180830381600087803b15801561457357600080fd5b505af1158015614587573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145ab9190614dd1565b5050505050565b6060614607826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166134729092919063ffffffff16565b805190915015611e6357808060200190518101906146259190614dd1565b611e635760405162461bcd60e51b81526004016107339061537c565b606061464c85614a5c565b6146685760405162461bcd60e51b815260040161073390615320565b60006060866001600160a01b031685876040516146859190614fcd565b60006040518083038185875af1925050503d80600081146146c2576040519150601f19603f3d011682016040523d82523d6000602084013e6146c7565b606091505b509150915081156146db5791506134819050565b8051156146eb5780518082602001fd5b8360405162461bcd60e51b8152600401610733919061511a565b600d5460009061471757506000610db8565b600c5482101561472957506000610db8565b506000805b82821015610cf9576000196000805b600d5481101561488557600d818154811061475457fe5b6000918252602091829020015460408051635be9b2d360e01b815290516001600160a01b0390921692635be9b2d392600480840193829003018186803b15801561479d57600080fd5b505afa1580156147b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147d59190614dd1565b1561487d576000600d82815481106147e957fe5b60009182526020918290200154604080516357ded9c960e01b815290516001600160a01b03909216926357ded9c992600480840193829003018186803b15801561483257600080fd5b505afa158015614846573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061486a9190614f7c565b90508381101561487b578093508192505b505b60010161473d565b50600d818154811061489357fe5b6000918252602091829020015460408051635be9b2d360e01b815290516001600160a01b0390921692635be9b2d392600480840193829003018186803b1580156148dc57600080fd5b505afa1580156148f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149149190614dd1565b61492057505050610db8565b6149c4600d828154811061493057fe5b600091825260209091200154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d9061496b90888a0390600401615469565b602060405180830381600087803b15801561498557600080fd5b505af1158015614999573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149bd9190614f7c565b8590613581565b9350600190920191600683106149dc57505050610db8565b505061472e565b60008184841115614a075760405162461bcd60e51b8152600401610733919061511a565b505050900390565b6000818310614a1e57816135a6565b5090919050565b60008183614a465760405162461bcd60e51b8152600401610733919061511a565b506000838581614a5257fe5b0495945050505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590613481575050151592915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614ad65782800160ff19823516178555614b03565b82800160010185558215614b03579182015b82811115614b03578235825591602001919060010190614ae8565b50614b0f929150614b90565b5090565b6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604051806080016040528060608152602001600081526020016000815260200160006001600160a01b031681525090565b5b80821115614b0f5760008155600101614b91565b600060408284031215614bb6578081fd5b614bc0604061551c565b90508135614bcd8161558f565b8152602082013561ffff81168114614be457600080fd5b602082015292915050565b600060208284031215614c00578081fd5b81356135a68161558f565b600060208284031215614c1c578081fd5b81516135a68161558f565b60008060008060808587031215614c3c578283fd5b8435614c478161558f565b93506020850135614c578161558f565b92506040850135614c678161558f565b91506060850135614c778161558f565b939692955090935050565b60006020808385031215614c94578182fd5b823567ffffffffffffffff811115614caa578283fd5b8301601f81018513614cba578283fd5b8035614ccd614cc882615543565b61551c565b818152838101908385016040808502860187018a1015614ceb578788fd5b8795505b84861015614d1757614d018a83614ba5565b8452600195909501949286019290810190614cef565b509098975050505050505050565b60006020808385031215614d37578182fd5b825167ffffffffffffffff811115614d4d578283fd5b8301601f81018513614d5d578283fd5b8051614d6b614cc882615543565b8181528381019083850185840285018601891015614d87578687fd5b8694505b83851015614da9578051835260019490940193918501918501614d8b565b50979650505050505050565b600060208284031215614dc6578081fd5b81356135a6816155a4565b600060208284031215614de2578081fd5b81516135a6816155a4565b60008060208385031215614dff578182fd5b823567ffffffffffffffff80821115614e16578384fd5b818501915085601f830112614e29578384fd5b813581811115614e37578485fd5b866020828501011115614e48578485fd5b60209290920196919550909350505050565b600060208284031215614e6b578081fd5b815167ffffffffffffffff80821115614e82578283fd5b818401915084601f830112614e95578283fd5b815181811115614ea3578384fd5b614eb6601f8201601f191660200161551c565b9150808252856020828501011115614ecc578384fd5b614edd816020840160208601615563565b50949350505050565b6000610120808385031215614ef9578182fd5b614f028161551c565b9050825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152508091505092915050565b600060208284031215614f75578081fd5b5035919050565b600060208284031215614f8d578081fd5b5051919050565b6001600160a01b03169052565b60008151808452614fb9816020860160208601615563565b601f01601f19169290920160200192915050565b60008251614fdf818460208701615563565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03948516815292841660208401529083166040830152909116606082015260800190565b6001600160a01b03929092168252602082015260400190565b60208082528251828201819052600091906040908185019080840286018301878501865b83811015614d1757603f198984030185528151608081518186526150a582870182614fa1565b9150508882015189860152878201518886015260608083015192506150cc81870184614f94565b50958801959350509086019060010161507f565b901515815260200190565b60006020825282602083015282846040840137818301604090810191909152601f909201601f19160101919050565b6000602082526135a66020830184614fa1565b6020808252600b908201526a085cdd1c985d1959da5cdd60aa1b604082015260600190565b6020808252600f908201526e2ab73237b1b5b2b2102632b73232b960891b604082015260600190565b602080825260059082015264085dd85b9d60da1b604082015260600190565b6020808252600b908201526a05348415245213d313030360ac1b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600a90820152692727aa102622a72222a960b11b604082015260600190565b6020808252600c908201526b216865616c7468636865636b60a01b604082015260600190565b6020808252601c908201527f537472617465677920616c726561647920696e697469616c697a656400000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260069082015265085d985d5b1d60d21b604082015260600190565b6020808252600790820152662173686172657360c81b604082015260600190565b6020808252600d908201526c105b1c9958591e481059191959609a1b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600b908201526a08585d5d1a1bdc9a5e995960aa1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600a9082015269085c1c9bdd1958dd195960b21b604082015260600190565b6020808252600f908201526e15d2551211149055c8119052531151608a1b604082015260600190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b90815260200190565b60006040820184835260206040818501528185518084526060860191508287019350845b818110156154bb5784516001600160a01b031683529383019391830191600101615496565b5090979650505050505050565b9283526020830191909152604082015260600190565b93845260208401929092526040830152606082015260800190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff8111828210171561553b57600080fd5b604052919050565b600067ffffffffffffffff821115615559578081fd5b5060209081020190565b60005b8381101561557e578181015183820152602001615566565b83811115612ec85750506000910152565b6001600160a01b03811681146119d957600080fd5b80151581146119d957600080fdfea26469706673582212207a224399c14c11ec8e7f566fabefc939a638034f3ad5dd97286939b9860a8e5f64736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000da816459f1ab5631232fe5e97a05bbbb94970c95
-----Decoded View---------------
Arg [0] : _vault (address): 0xdA816459F1AB5631232FE5e97a05BBBb94970c95
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000da816459f1ab5631232fe5e97a05bbbb94970c95
Deployed Bytecode Sourcemap
55813:20558:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54870:444;;;;;;:::i;:::-;;:::i;:::-;;26099:25;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58064:119;;;:::i;65850:225::-;;;:::i;:::-;;;;;;;:::i;36472:175::-;;;;;;:::i;:::-;;:::i;32040:118::-;;;;;;:::i;:::-;;:::i;29378:28::-;;;:::i;28126:18::-;;;:::i;:::-;;;;;;;:::i;28035:25::-;;;:::i;39874:148::-;;;:::i;:::-;;;;;;;:::i;26498:91::-;;;:::i;29014:29::-;;;:::i;56320:30::-;;;:::i;51274:515::-;;;;;;:::i;:::-;;:::i;65321:475::-;;;;;;:::i;:::-;;:::i;34521:154::-;;;;;;:::i;:::-;;:::i;56043:73::-;;;:::i;44971:170::-;;;:::i;49450:1580::-;;;:::i;56267:26::-;;;:::i;57812:127::-;;;;;;:::i;:::-;;:::i;57947:109::-;;;;;;:::i;:::-;;:::i;29457:25::-;;;:::i;61136:383::-;;;:::i;74409:1289::-;;;;;;:::i;:::-;;:::i;26155:25::-;;;:::i;55954:82::-;;;:::i;33278:174::-;;;;;;:::i;:::-;;:::i;36950:171::-;;;;;;:::i;:::-;;:::i;58832:101::-;;;;;;:::i;:::-;;:::i;73489:326::-;;;;;;:::i;:::-;;:::i;56123:41::-;;;:::i;70305:1047::-;;;;;;:::i;:::-;;:::i;56512:157::-;;;;;;:::i;:::-;;:::i;58723:101::-;;;;;;:::i;:::-;;:::i;29200:27::-;;;:::i;27905:94::-;;;:::i;35746:169::-;;;;;;:::i;:::-;;:::i;56229:31::-;;;;;;:::i;:::-;;:::i;58336:335::-;;;;;;:::i;:::-;;:::i;28863:29::-;;;:::i;28067:22::-;;;:::i;32166:123::-;;;;;;:::i;:::-;;:::i;28096:21::-;;;:::i;56171:49::-;;;:::i;26187:26::-;;;:::i;60972:92::-;;;:::i;32522:202::-;;;;;;:::i;:::-;;:::i;52561:281::-;;;;;;:::i;:::-;;:::i;56677:897::-;;;;;;:::i;:::-;;:::i;63747:1456::-;;;:::i;:::-;;;;;;;;;;:::i;33741:263::-;;;;;;:::i;:::-;;:::i;46908:1736::-;;;;;;:::i;:::-;;:::i;60765:199::-;;;:::i;35192:154::-;;;;;;:::i;:::-;;:::i;57582:222::-;;;;;;:::i;:::-;;:::i;28007:21::-;;;:::i;60241:478::-;;;:::i;:::-;;;;;;;:::i;53271:173::-;;;:::i;54870:444::-;30083:12;:10;:12::i;:::-;-1:-1:-1;;;;;30069:26:0;:10;-1:-1:-1;;;;;30069:26:0;;30061:50;;;;-1:-1:-1;;;30061:50:0;;;;;;;:::i;:::-;;;;;;;;;54962:4:::1;::::0;-1:-1:-1;;;;;54944:23:0;;::::1;54962:4:::0;::::1;54944:23;;54936:41;;;;-1:-1:-1::0;;;54936:41:0::1;;;;;;;:::i;:::-;55014:5;::::0;-1:-1:-1;;;;;54996:24:0;;::::1;55014:5:::0;::::1;54996:24;;54988:44;;;;-1:-1:-1::0;;;54988:44:0::1;;;;;;;:::i;:::-;55045:33;55081:17;:15;:17::i;:::-;55045:53;;55114:9;55109:102;55129:16;:23;55125:1;:27;55109:102;;;55177:16;55194:1;55177:19;;;;;;;;;;;;;;-1:-1:-1::0;;;;;55167:29:0::1;:6;-1:-1:-1::0;;;;;55167:29:0::1;;;55159:52;;;;-1:-1:-1::0;;;55159:52:0::1;;;;;;;:::i;:::-;55154:3;;55109:102;;;;55224:82;55252:12;:10;:12::i;:::-;55266:39;::::0;-1:-1:-1;;;55266:39:0;;-1:-1:-1;;;;;55266:24:0;::::1;::::0;::::1;::::0;:39:::1;::::0;55299:4:::1;::::0;55266:39:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;55224:27:0;::::1;::::0;:82;:27:::1;:82::i;:::-;30122:1;54870:444:::0;:::o;26099:25::-;;;;;;;;;;;;;;;-1:-1:-1;;26099:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;58064:119::-;58138:37;;;;;;;;;;;;;;;;;58064:119;;:::o;65850:225::-;65898:7;;;65944:103;65968:7;:14;65964:18;;65944:103;;;66010:25;66018:7;66026:1;66018:10;;;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;;;66018:16:0;;;;-1:-1:-1;;;;;66018:10:0;;;;:14;;:16;;;;;;;;;;:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66010:3;;:7;:25::i;:::-;66004:31;-1:-1:-1;65984:3:0;;65944:103;;;-1:-1:-1;66064:3:0;-1:-1:-1;65850:225:0;:::o;36472:175::-;29568:10;;-1:-1:-1;;;;;29568:10:0;29554;:24;;:54;;;29596:12;:10;:12::i;:::-;-1:-1:-1;;;;;29582:26:0;:10;-1:-1:-1;;;;;29582:26:0;;29554:54;29546:78;;;;-1:-1:-1;;;29546:78:0;;;;;;;:::i;:::-;36557:13:::1;:30:::0;;;36603:36:::1;::::0;::::1;::::0;::::1;::::0;36573:14;;36603:36:::1;:::i;:::-;;;;;;;;36472:175:::0;:::o;32040:118::-;30540:5;;;;;;;;;-1:-1:-1;;;;;30540:5:0;-1:-1:-1;;;;;30540:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;30526:32:0;:10;-1:-1:-1;;;;;30526:32:0;;:62;;;;30576:12;:10;:12::i;:::-;-1:-1:-1;;;;;30562:26:0;:10;-1:-1:-1;;;;;30562:26:0;;30526:62;30518:86;;;;-1:-1:-1;;;30518:86:0;;;;;;;:::i;:::-;32124:11:::1;:26:::0;;-1:-1:-1;;;;;32124:26:0;;::::1;;;-1:-1:-1::0;;;;;;32124:26:0;;::::1;::::0;;;::::1;::::0;;32040:118::o;29378:28::-;;;;:::o;28126:18::-;;;-1:-1:-1;;;;;28126:18:0;;:::o;28035:25::-;;;-1:-1:-1;;;;;28035:25:0;;:::o;39874:148::-;39939:5;;:31;;-1:-1:-1;;;39939:31:0;;39915:4;;;;-1:-1:-1;;;;;39939:5:0;;;;:16;;:31;;39964:4;;39939:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;:45;:75;;;;40013:1;39988:22;:20;:22::i;:::-;:26;39939:75;39932:82;;39874:148;:::o;26498:91::-;26567:14;;;;;;;;;;;;-1:-1:-1;;;26567:14:0;;;;26498:91;:::o;29014:29::-;;;;:::o;56320:30::-;;;;;;-1:-1:-1;;;;;56320:30:0;;:::o;51274:515::-;51389:5;;51333:13;;-1:-1:-1;;;;;51389:5:0;51367:10;:28;51359:47;;;;-1:-1:-1;;;51359:47:0;;;;;;;:::i;:::-;51492:19;51545:32;51563:13;51545:17;:32::i;:::-;51669:4;;51522:55;;-1:-1:-1;51522:55:0;;-1:-1:-1;51669:42:0;;-1:-1:-1;;;;;51669:4:0;51687:10;51522:55;51669:17;:42::i;:::-;51274:515;;;;:::o;65321:475::-;65435:5;;:31;;-1:-1:-1;;;65435:31:0;;65392:7;;;;-1:-1:-1;;;;;65435:5:0;;;;:16;;:31;;65460:4;;65435:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;65412:64;;65487:14;65531:12;65516;:27;65512:277;;;-1:-1:-1;65569:27:0;;;65618:34;65569:27;65618:26;:34::i;:::-;65611:41;;;;;;65512:277;-1:-1:-1;65694:27:0;;;65743:34;65694:27;65743:26;:34::i;65321:475::-;;;;:::o;34521:154::-;29568:10;;-1:-1:-1;;;;;29568:10:0;29554;:24;;:54;;;29596:12;:10;:12::i;:::-;-1:-1:-1;;;;;29582:26:0;:10;-1:-1:-1;;;;;29582:26:0;;29554:54;29546:78;;;;-1:-1:-1;;;29546:78:0;;;;;;;:::i;:::-;34599:14:::1;:23:::0;;;34638:29:::1;::::0;::::1;::::0;::::1;::::0;34616:6;;34638:29:::1;:::i;56043:73::-:0;56074:42;56043:73;:::o;44971:170::-;30209:6;;-1:-1:-1;;;;;30209:6:0;30195:10;:20;;:65;;-1:-1:-1;30250:10:0;;-1:-1:-1;;;;;30250:10:0;30236;:24;30195:65;:112;;;;30295:12;:10;:12::i;:::-;-1:-1:-1;;;;;30281:26:0;:10;-1:-1:-1;;;;;30281:26:0;;30195:112;:163;;;;30342:5;;;;;;;;;-1:-1:-1;;;;;30342:5:0;-1:-1:-1;;;;;30342:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;30328:30:0;:10;-1:-1:-1;;;;;30328:30:0;;30195:163;:216;;;;30393:5;;;;;;;;;-1:-1:-1;;;;;30393:5:0;-1:-1:-1;;;;;30393:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;30379:32:0;:10;-1:-1:-1;;;;;30379:32:0;;30195:216;30173:277;;;;-1:-1:-1;;;30173:277:0;;;;;;;:::i;:::-;45109:5:::1;::::0;:23:::1;::::0;;-1:-1:-1;;;45109:23:0;;;;45094:39:::1;::::0;-1:-1:-1;;;;;45109:5:0::1;::::0;:21:::1;::::0;:23:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:5;:23;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45094:14;:39::i;:::-;44971:170::o:0;49450:1580::-;30209:6;;-1:-1:-1;;;;;30209:6:0;30195:10;:20;;:65;;-1:-1:-1;30250:10:0;;-1:-1:-1;;;;;30250:10:0;30236;:24;30195:65;:112;;;;30295:12;:10;:12::i;:::-;-1:-1:-1;;;;;30281:26:0;:10;-1:-1:-1;;;;;30281:26:0;;30195:112;:163;;;;30342:5;;;;;;;;;-1:-1:-1;;;;;30342:5:0;-1:-1:-1;;;;;30342:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;30328:30:0;:10;-1:-1:-1;;;;;30328:30:0;;30195:163;:216;;;;30393:5;;;;;;;;;-1:-1:-1;;;;;30393:5:0;-1:-1:-1;;;;;30393:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;30379:32:0;:10;-1:-1:-1;;;;;30379:32:0;;30195:216;30173:277;;;;-1:-1:-1;;;30173:277:0;;;;;;;:::i;:::-;49501:14:::1;49530:12:::0;49557:23:::1;49583:5;;;;;;;;;-1:-1:-1::0;;;;;49583:5:0::1;-1:-1:-1::0;;;;;49583:21:0::1;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49655:13;::::0;49557:49;;-1:-1:-1;49617:19:0::1;::::0;49655:13:::1;;49651:580;;;49737:19;49759:23;:21;:23::i;:::-;49737:45;;49815:15;49801:11;:29;49797:226;;;49858:32;:15:::0;49878:11;49858:19:::1;:32::i;:::-;49851:39;;49797:226;;;49930:15;49916:11;:29;49912:111;;;49975:32;:11:::0;49991:15;49975::::1;:32::i;:::-;49966:41;;49912:111;50051:25;:15:::0;50071:4;50051:19:::1;:25::i;:::-;50037:39;;49651:580;;;;50189:30;50203:15;50189:13;:30::i;:::-;50159:60:::0;;-1:-1:-1;50159:60:0;-1:-1:-1;50159:60:0;-1:-1:-1;49651:580:0::1;50447:5;::::0;:31:::1;::::0;-1:-1:-1;;;50447:31:0;;50427:17:::1;::::0;-1:-1:-1;;;;;50447:5:0::1;::::0;:16:::1;::::0;:31:::1;::::0;50472:4:::1;::::0;50447:31:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;::::0;50517:5:::1;::::0;:39:::1;::::0;-1:-1:-1;;;50517:39:0;;50447:41;;-1:-1:-1;;;;;;50517:5:0::1;::::0;:12:::1;::::0;:39:::1;::::0;50530:6;;50538:4;;50544:11;;50517:39:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50499:57;;50632:31;50647:15;50632:14;:31::i;:::-;50718:13;::::0;::::1;;:42:::0;::::1;;;-1:-1:-1::0;50735:11:0::1;::::0;::::1;::::0;::::1;-1:-1:-1::0;;;;;50735:11:0::1;:25:::0;::::1;50718:42;50714:238;;;50797:11;::::0;50785:85:::1;::::0;-1:-1:-1;;;50785:85:0;;50797:11:::1;::::0;;::::1;-1:-1:-1::0;;;;;50797:11:0::1;::::0;50785:30:::1;::::0;:85:::1;::::0;50816:6;;50824:4;;50830:11;;50843:15;;50860:9;;50785:85:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50777:110;;;;-1:-1:-1::0;;;50777:110:0::1;;;;;;;:::i;:::-;50714:238;;;50936:4;50920:20:::0;;-1:-1:-1;;50920:20:0::1;::::0;::::1;::::0;;50714:238:::1;50969:53;50979:6;50987:4;50993:11;51006:15;50969:53;;;;;;;;;:::i;:::-;;;;;;;;30461:1;;;;;49450:1580::o:0;56267:26::-;;;;;;:::o;57812:127::-;29568:10;;-1:-1:-1;;;;;29568:10:0;29554;:24;;:54;;;29596:12;:10;:12::i;:::-;-1:-1:-1;;;;;29582:26:0;:10;-1:-1:-1;;;;;29582:26:0;;29554:54;29546:78;;;;-1:-1:-1;;;29546:78:0;;;;;;;:::i;:::-;57899:19:::1;:32:::0;57812:127::o;57947:109::-;29568:10;;-1:-1:-1;;;;;29568:10:0;29554;:24;;:54;;;29596:12;:10;:12::i;:::-;-1:-1:-1;;;;;29582:26:0;:10;-1:-1:-1;;;;;29582:26:0;;29554:54;29546:78;;;;-1:-1:-1;;;29546:78:0;;;;;;;:::i;:::-;58023:15:::1;:25:::0;;-1:-1:-1;;;;;58023:25:0;;::::1;;;-1:-1:-1::0;;;;;;58023:25:0;;::::1;::::0;;;::::1;::::0;;57947:109::o;29457:25::-;;;;;;:::o;61136:383::-;61181:7;61201:11;61215:22;:20;:22::i;:::-;61201:36;-1:-1:-1;61252:8:0;61248:49;;61284:1;61277:8;;;;;61248:49;61309:19;61350:9;61345:127;61369:7;:14;61365:18;;61345:127;;;61419:41;61435:7;61443:1;61435:10;;;;;;;;;;;;;;;;;;;:24;;;-1:-1:-1;;;61435:24:0;;;;-1:-1:-1;;;;;61435:10:0;;;;:22;;:24;;;;;;;;;;:10;:24;;;;;;;;;;61419:41;61405:55;-1:-1:-1;61385:3:0;;61345:127;;;-1:-1:-1;61491:20:0;:11;61507:3;61491:15;:20::i;:::-;61484:27;;;;61136:383;:::o;74409:1289::-;74478:4;74578:24;74593:8;74578:14;:24::i;:::-;74574:69;;;-1:-1:-1;74626:5:0;74619:12;;74574:69;74800:14;74816:17;74837;74858:24;:22;:24::i;:::-;74799:83;;;;;;;74980:9;74968;:21;74964:727;;;75006:11;75020:7;75028:6;75020:15;;;;;;;;;;;;;;;;;;;:21;;;-1:-1:-1;;;75020:21:0;;;;-1:-1:-1;;;;;75020:15:0;;;;:19;;:21;;;;;;;;;;:15;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75006:35;;75425:22;75450:91;56212:8;75450:71;75506:14;;75450:51;75496:4;75472:18;75480:9;75472:3;:7;;:18;;;;:::i;:::-;75451;:3;75459:9;75451:7;:18::i;:::-;:39;;75450:45;:51::i;:::-;:55;;:71::i;:::-;:75;;:91::i;:::-;75425:116;;75558:20;75581:25;75597:8;75581:15;:25::i;:::-;75558:48;;75664:14;75631:30;75648:12;;75631;:16;;:30;;;;:::i;:::-;:47;75623:56;;;;;;;;;;74964:727;74409:1289;;;;;;:::o;26155:25::-;;;;;;:::o;55954:82::-;55994:42;55954:82;:::o;33278:174::-;29568:10;;-1:-1:-1;;;;;29568:10:0;29554;:24;;:54;;;29596:12;:10;:12::i;:::-;-1:-1:-1;;;;;29582:26:0;:10;-1:-1:-1;;;;;29582:26:0;;29554:54;29546:78;;;;-1:-1:-1;;;29546:78:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;33357:21:0;::::1;33349:30;;;::::0;::::1;;33390:6;:16:::0;;-1:-1:-1;;;;;;33390:16:0::1;-1:-1:-1::0;;;;;33390:16:0;::::1;;::::0;;33422:22:::1;::::0;::::1;::::0;::::1;::::0;33390:16;;33422:22:::1;:::i;36950:171::-:0;29568:10;;-1:-1:-1;;;;;29568:10:0;29554;:24;;:54;;;29596:12;:10;:12::i;:::-;-1:-1:-1;;;;;29582:26:0;:10;-1:-1:-1;;;;;29582:26:0;;29554:54;29546:78;;;;-1:-1:-1;;;29546:78:0;;;;;;;:::i;:::-;37039:26:::1;:11;37053:12:::0;;37039:26:::1;:::i;:::-;;37081:32;37100:12;;37081:32;;;;;;;:::i;:::-;;;;;;;;36950:171:::0;;:::o;58832:101::-;29568:10;;-1:-1:-1;;;;;29568:10:0;29554;:24;;:54;;;29596:12;:10;:12::i;:::-;-1:-1:-1;;;;;29582:26:0;:10;-1:-1:-1;;;;;29582:26:0;;29554:54;29546:78;;;;-1:-1:-1;;;29546:78:0;;;;;;;:::i;:::-;58903:22:::1;58917:1;58920:4;58903:13;:22::i;:::-;58832:101:::0;:::o;73489:326::-;73599:16;;;73613:1;73599:16;;;73575:21;73599:16;;;;;73555:7;;73575:21;;73599:16;73613:1;73599:16;;;;;;;;;;-1:-1:-1;73599:16:0;73575:40;;56074:42;73626:4;73631:1;73626:7;;;;;;;;-1:-1:-1;;;;;73626:14:0;;;:7;;;;;;;;;:14;73669:4;;73651:7;;73669:4;;;73651;;73669;;73651:7;;;;;;-1:-1:-1;;;;;73651:23:0;;;:7;;;;;;;;;;;:23;73714:48;;-1:-1:-1;;;73714:48:0;;73687:24;;55994:42;;73714:33;;:48;;73748:7;;73757:4;;73714:48;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;73714:48:0;;;;;;;;;;;;:::i;:::-;73687:75;;73780:7;73805:1;73788:7;:14;:18;73780:27;;;;;;;;;;;;;;73773:34;;;;73489:326;;;:::o;56123:41::-;;;;:::o;70305:1047::-;29568:10;;-1:-1:-1;;;;;29568:10:0;29554;:24;;:54;;;29596:12;:10;:12::i;:::-;-1:-1:-1;;;;;29582:26:0;:10;-1:-1:-1;;;;;29582:26:0;;29554:54;29546:78;;;;-1:-1:-1;;;29546:78:0;;;;;;;:::i;:::-;70400:13:::1;70435:9:::0;70430:96:::1;70454:7;:14:::0;70450:18;::::1;70430:96;;;70490:7;70498:1;70490:10;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;70490:10:0::1;-1:-1:-1::0;;;;;70490:22:0::1;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;70470:3:0::1;;70430:96;;;-1:-1:-1::0;70555:4:0::1;::::0;:29:::1;::::0;-1:-1:-1;;;70555:29:0;;70538:14:::1;::::0;-1:-1:-1;;;;;70555:4:0::1;::::0;:14:::1;::::0;:29:::1;::::0;70578:4:::1;::::0;70555:29:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;70538:46;;70602:9;70597:698;70621:13;:20;70617:1;:24;70597:698;;;70663:10;70797:9:::0;70792:186:::1;70816:7;:14:::0;70812:18;::::1;70792:186;;;70883:13;70897:1;70883:16;;;;;;;;;;;;;;:23;;;-1:-1:-1::0;;;;;70860:46:0::1;70868:7;70876:1;70868:10;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;70868:10:0::1;70860:46;70856:107;;;70939:4;70931:12;;70856:107;70832:3;;70792:186;;;;71000:5;70992:28;;;;-1:-1:-1::0;;;70992:28:0::1;;;;;;;:::i;:::-;71045:33;71055:13;71069:1;71055:16;;;;;;;;;;;;;;:22;;;71045:33;;:5;:9;;:33;;;;:::i;:::-;71037:41;;71093:14;71110:44;71149:4;71110:34;71121:13;71135:1;71121:16;;;;;;;;;;;;;;:22;;;71110:34;;:6;:10;;:34;;;;:::i;:44::-;71093:61;;71169:50;71187:13;71201:1;71187:16;;;;;;;;;::::0;;::::1;::::0;;;;;;:23;71169:4:::1;::::0;-1:-1:-1;;;;;71169:4:0::1;::::0;71212:6;71169:17:::1;:50::i;:::-;71249:13;71263:1;71249:16;;;;;;;;;;;;;;:23;;;-1:-1:-1::0;;;;;71234:47:0::1;;:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;70643:3:0::1;::::0;;::::1;::::0;-1:-1:-1;70597:698:0::1;::::0;-1:-1:-1;;;70597:698:0::1;;;71315:5;71324:4;71315:13;71307:37;;;;-1:-1:-1::0;;;71307:37:0::1;;;;;;;:::i;:::-;29635:1;;70305:1047:::0;:::o;56512:157::-;56607:54;;-1:-1:-1;;;56607:54:0;;56561:19;;56607:4;;:10;;:54;;56618:6;;56626:10;;;;;;56607:54;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56593:68;56512:157;-1:-1:-1;;56512:157:0:o;58723:101::-;29568:10;;-1:-1:-1;;;;;29568:10:0;29554;:24;;:54;;;29596:12;:10;:12::i;:::-;-1:-1:-1;;;;;29582:26:0;:10;-1:-1:-1;;;;;29582:26:0;;29554:54;29546:78;;;;-1:-1:-1;;;29546:78:0;;;;;;;:::i;:::-;58793:23:::1;58807:1;58810:5;58793:13;:23::i;29200:27::-:0;;;;:::o;27905:94::-;27963:7;27905:94;:::o;35746:169::-;29568:10;;-1:-1:-1;;;;;29568:10:0;29554;:24;;:54;;;29596:12;:10;:12::i;:::-;-1:-1:-1;;;;;29582:26:0;:10;-1:-1:-1;;;;;29582:26:0;;29554:54;29546:78;;;;-1:-1:-1;;;29546:78:0;;;;;;;:::i;:::-;35829:12:::1;:28:::0;;;35873:34:::1;::::0;::::1;::::0;::::1;::::0;35844:13;;35873:34:::1;:::i;56229:31::-:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;56229:31:0;;-1:-1:-1;56229:31:0;:::o;58336:335::-;30083:12;:10;:12::i;:::-;-1:-1:-1;;;;;30069:26:0;:10;-1:-1:-1;;;;;30069:26:0;;30061:50;;;;-1:-1:-1;;;30061:50:0;;;;;;;:::i;:::-;58399:16:::1;58433:1;58399:36;;58478:4;-1:-1:-1::0;;;;;58454:29:0::1;:1;-1:-1:-1::0;;;;;58454:10:0::1;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;58454:29:0::1;;58446:57;;;;-1:-1:-1::0;;;58446:57:0::1;;;;;;;:::i;:::-;58521:9;58516:122;58540:7;:14:::0;58536:18;::::1;58516:122;;;58597:7;58605:1;58597:10;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;58584:24:0;;::::1;58597:10:::0;::::1;58584:24;;58576:50;;;;-1:-1:-1::0;;;58576:50:0::1;;;;;;;:::i;:::-;58556:3;;58516:122;;;-1:-1:-1::0;58648:7:0::1;:15:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;58648:15:0;;;;;::::1;::::0;;-1:-1:-1;;;;;;58648:15:0::1;-1:-1:-1::0;;;;;58648:15:0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;58336:335:0:o;28863:29::-;;;;:::o;28067:22::-;;;-1:-1:-1;;;;;28067:22:0;;:::o;32166:123::-;30540:5;;;;;;;;;-1:-1:-1;;;;;30540:5:0;-1:-1:-1;;;;;30540:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;30526:32:0;:10;-1:-1:-1;;;;;30526:32:0;;:62;;;;30576:12;:10;:12::i;:::-;-1:-1:-1;;;;;30562:26:0;:10;-1:-1:-1;;;;;30562:26:0;;30526:62;30518:86;;;;-1:-1:-1;;;30518:86:0;;;;;;;:::i;:::-;32251:13:::1;:30:::0;;-1:-1:-1;;32251:30:0::1;::::0;::::1;;::::0;;;::::1;::::0;;32166:123::o;28096:21::-;;;-1:-1:-1;;;;;28096:21:0;;:::o;56171:49::-;56212:8;56171:49;:::o;26187:26::-;;;;;;-1:-1:-1;;;;;26187:26:0;;:::o;60972:92::-;61042:7;:14;60972:92;:::o;32522:202::-;29568:10;;-1:-1:-1;;;;;29568:10:0;29554;:24;;:54;;;29596:12;:10;:12::i;:::-;-1:-1:-1;;;;;29582:26:0;:10;-1:-1:-1;;;;;29582:26:0;;29554:54;29546:78;;;;-1:-1:-1;;;29546:78:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;32609:25:0;::::1;32601:34;;;::::0;::::1;;32646:10;:24:::0;;-1:-1:-1;;;;;;32646:24:0::1;-1:-1:-1::0;;;;;32646:24:0;::::1;;::::0;;32686:30:::1;::::0;::::1;::::0;::::1;::::0;32646:24;;32686:30:::1;:::i;52561:281::-:0;52650:5;;-1:-1:-1;;;;;52650:5:0;52628:10;:28;52620:37;;;;;;52714:5;;52676:34;;;-1:-1:-1;;;52676:34:0;;;;-1:-1:-1;;;;;52714:5:0;;;;52676:32;;;;;:34;;;;;;;;;;;;;;:32;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;52676:43:0;;52668:52;;;;;;52731:30;52748:12;52731:16;:30::i;:::-;52804:4;;:29;;-1:-1:-1;;;52804:29:0;;52772:62;;52790:12;;-1:-1:-1;;;;;52804:4:0;;;;:14;;:29;;52827:4;;52804:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52772:4;;-1:-1:-1;;;;;52772:4:0;;:62;:17;:62::i;56677:897::-;57105:4;57099:11;-1:-1:-1;;;57124:86:0;;57004:4;56988:22;;57247:4;57231:21;;57224:43;;;-1:-1:-1;;;57304:4:0;57288:21;;57281:97;56825:19;;57429:4;57099:11;56825:19;57407:27;57457:72;;-1:-1:-1;;;57457:72:0;;57392:42;;-1:-1:-1;;;;;;57457:32:0;;;-1:-1:-1;57457:32:0;;:72;;57490:6;;57498:11;;57511:8;;57521:7;;57457:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;57547:19:0;;-1:-1:-1;;;;;57547:19:0;;;-1:-1:-1;57547:19:0;;-1:-1:-1;57547:19:0;;;56677:897;;;;;;;:::o;63747:1456::-;64052:4;;:29;;-1:-1:-1;;;64052:29:0;;63843:15;;;;;;;;;;-1:-1:-1;;;;;64052:4:0;;:14;;:29;;64075:4;;64052:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64030:51;;-1:-1:-1;;64248:24:0;;64293:1;64283:11;;64305:17;64342:9;64337:348;64361:7;:14;64357:18;;64337:348;;;64401:7;64409:1;64401:10;;;;;;;;;;;;;;;;;;;:22;;;-1:-1:-1;;;64401:22:0;;;;-1:-1:-1;;;;;64401:10:0;;;;:20;;:22;;;;;;;;;;:10;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64397:277;;;64444:11;64458:7;64466:1;64458:10;;;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;;;64458:16:0;;;;-1:-1:-1;;;;;64458:10:0;;;;:14;;:16;;;;;;;;;;:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64444:30;;64503:10;64497:3;:16;64493:166;;;64551:3;64538:16;;64587:1;64577:11;;64623:7;64631:1;64623:10;;;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;;;64623:16:0;;;;-1:-1:-1;;;;;64623:10:0;;;;:14;;:16;;;;;;;;;;:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64611:28;;64493:166;64397:277;;64377:3;;64337:348;;;-1:-1:-1;64697:13:0;64713:26;:9;64727:11;64713:13;:26::i;:::-;64697:42;;64752:18;64796:1;64785:12;;64815:9;64810:263;64834:7;:14;64830:18;;64810:263;;;64870:11;64902:7;64910:1;64902:10;;;;;;;;;;;;;;;;;;:39;;-1:-1:-1;;;64902:39:0;;-1:-1:-1;;;;;64902:10:0;;;;:26;;:39;;64929:11;;64902:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64896:45;;64968:10;64962:3;:16;64958:104;;;65012:3;64999:16;;65045:1;65034:12;;64958:104;-1:-1:-1;64850:3:0;;64810:263;;;;65155:7;65163:8;65155:17;;;;;;;;;;;;;;;;;;:40;;-1:-1:-1;;;65155:40:0;;-1:-1:-1;;;;;65155:17:0;;;;:33;;:40;;65189:5;;65155:40;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65142:53;;63747:1456;;;;;;;;:::o;33741:263::-;29970:10;;-1:-1:-1;;;;;29970:10:0;29956;:24;29948:48;;;;-1:-1:-1;;;29948:48:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;33822:22:0;::::1;33814:31;;;::::0;::::1;;33856:5;::::0;33870:7:::1;::::0;;33856:25:::1;::::0;-1:-1:-1;;;33856:25:0;;-1:-1:-1;;;;;33856:5:0;;::::1;::::0;:13:::1;::::0;:25:::1;::::0;33870:7;;::::1;::::0;33856:5:::1;::::0;:25:::1;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;33892:7:0::1;:18:::0;;-1:-1:-1;;;;;;33892:18:0::1;-1:-1:-1::0;;;;;33892:18:0;;::::1;::::0;;;::::1;::::0;;;33921:5:::1;::::0;:35:::1;::::0;-1:-1:-1;;;33921:35:0;;:5;;::::1;::::0;:13:::1;::::0;:35:::1;::::0;33935:7:::1;::::0;-1:-1:-1;;33952:2:0;33921:35:::1;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;33972:24;33987:8;33972:24;;;;;;:::i;46908:1736::-:0;46984:4;47001:16;47020:24;47030:13;47020:9;:24::i;:::-;47001:43;;47055:28;;:::i;:::-;47086:5;;:31;;-1:-1:-1;;;47086:31:0;;-1:-1:-1;;;;;47086:5:0;;;;:16;;:31;;47111:4;;47086:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47055:62;;47194:6;:17;;;47215:1;47194:22;47190:40;;;47225:5;47218:12;;;;;;47190:40;47375:14;;47354:17;;;;47334:38;;:15;;:19;:38::i;:::-;:55;47330:73;;;47398:5;47391:12;;;;;;47330:73;47522:14;;47500:17;;;;47480:38;;:15;;:19;:38::i;:::-;:56;47476:73;;47545:4;47538:11;;;;;;47476:73;47979:5;;:23;;;-1:-1:-1;;;47979:23:0;;;;47957:19;;-1:-1:-1;;;;;47979:5:0;;:21;;:23;;;;;;;;;;;;;;:5;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47957:45;;48031:13;;48017:11;:27;48013:44;;;48053:4;48046:11;;;;;;;48013:44;48111:13;48127:22;:20;:22::i;:::-;48111:38;;48239:6;:16;;;48212:24;48222:13;;48212:5;:9;;:24;;;;:::i;:::-;:43;48208:60;;;48264:4;48257:11;;;;;;;;48208:60;48281:14;48322:6;:16;;;48314:5;:24;48310:66;;;48359:16;;;;48349:27;;:5;;:9;:27::i;:::-;48340:36;;48310:66;48546:5;;:23;;;-1:-1:-1;;;48546:23:0;;;;48529:14;;-1:-1:-1;;;;;48546:5:0;;:21;;:23;;;;;;;;;;;;;;:5;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48529:40;-1:-1:-1;48617:18:0;48529:40;48628:6;48617:10;:18::i;:::-;48588:12;;:26;;48605:8;48588:16;:26::i;:::-;:47;;46908:1736;-1:-1:-1;;;;;;;;46908:1736:0:o;60765:199::-;60827:7;60847:11;60861:17;:15;:17::i;:::-;60903:4;;:29;;-1:-1:-1;;;60903:29:0;;60847:31;;-1:-1:-1;60895:38:0;;-1:-1:-1;;;;;60903:4:0;;;;:14;;:29;;60926:4;;60903:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60895:3;;:7;:38::i;:::-;60889:44;-1:-1:-1;;60765:199:0;:::o;35192:154::-;29568:10;;-1:-1:-1;;;;;29568:10:0;29554;:24;;:54;;;29596:12;:10;:12::i;:::-;-1:-1:-1;;;;;29582:26:0;:10;-1:-1:-1;;;;;29582:26:0;;29554:54;29546:78;;;;-1:-1:-1;;;29546:78:0;;;;;;;:::i;:::-;35270:14:::1;:23:::0;;;35309:29:::1;::::0;::::1;::::0;::::1;::::0;35287:6;;35309:29:::1;:::i;57582:222::-:0;57745:51;57757:6;57765:11;57778:8;57788:7;57745:11;:51::i;:::-;57582:222;;;;:::o;28007:21::-;;;-1:-1:-1;;;;;28007:21:0;;:::o;60241:478::-;60366:7;:14;60286:19;;;;60349:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;60318:63;;60397:9;60392:292;60416:7;:14;60412:18;;60392:292;;;60452:19;;:::i;:::-;60495:7;60503:1;60495:10;;;;;;;;;;;;;;;;;:23;;;-1:-1:-1;;;60495:23:0;;;;-1:-1:-1;;;;;60495:10:0;;;;:21;;:23;;;;;;;;;;:10;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;60495:23:0;;;;;;;;;;;;:::i;:::-;60486:32;;60549:7;:10;;60557:1;;60549:10;;;;;;;;;;;;;;;;-1:-1:-1;;;;;60549:10:0;60533:5;;;:27;60586:7;:10;;60594:1;;60586:10;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;;;60586:16:0;;;;-1:-1:-1;;;;;60586:10:0;;;;:14;;:16;;;;;;;;;;:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60575:8;;;:27;60626:7;:10;;60634:1;;60626:10;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;;;60626:16:0;;;;-1:-1:-1;;;;;60626:10:0;;;;:14;;:16;;;;;;;;;;:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60617:6;;;:25;60657:11;;60617:1;;60657:8;;60666:1;;60657:11;;;;;;;;;;;;;;;:15;-1:-1:-1;60432:3:0;;60392:292;;53271:173;29734:10;;-1:-1:-1;;;;;29734:10:0;29720;:24;;:54;;;29762:12;:10;:12::i;:::-;-1:-1:-1;;;;;29748:26:0;:10;-1:-1:-1;;;;;29748:26:0;;29720:54;:88;;;;29792:5;;;;;;;;;-1:-1:-1;;;;;29792:5:0;-1:-1:-1;;;;;29792:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;29778:30:0;:10;-1:-1:-1;;;;;29778:30:0;;29720:88;:124;;;;29826:5;;;;;;;;;-1:-1:-1;;;;;29826:5:0;-1:-1:-1;;;;;29826:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;29812:32:0;:10;-1:-1:-1;;;;;29812:32:0;;29720:124;29698:185;;;;-1:-1:-1;;;29698:185:0;;;;;;;:::i;:::-;53343:13:::1;:20:::0;;-1:-1:-1;;53343:20:0::1;53359:4;53343:20;::::0;;53374:5:::1;::::0;:22:::1;::::0;;-1:-1:-1;;;53374:22:0;;;;-1:-1:-1;;;;;53374:5:0;;::::1;::::0;:20:::1;::::0;:22:::1;::::0;;::::1;::::0;53343:13:::1;::::0;53374:22;;;;;;;;53343:13;53374:5;:22;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;53414:22:0::1;::::0;::::1;::::0;-1:-1:-1;53414:22:0;;-1:-1:-1;53414:22:0::1;53271:173::o:0;18334:622::-;18704:10;;;18703:62;;-1:-1:-1;18720:39:0;;-1:-1:-1;;;18720:39:0;;-1:-1:-1;;;;;18720:15:0;;;;;:39;;18744:4;;18751:7;;18720:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;18703:62;18695:152;;;;-1:-1:-1;;;18695:152:0;;;;;;;:::i;:::-;18858:90;18878:5;18908:22;;;18932:7;18941:5;18885:62;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;18885:62:0;;;;;;;;;;;;;;-1:-1:-1;;;;;18885:62:0;-1:-1:-1;;;;;;18885:62:0;;;;;;;;;;18858:19;:90::i;5437:196::-;5540:12;5572:53;5595:6;5603:4;5609:1;5612:12;5572:22;:53::i;:::-;5565:60;5437:196;-1:-1:-1;;;;5437:196:0:o;37275:98::-;37347:5;;:18;;;-1:-1:-1;;;37347:18:0;;;;37320:7;;-1:-1:-1;;;;;37347:5:0;;:16;;:18;;;;;;;;;;;;;;:5;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;76161:207::-;76278:16;;;76292:1;76278:16;;;;;;;;;76220;;;;76278;;;;;;;;;;-1:-1:-1;;76328:4:0;;76305:12;;;;-1:-1:-1;;;;;;76328:4:0;;76305:12;;-1:-1:-1;76328:4:0;;76305:12;;;;-1:-1:-1;;;;;76305:28:0;;;:12;;;;;;;;;;;:28;76351:9;-1:-1:-1;76161:207:0;:::o;17675:177::-;17758:86;17778:5;17808:23;;;17833:2;17837:5;17785:58;;;;;;;;;:::i;12308:181::-;12366:7;12398:5;;;12422:6;;;;12414:46;;;;-1:-1:-1;;;12414:46:0;;;;;;;:::i;:::-;12480:1;12308:181;-1:-1:-1;;;12308:181:0:o;72849:632::-;72993:4;;:29;;-1:-1:-1;;;72993:29:0;;72926:20;;;;;;-1:-1:-1;;;;;72993:4:0;;:14;;:29;;73016:4;;72993:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72974:48;;73051:13;73039:8;:25;73035:439;;73174:13;73189:1;73166:25;;;;;;;73035:439;73224:16;73243:53;73287:8;73243:39;73273:8;73257:13;:24;73243:13;:39::i;:::-;:43;;:53::i;:::-;73224:72;;73327:13;73315:8;:25;73311:152;;73369:13;73384:1;73361:25;;;;;;;;73311:152;73435:8;-1:-1:-1;73445:1:0;;-1:-1:-1;73427:20:0;;-1:-1:-1;73427:20:0;72849:632;;;;:::o;61633:844::-;61708:7;;;;;61824:283;61848:7;:14;61844:18;;61824:283;;;61884:11;61898:7;61906:1;61898:10;;;;;;;;;;;;;;;;;;:34;;-1:-1:-1;;;61898:34:0;;-1:-1:-1;;;;;61898:10:0;;;;:26;;:34;;61925:6;;61898:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61884:48;;61957:10;61951:3;:16;61947:149;;;62000:1;61988:13;;62033:3;62020:16;;62064:7;62072:1;62064:10;;;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;;;62064:16:0;;;;-1:-1:-1;;;;;62064:10:0;;;;:14;;:16;;;;;;;;;;:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62055:25;;61947:149;-1:-1:-1;61864:3:0;;61824:283;;;-1:-1:-1;62119:19:0;62141:34;62156:18;:6;62167;62156:10;:18::i;:::-;62141:10;;:14;:34::i;:::-;62119:56;;62193:9;62188:181;62212:7;:14;62208:18;;62188:181;;;62257:9;62252:1;:14;62248:110;;62301:41;62317:7;62325:1;62317:10;;;;;;;62301:41;62287:55;;62248:110;62228:3;;62188:181;;;;62381:11;62395:34;62422:6;62395:22;:20;:22::i;:34::-;62381:48;-1:-1:-1;62449:20:0;:11;62381:48;62449:15;:20::i;:::-;62442:27;61633:844;-1:-1:-1;;;;;;;61633:844:0:o;62597:1028::-;62672:7;-1:-1:-1;;62672:7:0;;62768:237;62792:7;:14;62788:18;;62768:237;;;62828:11;62842:7;62850:1;62842:10;;;;;;;;;;;;;;;;;;:34;;-1:-1:-1;;;62842:34:0;;-1:-1:-1;;;;;62842:10:0;;;;:26;;:34;;62869:6;;62842:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62828:48;;62901:9;62895:3;:15;62891:103;;;62943:1;62931:13;;62975:3;62963:15;;62891:103;-1:-1:-1;62808:3:0;;62768:237;;;;63017:19;63058:9;63053:468;63077:7;:14;63073:18;;63053:468;;;63122:9;63117:1;:14;63113:397;;63166:41;63182:7;63190:1;63182:10;;;;;;;63166:41;63152:55;;63113:397;;;63248:13;63264:7;63272:1;63264:10;;;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;;;63264:16:0;;;;-1:-1:-1;;;;;63264:10:0;;;;:14;;:16;;;;;;;;;;:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63248:32;;63311:6;63303:5;:14;63299:125;;;63399:5;63390:14;;63299:125;63456:38;63472:21;:9;63486:6;63472:13;:21::i;:::-;63456:11;;:15;:38::i;:::-;63442:52;;63113:397;;63093:3;;63053:468;;;;63531:11;63545:34;63572:6;63545:22;:20;:22::i;:34::-;63531:48;-1:-1:-1;63597:20:0;:11;63531:48;63597:15;:20::i;:::-;63590:27;62597:1028;-1:-1:-1;;;;;;62597:1028:0:o;69244:894::-;69460:13;;;;69456:52;;;69490:7;;69456:52;69594:7;:14;69590:58;;69630:7;;69590:58;69661:14;69677:17;69696:15;69713:17;69734:24;:22;:24::i;:::-;69660:98;;;;;;;;69787:9;69775;:21;69771:164;;;69894:7;69902:6;69894:15;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;69894:15:0;-1:-1:-1;;;;;69894:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;69771:164;69961:4;;:29;;-1:-1:-1;;;69961:29:0;;69947:11;;-1:-1:-1;;;;;69961:4:0;;:14;;:29;;69984:4;;69961:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;69947:43;-1:-1:-1;70005:7:0;;70001:130;;70029:49;70055:7;70063;70055:16;;;;;;;;;;;;;;;;;;70029:4;;-1:-1:-1;;;;;70029:4:0;;;;70055:16;70074:3;70029:17;:49::i;:::-;70093:7;70101;70093:16;;;;;;;;;;;;;;;;;:26;;;-1:-1:-1;;;70093:26:0;;;;-1:-1:-1;;;;;70093:16:0;;;;:24;;:26;;;;;;;;;;:16;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70001:130;69244:894;;;;;;:::o;75706:148::-;75766:20;75814:32;75828:17;:15;:17::i;:::-;75814:13;:32::i;12772:136::-;12830:7;12857:43;12861:1;12864;12857:43;;;;;;;;;;;;;;;;;:3;:43::i;66280:2753::-;66397:15;;66574:16;66397:15;66624:17;:15;:17::i;:::-;66676:4;;:29;;-1:-1:-1;;;66676:29:0;;66603:38;;-1:-1:-1;66654:19:0;;-1:-1:-1;;;;;66676:4:0;;;;:14;;:29;;66699:4;;66676:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66654:51;-1:-1:-1;66718:13:0;66734:27;66654:51;66750:10;66734:15;:27::i;:::-;66718:43;-1:-1:-1;66778:15:0;66774:302;;66887:11;66872:12;:26;66868:143;;;66984:11;66969:26;;66868:143;67027:37;;;;;66774:302;67103:5;;:31;;-1:-1:-1;;;67103:31:0;;67088:12;;-1:-1:-1;;;;;67103:5:0;;:16;;:31;;67128:4;;67103:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;67088:56;;67169:4;67161:5;:12;67157:1869;;;67200:12;;;;-1:-1:-1;67229:20:0;67252:25;67200:12;67264;67252:11;:25::i;:::-;67229:48;;67433:1;67418:12;:16;:46;;;;;67452:12;67438:11;:26;67418:46;67414:693;;;67534:44;67548:29;:12;67565:11;67548:16;:29::i;67534:44::-;-1:-1:-1;67616:4:0;;:29;;-1:-1:-1;;;67616:29:0;;67597:16;;-1:-1:-1;;;;;67616:4:0;;:14;;:29;;67639:4;;67616:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;67597:48;;67786:12;67775:8;:23;67771:321;;;67837:8;67827:7;:18;67823:250;;;67884:8;67874:18;;67934:1;67919:16;;67823:250;;;68007:42;68027:7;68016:8;:18;68036:12;68007:8;:42::i;:::-;67992:57;;67823:250;67414:693;;67157:1869;;;;68236:12;;;;-1:-1:-1;68263:20:0;68286:23;68236:12;68296;68286:9;:23::i;:::-;68263:46;;68345:1;68330:12;:16;:46;;;;;68364:12;68350:11;:26;68330:46;68326:689;;;68448:44;68462:29;:12;68479:11;68462:16;:29::i;68448:44::-;-1:-1:-1;68530:4:0;;:29;;-1:-1:-1;;;68530:29:0;;68511:16;;-1:-1:-1;;;;;68530:4:0;;:14;;:29;;68553:4;;68530:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68511:48;;68700:12;68689:8;:23;68685:315;;;68749:8;68741:5;:16;68737:244;;;68794:8;68786:16;;68844:1;68829:16;;68737:244;;;68917:40;68937:5;68926:8;:16;68944:12;68917:8;:40::i;:::-;68902:55;;68737:244;68326:689;;67157:1869;;66280:2753;;;;;;;;;;:::o;14609:132::-;14667:7;14694:39;14698:1;14701;14694:39;;;;;;;;;;;;;;;;;:3;:39::i;13662:471::-;13720:7;13965:6;13961:47;;-1:-1:-1;13995:1:0;13988:8;;13961:47;14032:5;;;14036:1;14032;:5;:1;14056:5;;;;;:10;14048:56;;;;-1:-1:-1;;;14048:56:0;;;;;;;:::i;73823:578::-;74100:4;;73889:7;;;;-1:-1:-1;;;;;74100:4:0;56074:42;74092:21;74088:274;;;-1:-1:-1;74145:8:0;74088:274;;;74175:15;;;;;-1:-1:-1;;;;;74175:15:0;74171:191;;74236:19;74246:8;74236:9;:19::i;:::-;74221:34;;74171:191;;;74314:15;;74303:47;;-1:-1:-1;;;74303:47:0;;74314:15;;;;-1:-1:-1;;;;;74314:15:0;;74303:37;;:47;;74341:8;;74303:47;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;59004:956::-;59075:9;59070:844;59094:7;:14;59090:18;;59070:844;;;59147:7;59155:1;59147:10;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59134:24:0;;;59147:10;;59134:24;59130:773;;;59179:17;59199:7;59207:1;59199:10;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59199:10:0;-1:-1:-1;;;;;59199:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59179:44;;59249:5;59244:95;;59287:12;59279:40;;;;-1:-1:-1;;;59279:40:0;;;;;;;:::i;:::-;59448:7;:14;-1:-1:-1;;59448:18:0;59443:23;;59439:112;;59504:7;59512:14;;-1:-1:-1;;59512:18:0;;;59504:27;;;;;;;;;;;;;;;;59491:7;:10;;-1:-1:-1;;;;;59504:27:0;;;;59499:1;;59491:10;;;;;;;;;;;;;;:40;;;;;-1:-1:-1;;;;;59491:40:0;;;;;-1:-1:-1;;;;;59491:40:0;;;;;;59439:112;59646:7;:13;;;;;;;;;;;;;;-1:-1:-1;;59646:13:0;;;;;;;-1:-1:-1;;;;;;59646:13:0;;;;;;;;;59768:4;;:29;;-1:-1:-1;;;59768:29:0;;-1:-1:-1;;;;;59768:4:0;;;;:14;;:29;;59791:4;;59768:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:33;59764:99;;;59826:17;59841:1;59826:14;:17::i;:::-;59881:7;;;;59130:773;59110:3;;59070:844;;;-1:-1:-1;59924:28:0;;-1:-1:-1;;;59924:28:0;;;;;;;:::i;75928:225::-;76027:5;;:31;;-1:-1:-1;;;76027:31:0;;76005:19;;-1:-1:-1;;;;;76027:5:0;;:16;;:31;;76052:4;;76027:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;76005:63;;76082:12;76096:19;76119:26;76133:11;76119:13;:26::i;:::-;-1:-1:-1;;;;;;;75928:225:0:o;31305:727::-;31477:4;;-1:-1:-1;;;;;31477:4:0;31469:27;31461:68;;;;-1:-1:-1;;;31461:68:0;;;;;;;:::i;:::-;31542:5;:24;;-1:-1:-1;;;;;;31542:24:0;-1:-1:-1;;;;;31542:24:0;;;;;;;;;;;31591:13;;;-1:-1:-1;;;31591:13:0;;;;:5;;;;;:11;;:13;;;;;;;;;;;;;;;:5;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31577:4;:28;;-1:-1:-1;;;;;;31577:28:0;-1:-1:-1;;;;;31577:28:0;;;;;;;;31616:37;;:4;31633:6;-1:-1:-1;;31616:16:0;:37::i;:::-;31712:10;:24;;-1:-1:-1;;;;;31712:24:0;;;-1:-1:-1;;;;;;31712:24:0;;;;;;;31747:7;:18;;;;;;;;;;;;31776:6;:16;;;;;;;;;;;;;;31712:10;31838:14;:18;;;31884:5;31867:14;:22;31915:3;31900:12;:18;31929:13;:17;31959:5;;:35;;-1:-1:-1;;;31959:35:0;;:5;;;;:13;;:35;;31973:7;;;-1:-1:-1;;;31959:35:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;31305:727;;;;:::o;19980:761::-;20404:23;20430:69;20458:4;20430:69;;;;;;;;;;;;;;;;;20438:5;-1:-1:-1;;;;;20430:27:0;;;:69;;;;;:::i;:::-;20514:17;;20404:95;;-1:-1:-1;20514:21:0;20510:224;;20656:10;20645:30;;;;;;;;;;;;:::i;:::-;20637:85;;;;-1:-1:-1;;;20637:85:0;;;;;;;:::i;6814:979::-;6944:12;6977:18;6988:6;6977:10;:18::i;:::-;6969:60;;;;-1:-1:-1;;;6969:60:0;;;;;;;:::i;:::-;7103:12;7117:23;7144:6;-1:-1:-1;;;;;7144:11:0;7164:8;7175:4;7144:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7102:78;;;;7195:7;7191:595;;;7226:10;-1:-1:-1;7219:17:0;;-1:-1:-1;7219:17:0;7191:595;7340:17;;:21;7336:439;;7603:10;7597:17;7664:15;7651:10;7647:2;7643:19;7636:44;7551:148;7746:12;7739:20;;-1:-1:-1;;;7739:20:0;;;;;;;;:::i;71415:1249::-;71513:7;:14;71473:23;;71509:60;;-1:-1:-1;71556:1:0;71549:8;;71509:60;71625:19;;71615:7;:29;71611:70;;;-1:-1:-1;71668:1:0;71661:8;;71611:70;-1:-1:-1;71711:1:0;;71842:815;71867:7;71849:15;:25;71842:815;;;-1:-1:-1;;71891:17:0;;71970:326;71994:7;:14;71990:18;;71970:326;;;72038:7;72046:1;72038:10;;;;;;;;;;;;;;;;;;;:22;;;-1:-1:-1;;;72038:22:0;;;;-1:-1:-1;;;;;72038:10:0;;;;:20;;:22;;;;;;;;;;:10;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72034:247;;;72085:11;72099:7;72107:1;72099:10;;;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;;;72099:16:0;;;;-1:-1:-1;;;;;72099:10:0;;;;:14;;:16;;;;;;;;;;:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72085:30;;72148:9;72142:3;:15;72138:124;;;72198:3;72186:15;;72237:1;72228:10;;72138:124;72034:247;;72010:3;;71970:326;;;;72315:7;72323:6;72315:15;;;;;;;;;;;;;;;;;;;:27;;;-1:-1:-1;;;72315:27:0;;;;-1:-1:-1;;;;;72315:15:0;;;;:25;;:27;;;;;;;;;;:15;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72310:91;;72363:22;;;;;72310:91;72433:72;72453:7;72461:6;72453:15;;;;;;;;;;;;;;;;;;:51;;-1:-1:-1;;;72453:51:0;;-1:-1:-1;;;;;72453:15:0;;;;:24;;:51;;72478:25;;;;72453:51;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72433:15;;:19;:72::i;:::-;72415:90;-1:-1:-1;72520:3:0;;;;;72586:1;72581:6;;72577:69;;72608:22;;;;;72577:69;71842:815;;;;13211:192;13297:7;13333:12;13325:6;;;;13317:29;;;;-1:-1:-1;;;13317:29:0;;;;;;;;:::i;:::-;-1:-1:-1;;;13369:5:0;;;13211:192::o;10980:106::-;11038:7;11069:1;11065;:5;:13;;11077:1;11065:13;;;-1:-1:-1;11073:1:0;;10980:106;-1:-1:-1;10980:106:0:o;15237:278::-;15323:7;15358:12;15351:5;15343:28;;;;-1:-1:-1;;;15343:28:0;;;;;;;;:::i;:::-;;15382:9;15398:1;15394;:5;;;;;;;15237:278;-1:-1:-1;;;;;15237:278:0:o;2322:619::-;2382:4;2850:20;;2693:66;2890:23;;;;;;:42;;-1:-1:-1;;2917:15:0;;;2882:51;-1:-1:-1;;2322:619:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;4863:473;;4981:4;4969:9;4964:3;4960:19;4956:30;4953:2;;;-1:-1;;4989:12;4953:2;5017:20;4981:4;5017:20;:::i;:::-;5008:29;;85:6;72:20;97:33;124:5;97:33;:::i;:::-;5096:75;;5233:2;5286:22;;5409:20;40758:6;40747:18;;43365:34;;43355:2;;-1:-1;;43403:12;43355:2;5233;5248:16;;5241:74;5252:5;4947:389;-1:-1;;4947:389::o;5756:241::-;;5860:2;5848:9;5839:7;5835:23;5831:32;5828:2;;;-1:-1;;5866:12;5828:2;85:6;72:20;97:33;124:5;97:33;:::i;6004:263::-;;6119:2;6107:9;6098:7;6094:23;6090:32;6087:2;;;-1:-1;;6125:12;6087:2;226:6;220:13;238:33;265:5;238:33;:::i;6274:617::-;;;;;6429:3;6417:9;6408:7;6404:23;6400:33;6397:2;;;-1:-1;;6436:12;6397:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;6488:63;-1:-1;6588:2;6627:22;;72:20;97:33;72:20;97:33;:::i;:::-;6596:63;-1:-1;6696:2;6735:22;;72:20;97:33;72:20;97:33;:::i;:::-;6704:63;-1:-1;6804:2;6843:22;;72:20;97:33;72:20;97:33;:::i;:::-;6391:500;;;;-1:-1;6391:500;;-1:-1;;6391:500::o;6898:435::-;;7056:2;;7044:9;7035:7;7031:23;7027:32;7024:2;;;-1:-1;;7062:12;7024:2;7120:17;7107:31;7158:18;7150:6;7147:30;7144:2;;;-1:-1;;7180:12;7144:2;7285:22;;460:4;448:17;;444:27;-1:-1;434:2;;-1:-1;;475:12;434:2;522:6;509:20;544:109;559:93;645:6;559:93;:::i;:::-;544:109;:::i;:::-;681:21;;;738:14;;;;713:17;;;839:4;827:17;;;818:27;;;;815:36;-1:-1;812:2;;;-1:-1;;854:12;812:2;-1:-1;880:10;;874:235;899:6;896:1;893:13;874:235;;;979:66;1041:3;1029:10;979:66;:::i;:::-;967:79;;921:1;914:9;;;;;1060:14;;;;1088;;;;874:235;;;-1:-1;7200:117;;7018:315;-1:-1;;;;;;;;7018:315::o;7340:392::-;;7480:2;;7468:9;7459:7;7455:23;7451:32;7448:2;;;-1:-1;;7486:12;7448:2;7537:17;7531:24;7575:18;7567:6;7564:30;7561:2;;;-1:-1;;7597:12;7561:2;7684:22;;1262:4;1250:17;;1246:27;-1:-1;1236:2;;-1:-1;;1277:12;1236:2;1317:6;1311:13;1339:80;1354:64;1411:6;1354:64;:::i;1339:80::-;1447:21;;;1504:14;;;;1479:17;;;1593;;;1584:27;;;;1581:36;-1:-1;1578:2;;;-1:-1;;1620:12;1578:2;-1:-1;1646:10;;1640:217;1665:6;1662:1;1659:13;1640:217;;;5693:13;;1733:61;;1687:1;1680:9;;;;;1808:14;;;;1836;;1640:217;;;-1:-1;7617:99;7442:290;-1:-1;;;;;;;7442:290::o;7739:235::-;;7840:2;7828:9;7819:7;7815:23;7811:32;7808:2;;;-1:-1;;7846:12;7808:2;1948:6;1935:20;1960:30;1984:5;1960:30;:::i;7981:257::-;;8093:2;8081:9;8072:7;8068:23;8064:32;8061:2;;;-1:-1;;8099:12;8061:2;2083:6;2077:13;2095:30;2119:5;2095:30;:::i;8549:367::-;;;8673:2;8661:9;8652:7;8648:23;8644:32;8641:2;;;-1:-1;;8679:12;8641:2;8737:17;8724:31;8775:18;;8767:6;8764:30;8761:2;;;-1:-1;;8797:12;8761:2;8883:6;8872:9;8868:22;;;2442:3;2435:4;2427:6;2423:17;2419:27;2409:2;;-1:-1;;2450:12;2409:2;2493:6;2480:20;8775:18;2512:6;2509:30;2506:2;;;-1:-1;;2542:12;2506:2;2637:3;8673:2;2617:17;2578:6;2603:32;;2600:41;2597:2;;;-1:-1;;2644:12;2597:2;8673;2574:17;;;;;8817:83;;-1:-1;8635:281;;-1:-1;;;;8635:281::o;8923:362::-;;9048:2;9036:9;9027:7;9023:23;9019:32;9016:2;;;-1:-1;;9054:12;9016:2;9105:17;9099:24;9143:18;;9135:6;9132:30;9129:2;;;-1:-1;;9165:12;9129:2;9252:6;9241:9;9237:22;;;2786:3;2779:4;2771:6;2767:17;2763:27;2753:2;;-1:-1;;2794:12;2753:2;2834:6;2828:13;9143:18;38124:6;38121:30;38118:2;;;-1:-1;;38154:12;38118:2;2856:65;38227:9;38208:17;;-1:-1;;38204:33;9048:2;38285:15;2856:65;:::i;:::-;2847:74;;2941:6;2934:5;2927:21;3045:3;9048:2;3036:6;2969;3027:16;;3024:25;3021:2;;;-1:-1;;3052:12;3021:2;3072:39;3104:6;9048:2;3003:5;2999:16;9048:2;2969:6;2965:17;3072:39;:::i;:::-;-1:-1;9185:84;9010:275;-1:-1;;;;9010:275::o;9292:324::-;;9437:3;;9425:9;9416:7;9412:23;9408:33;9405:2;;;-1:-1;;9444:12;9405:2;3321:22;9437:3;3321:22;:::i;:::-;3312:31;;3467:22;5693:13;3417:16;3410:86;3563:2;3632:9;3628:22;5693:13;3563:2;3582:5;3578:16;3571:86;3723:2;3792:9;3788:22;5693:13;3723:2;3742:5;3738:16;3731:86;3891:2;3960:9;3956:22;5693:13;3891:2;3910:5;3906:16;3899:86;4059:3;4129:9;4125:22;5693:13;4059:3;4079:5;4075:16;4068:86;4221:3;4291:9;4287:22;5693:13;4221:3;4241:5;4237:16;4230:86;4382:3;4452:9;4448:22;5693:13;4382:3;4402:5;4398:16;4391:86;4543:3;4613:9;4609:22;5693:13;4543:3;4563:5;4559:16;4552:86;4704:3;;4776:9;4772:22;5693:13;4704:3;4724:5;4720:18;4713:88;;9496:104;;;;9399:217;;;;:::o;9623:241::-;;9727:2;9715:9;9706:7;9702:23;9698:32;9695:2;;;-1:-1;;9733:12;9695:2;-1:-1;5545:20;;9689:175;-1:-1;9689:175::o;9871:263::-;;9986:2;9974:9;9965:7;9961:23;9957:32;9954:2;;;-1:-1;;9992:12;9954:2;-1:-1;5693:13;;9948:186;-1:-1;9948:186::o;10746:103::-;-1:-1;;;;;40839:54;10807:37;;10801:48::o;14313:327::-;;14448:5;38764:12;39623:6;39618:3;39611:19;14532:52;14577:6;39660:4;39655:3;39651:14;39660:4;14558:5;14554:16;14532:52;:::i;:::-;38227:9;42870:14;-1:-1;;42866:28;14596:39;;;;39660:4;14596:39;;14395:245;-1:-1;;14395:245::o;22186:271::-;;13125:5;38764:12;13236:52;13281:6;13276:3;13269:4;13262:5;13258:16;13236:52;:::i;:::-;13300:16;;;;;22320:137;-1:-1;;22320:137::o;22464:222::-;-1:-1;;;;;40839:54;;;;10807:37;;22591:2;22576:18;;22562:124::o;22693:333::-;-1:-1;;;;;40839:54;;;10807:37;;40839:54;;23012:2;22997:18;;10807:37;22848:2;22833:18;;22819:207::o;23033:604::-;-1:-1;;;;;40839:54;;;10807:37;;40839:54;;;23441:2;23426:18;;10676:58;40839:54;;;23532:2;23517:18;;10676:58;40839:54;;;23623:2;23608:18;;10676:58;23268:3;23253:19;;23239:398::o;24207:349::-;-1:-1;;;;;40839:54;;;;10807:37;;24542:2;24527:18;;13910:58;24370:2;24355:18;;24341:215::o;24903:482::-;25136:2;25150:47;;;38764:12;;25121:18;;;39611:19;;;24903:482;;25136:2;39651:14;;;;;;12237:17;;;12228:27;;;;38432:14;;;24903:482;12393:414;12418:6;12415:1;12412:13;12393:414;;;12470:20;;25125:9;12474:4;12470:20;;12465:3;12458:33;12525:6;12519:13;21220:4;21292:16;21286:23;21220:4;21329:14;21322:38;21375:73;21220:4;21215:3;21211:14;21429:12;21375:73;:::i;:::-;21367:81;;;25136:2;21528:5;21524:16;21518:23;25136:2;21599:3;21595:14;22017:37;39651:14;21682:5;21678:16;21672:23;39651:14;21753:3;21749:14;22017:37;21842:4;;21835:5;21831:16;21825:23;21805:43;;21854:63;21842:4;21906:3;21902:14;21888:12;21854:63;:::i;:::-;-1:-1;12786:14;;;;12539:128;-1:-1;;39323:14;;;;12440:1;12433:9;12393:414;;25392:210;40545:13;;40538:21;12919:34;;25513:2;25498:18;;25484:118::o;26400:330::-;;26557:2;26578:17;26571:47;39623:6;26557:2;26546:9;26542:18;39611:19;42453:6;42448:3;39651:14;26546:9;39651:14;42430:30;42491:16;;;39651:14;42491:16;;;42484:27;;;;38227:9;42870:14;;;-1:-1;;42866:28;14260:39;;;26528:202;-1:-1;26528:202::o;26737:310::-;;26884:2;26905:17;26898:47;26959:78;26884:2;26873:9;26869:18;27023:6;26959:78;:::i;27054:416::-;27254:2;27268:47;;;15226:2;27239:18;;;39611:19;-1:-1;;;39651:14;;;15242:34;15295:12;;;27225:245::o;27477:416::-;27677:2;27691:47;;;15546:2;27662:18;;;39611:19;-1:-1;;;39651:14;;;15562:38;15619:12;;;27648:245::o;27900:416::-;28100:2;28114:47;;;15870:1;28085:18;;;39611:19;-1:-1;;;39651:14;;;15885:28;15932:12;;;28071:245::o;28323:416::-;28523:2;28537:47;;;16183:2;28508:18;;;39611:19;-1:-1;;;39651:14;;;16199:34;16252:12;;;28494:245::o;28746:416::-;28946:2;28960:47;;;16503:2;28931:18;;;39611:19;16539:29;39651:14;;;16519:50;16588:12;;;28917:245::o;29169:416::-;29369:2;29383:47;;;16839:2;29354:18;;;39611:19;-1:-1;;;39651:14;;;16855:33;16907:12;;;29340:245::o;29592:416::-;29792:2;29806:47;;;17158:2;29777:18;;;39611:19;-1:-1;;;39651:14;;;17174:35;17228:12;;;29763:245::o;30015:416::-;30215:2;30229:47;;;17479:2;30200:18;;;39611:19;17515:30;39651:14;;;17495:51;17565:12;;;30186:245::o;30438:416::-;30638:2;30652:47;;;17816:2;30623:18;;;39611:19;17852:34;39651:14;;;17832:55;-1:-1;;;17907:12;;;17900:25;17944:12;;;30609:245::o;30861:416::-;31061:2;31075:47;;;18195:1;31046:18;;;39611:19;-1:-1;;;39651:14;;;18210:29;18258:12;;;31032:245::o;31284:416::-;31484:2;31498:47;;;18509:1;31469:18;;;39611:19;-1:-1;;;39651:14;;;18524:30;18573:12;;;31455:245::o;31707:416::-;31907:2;31921:47;;;18824:2;31892:18;;;39611:19;-1:-1;;;39651:14;;;18840:36;18895:12;;;31878:245::o;32130:416::-;32330:2;32344:47;;;19146:2;32315:18;;;39611:19;19182:31;39651:14;;;19162:52;19233:12;;;32301:245::o;32553:416::-;32753:2;32767:47;;;19484:2;32738:18;;;39611:19;-1:-1;;;39651:14;;;19500:34;19553:12;;;32724:245::o;32976:416::-;33176:2;33190:47;;;19804:2;33161:18;;;39611:19;19840:34;39651:14;;;19820:55;-1:-1;;;19895:12;;;19888:34;19941:12;;;33147:245::o;33399:416::-;33599:2;33613:47;;;20192:2;33584:18;;;39611:19;-1:-1;;;39651:14;;;20208:33;20260:12;;;33570:245::o;33822:416::-;34022:2;34036:47;;;20511:2;34007:18;;;39611:19;-1:-1;;;39651:14;;;20527:38;20584:12;;;33993:245::o;34245:416::-;34445:2;34459:47;;;20835:2;34430:18;;;39611:19;20871:34;39651:14;;;20851:55;-1:-1;;;20926:12;;;20919:46;20984:12;;;34416:245::o;34668:222::-;22017:37;;;34795:2;34780:18;;34766:124::o;34897:481::-;;35102:2;35091:9;35087:18;22047:5;22024:3;22017:37;35220:2;35102;35220;35209:9;35205:18;35198:48;35260:108;11200:5;38764:12;39623:6;39618:3;39611:19;39651:14;35091:9;39651:14;11212:93;;35220:2;11376:5;38432:14;11388:21;;-1:-1;11415:260;11440:6;11437:1;11434:13;11415:260;;;11501:13;;-1:-1;;;;;40839:54;10807:37;;39323:14;;;;10295;;;;7158:18;11455:9;11415:260;;;-1:-1;35252:116;;35073:305;-1:-1;;;;;;;35073:305::o;35385:444::-;22017:37;;;35732:2;35717:18;;22017:37;;;;35815:2;35800:18;;22017:37;35568:2;35553:18;;35539:290::o;35836:556::-;22017:37;;;36212:2;36197:18;;22017:37;;;;36295:2;36280:18;;22017:37;36378:2;36363:18;;22017:37;36047:3;36032:19;;36018:374::o;36399:668::-;22017:37;;;36803:2;36788:18;;22017:37;;;;36886:2;36871:18;;22017:37;;;;36969:2;36954:18;;22017:37;37052:3;37037:19;;22017:37;36638:3;36623:19;;36609:458::o;37074:256::-;37136:2;37130:9;37162:17;;;37237:18;37222:34;;37258:22;;;37219:62;37216:2;;;37294:1;;37284:12;37216:2;37136;37303:22;37114:216;;-1:-1;37114:216::o;37337:333::-;;37525:18;37517:6;37514:30;37511:2;;;-1:-1;;37547:12;37511:2;-1:-1;37592:4;37580:17;;;37645:15;;37448:222::o;42526:268::-;42591:1;42598:101;42612:6;42609:1;42606:13;42598:101;;;42679:11;;;42673:18;42660:11;;;42653:39;42634:2;42627:10;42598:101;;;42714:6;42711:1;42708:13;42705:2;;;-1:-1;;42591:1;42761:16;;42754:27;42575:219::o;42907:117::-;-1:-1;;;;;40839:54;;42966:35;;42956:2;;43015:1;;43005:12;43031:111;43112:5;40545:13;40538:21;43090:5;43087:32;43077:2;;43133:1;;43123:12
Swarm Source
ipfs://7a224399c14c11ec8e7f566fabefc939a638034f3ad5dd97286939b9860a8e5f
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.