Overview
MATIC Balance
0 MATIC
MATIC Value
$0.00More Info
Private Name Tags
ContractCreator:
Sponsored
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x6142f261 | 13630636 | 1070 days ago | IN | Create: MassetLogic | 0 MATIC | 0.00375254 |
Loading...
Loading
Contract Name:
MassetLogic
Compiler Version
v0.8.2+commit.661d1103
Contract Source Code (Solidity)
/** *Submitted for verification at polygonscan.com on 2021-06-25 */ pragma solidity 0.8.2; interface IPlatformIntegration { /** * @dev Deposit the given bAsset to Lending platform * @param _bAsset bAsset address * @param _amount Amount to deposit */ function deposit( address _bAsset, uint256 _amount, bool isTokenFeeCharged ) external returns (uint256 quantityDeposited); /** * @dev Withdraw given bAsset from Lending platform */ function withdraw( address _receiver, address _bAsset, uint256 _amount, bool _hasTxFee ) external; /** * @dev Withdraw given bAsset from Lending platform */ function withdraw( address _receiver, address _bAsset, uint256 _amount, uint256 _totalAmount, bool _hasTxFee ) external; /** * @dev Withdraw given bAsset from the cache */ function withdrawRaw( address _receiver, address _bAsset, uint256 _amount ) external; /** * @dev Returns the current balance of the given bAsset */ function checkBalance(address _bAsset) external returns (uint256 balance); /** * @dev Returns the pToken */ function bAssetToPToken(address _bAsset) external returns (address pToken); } struct BassetPersonal { // Address of the bAsset address addr; // Address of the bAsset address integrator; // An ERC20 can charge transfer fee, for example USDT, DGX tokens. bool hasTxFee; // takes a byte in storage // Status of the bAsset BassetStatus status; } struct BassetData { // 1 Basset * ratio / ratioScale == x Masset (relative value) // If ratio == 10e8 then 1 bAsset = 10 mAssets // A ratio is divised as 10^(18-tokenDecimals) * measurementMultiple(relative value of 1 base unit) uint128 ratio; // Amount of the Basset that is held in Collateral uint128 vaultBalance; } // Status of the Basset - has it broken its peg? enum BassetStatus { Default, Normal, BrokenBelowPeg, BrokenAbovePeg, Blacklisted, Liquidating, Liquidated, Failed } struct BasketState { bool undergoingRecol; bool failed; } struct FeederConfig { uint256 supply; uint256 a; WeightLimits limits; } struct InvariantConfig { uint256 supply; uint256 a; WeightLimits limits; uint256 recolFee; } struct BasicConfig { uint256 a; WeightLimits limits; } struct WeightLimits { uint128 min; uint128 max; } struct AmpData { uint64 initialA; uint64 targetA; uint64 rampStartTime; uint64 rampEndTime; } struct FeederData { uint256 swapFee; uint256 redemptionFee; uint256 govFee; uint256 pendingFees; uint256 cacheSize; BassetPersonal[] bAssetPersonal; BassetData[] bAssetData; AmpData ampData; WeightLimits weightLimits; } struct MassetData { uint256 swapFee; uint256 redemptionFee; uint256 cacheSize; uint256 surplus; BassetPersonal[] bAssetPersonal; BassetData[] bAssetData; BasketState basket; AmpData ampData; WeightLimits weightLimits; } struct AssetData { uint8 idx; uint256 amt; BassetPersonal personal; } struct Asset { uint8 idx; address addr; bool exists; } library Root { /** * @dev Returns the square root of a given number * @param x Input * @return y Square root of Input */ function sqrt(uint256 x) internal pure returns (uint256 y) { if (x == 0) return 0; else { uint256 xx = x; uint256 r = 1; if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; } if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; } if (xx >= 0x100000000) { xx >>= 32; r <<= 16; } if (xx >= 0x10000) { xx >>= 16; r <<= 8; } if (xx >= 0x100) { xx >>= 8; r <<= 4; } if (xx >= 0x10) { xx >>= 4; r <<= 2; } if (xx >= 0x8) { r <<= 1; } r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; // Seven iterations should be enough uint256 r1 = x / r; return uint256(r < r1 ? r : r1); } } } 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); } /** * @dev Interface of the ERC20 standard as defined in the EIP. */ /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } library SafeERC20 { using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } library SafeCast { /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { require(value < 2**128, "SafeCast: value doesn\'t fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { require(value < 2**64, "SafeCast: value doesn\'t fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { require(value < 2**32, "SafeCast: value doesn\'t fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { require(value < 2**16, "SafeCast: value doesn\'t fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits. */ function toUint8(uint256 value) internal pure returns (uint8) { require(value < 2**8, "SafeCast: value doesn\'t fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128) { require(value >= -2**127 && value < 2**127, "SafeCast: value doesn\'t fit in 128 bits"); return int128(value); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64) { require(value >= -2**63 && value < 2**63, "SafeCast: value doesn\'t fit in 64 bits"); return int64(value); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32) { require(value >= -2**31 && value < 2**31, "SafeCast: value doesn\'t fit in 32 bits"); return int32(value); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16) { require(value >= -2**15 && value < 2**15, "SafeCast: value doesn\'t fit in 16 bits"); return int16(value); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits. * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8) { require(value >= -2**7 && value < 2**7, "SafeCast: value doesn\'t fit in 8 bits"); return int8(value); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { require(value < 2**255, "SafeCast: value doesn't fit in an int256"); return int256(value); } } library MassetHelpers { using SafeERC20 for IERC20; function transferReturnBalance( address _sender, address _recipient, address _bAsset, uint256 _qty ) internal returns (uint256 receivedQty, uint256 recipientBalance) { uint256 balBefore = IERC20(_bAsset).balanceOf(_recipient); IERC20(_bAsset).safeTransferFrom(_sender, _recipient, _qty); recipientBalance = IERC20(_bAsset).balanceOf(_recipient); receivedQty = recipientBalance - balBefore; } function safeInfiniteApprove(address _asset, address _spender) internal { IERC20(_asset).safeApprove(_spender, 0); IERC20(_asset).safeApprove(_spender, 2**256 - 1); } } library StableMath { /** * @dev Scaling unit for use in specific calculations, * where 1 * 10**18, or 1e18 represents a unit '1' */ uint256 private constant FULL_SCALE = 1e18; /** * @dev Token Ratios are used when converting between units of bAsset, mAsset and MTA * Reasoning: Takes into account token decimals, and difference in base unit (i.e. grams to Troy oz for gold) * bAsset ratio unit for use in exact calculations, * where (1 bAsset unit * bAsset.ratio) / ratioScale == x mAsset unit */ uint256 private constant RATIO_SCALE = 1e8; /** * @dev Provides an interface to the scaling unit * @return Scaling unit (1e18 or 1 * 10**18) */ function getFullScale() internal pure returns (uint256) { return FULL_SCALE; } /** * @dev Provides an interface to the ratio unit * @return Ratio scale unit (1e8 or 1 * 10**8) */ function getRatioScale() internal pure returns (uint256) { return RATIO_SCALE; } /** * @dev Scales a given integer to the power of the full scale. * @param x Simple uint256 to scale * @return Scaled value a to an exact number */ function scaleInteger(uint256 x) internal pure returns (uint256) { return x * FULL_SCALE; } /*************************************** PRECISE ARITHMETIC ****************************************/ /** * @dev Multiplies two precise units, and then truncates by the full scale * @param x Left hand input to multiplication * @param y Right hand input to multiplication * @return Result after multiplying the two inputs and then dividing by the shared * scale unit */ function mulTruncate(uint256 x, uint256 y) internal pure returns (uint256) { return mulTruncateScale(x, y, FULL_SCALE); } /** * @dev Multiplies two precise units, and then truncates by the given scale. For example, * when calculating 90% of 10e18, (10e18 * 9e17) / 1e18 = (9e36) / 1e18 = 9e18 * @param x Left hand input to multiplication * @param y Right hand input to multiplication * @param scale Scale unit * @return Result after multiplying the two inputs and then dividing by the shared * scale unit */ function mulTruncateScale( uint256 x, uint256 y, uint256 scale ) internal pure returns (uint256) { // e.g. assume scale = fullScale // z = 10e18 * 9e17 = 9e36 // return 9e36 / 1e18 = 9e18 return (x * y) / scale; } /** * @dev Multiplies two precise units, and then truncates by the full scale, rounding up the result * @param x Left hand input to multiplication * @param y Right hand input to multiplication * @return Result after multiplying the two inputs and then dividing by the shared * scale unit, rounded up to the closest base unit. */ function mulTruncateCeil(uint256 x, uint256 y) internal pure returns (uint256) { // e.g. 8e17 * 17268172638 = 138145381104e17 uint256 scaled = x * y; // e.g. 138145381104e17 + 9.99...e17 = 138145381113.99...e17 uint256 ceil = scaled + FULL_SCALE - 1; // e.g. 13814538111.399...e18 / 1e18 = 13814538111 return ceil / FULL_SCALE; } /** * @dev Precisely divides two units, by first scaling the left hand operand. Useful * for finding percentage weightings, i.e. 8e18/10e18 = 80% (or 8e17) * @param x Left hand input to division * @param y Right hand input to division * @return Result after multiplying the left operand by the scale, and * executing the division on the right hand input. */ function divPrecisely(uint256 x, uint256 y) internal pure returns (uint256) { // e.g. 8e18 * 1e18 = 8e36 // e.g. 8e36 / 10e18 = 8e17 return (x * FULL_SCALE) / y; } /*************************************** RATIO FUNCS ****************************************/ /** * @dev Multiplies and truncates a token ratio, essentially flooring the result * i.e. How much mAsset is this bAsset worth? * @param x Left hand operand to multiplication (i.e Exact quantity) * @param ratio bAsset ratio * @return c Result after multiplying the two inputs and then dividing by the ratio scale */ function mulRatioTruncate(uint256 x, uint256 ratio) internal pure returns (uint256 c) { return mulTruncateScale(x, ratio, RATIO_SCALE); } /** * @dev Multiplies and truncates a token ratio, rounding up the result * i.e. How much mAsset is this bAsset worth? * @param x Left hand input to multiplication (i.e Exact quantity) * @param ratio bAsset ratio * @return Result after multiplying the two inputs and then dividing by the shared * ratio scale, rounded up to the closest base unit. */ function mulRatioTruncateCeil(uint256 x, uint256 ratio) internal pure returns (uint256) { // e.g. How much mAsset should I burn for this bAsset (x)? // 1e18 * 1e8 = 1e26 uint256 scaled = x * ratio; // 1e26 + 9.99e7 = 100..00.999e8 uint256 ceil = scaled + RATIO_SCALE - 1; // return 100..00.999e8 / 1e8 = 1e18 return ceil / RATIO_SCALE; } /** * @dev Precisely divides two ratioed units, by first scaling the left hand operand * i.e. How much bAsset is this mAsset worth? * @param x Left hand operand in division * @param ratio bAsset ratio * @return c Result after multiplying the left operand by the scale, and * executing the division on the right hand input. */ function divRatioPrecisely(uint256 x, uint256 ratio) internal pure returns (uint256 c) { // e.g. 1e14 * 1e8 = 1e22 // return 1e22 / 1e12 = 1e10 return (x * RATIO_SCALE) / ratio; } /*************************************** HELPERS ****************************************/ /** * @dev Calculates minimum of two numbers * @param x Left hand input * @param y Right hand input * @return Minimum of the two inputs */ function min(uint256 x, uint256 y) internal pure returns (uint256) { return x > y ? y : x; } /** * @dev Calculated maximum of two numbers * @param x Left hand input * @param y Right hand input * @return Maximum of the two inputs */ function max(uint256 x, uint256 y) internal pure returns (uint256) { return x > y ? x : y; } /** * @dev Clamps a value to an upper bound * @param x Left hand input * @param upperBound Maximum possible value to return * @return Input x clamped to a maximum value, upperBound */ function clamp(uint256 x, uint256 upperBound) internal pure returns (uint256) { return x > upperBound ? upperBound : x; } } // SPDX-License-Identifier: AGPL-3.0-or-later // External // Internal // Libs /** * @title MassetLogic * @author mStable * @notice Builds on and enforces the StableSwap invariant conceived by Michael Egorov. (https://www.curve.fi/stableswap-paper.pdf) * Derived by mStable and adapted for the needs of an mAsset, as described in MIP-7 (http://mips.mstable.org/MIPS/mip-7) * Calculates and validates the result of Masset operations with respect to the invariant. * This supports low slippage swaps and applies penalties towards min and max regions. * @dev VERSION: 1.0 * DATE: 2021-04-23 */ library MassetLogic { using StableMath for uint256; using SafeERC20 for IERC20; uint256 internal constant A_PRECISION = 100; /*************************************** MINT ****************************************/ /** * @notice Transfers token in, updates internal balances and computes the mAsset output * @param _data Masset storage state * @param _config Core config for use in the invariant validator * @param _input Data on the bAsset to deposit for the minted mAsset. * @param _inputQuantity Quantity in input token units. * @param _minOutputQuantity Minimum mAsset quantity to be minted. This protects against slippage. * @return mintOutput Quantity of mAsset minted from the deposited bAsset. */ function mint( MassetData storage _data, InvariantConfig calldata _config, Asset calldata _input, uint256 _inputQuantity, uint256 _minOutputQuantity ) external returns (uint256 mintOutput) { BassetData[] memory cachedBassetData = _data.bAssetData; // Transfer collateral to the platform integration address and call deposit uint256 quantityDeposited = _depositTokens( _data.bAssetPersonal[_input.idx], cachedBassetData[_input.idx].ratio, _inputQuantity, _getCacheDetails(_data, _config.supply) ); // Validation should be after token transfer, as bAssetQty is unknown before mintOutput = computeMint(cachedBassetData, _input.idx, quantityDeposited, _config); require(mintOutput >= _minOutputQuantity, "Mint quantity < min qty"); // Log the Vault increase - can only be done when basket is healthy _data.bAssetData[_input.idx].vaultBalance = cachedBassetData[_input.idx].vaultBalance + SafeCast.toUint128(quantityDeposited); } /** * @notice Transfers tokens in, updates internal balances and computes the mAsset output. * Only fAsset & mAsset are supported in this path. * @param _data Masset storage state * @param _config Core config for use in the invariant validator * @param _indices Non-duplicate addresses of the bAssets to deposit for the minted mAsset. * @param _inputQuantities Quantity of each input in input token units. * @param _minOutputQuantity Minimum mAsset quantity to be minted. This protects against slippage. * @return mintOutput Quantity of mAsset minted from the deposited bAsset. */ function mintMulti( MassetData storage _data, InvariantConfig calldata _config, uint8[] calldata _indices, uint256[] calldata _inputQuantities, uint256 _minOutputQuantity ) external returns (uint256 mintOutput) { uint256 len = _indices.length; uint256[] memory quantitiesDeposited = new uint256[](len); BassetData[] memory cachedBassetData = _data.bAssetData; uint256 maxCache = _getCacheDetails(_data, _config.supply); // Transfer the Bassets to the integrator, update storage and calc MassetQ for (uint256 i = 0; i < len; i++) { if (_inputQuantities[i] > 0) { uint8 idx = _indices[i]; BassetData memory bData = cachedBassetData[idx]; quantitiesDeposited[i] = _depositTokens( _data.bAssetPersonal[idx], bData.ratio, _inputQuantities[i], maxCache ); _data.bAssetData[idx].vaultBalance = bData.vaultBalance + SafeCast.toUint128(quantitiesDeposited[i]); } } // Validate the proposed mint, after token transfer mintOutput = computeMintMulti(cachedBassetData, _indices, quantitiesDeposited, _config); require(mintOutput >= _minOutputQuantity, "Mint quantity < min qty"); require(mintOutput > 0, "Zero mAsset quantity"); } /*************************************** SWAP ****************************************/ /** * @notice Swaps two assets - either internally between fAsset<>mAsset, or between fAsset<>mpAsset by * first routing through the mAsset pool. * @param _data Masset storage state * @param _config Core config for use in the invariant validator * @param _input Data on bAsset to deposit * @param _output Data on bAsset to withdraw * @param _inputQuantity Units of input bAsset to swap in * @param _minOutputQuantity Minimum quantity of the swap output asset. This protects against slippage * @param _recipient Address to transfer output asset to * @return swapOutput Quantity of output asset returned from swap * @return scaledFee Fee paid, in mAsset terms */ function swap( MassetData storage _data, InvariantConfig calldata _config, Asset calldata _input, Asset calldata _output, uint256 _inputQuantity, uint256 _minOutputQuantity, address _recipient ) external returns (uint256 swapOutput, uint256 scaledFee) { BassetData[] memory cachedBassetData = _data.bAssetData; // 3. Deposit the input tokens uint256 quantityDeposited = _depositTokens( _data.bAssetPersonal[_input.idx], cachedBassetData[_input.idx].ratio, _inputQuantity, _getCacheDetails(_data, _config.supply) ); // 3.1. Update the input balance _data.bAssetData[_input.idx].vaultBalance = cachedBassetData[_input.idx].vaultBalance + SafeCast.toUint128(quantityDeposited); // 3. Validate the swap (swapOutput, scaledFee) = computeSwap( cachedBassetData, _input.idx, _output.idx, quantityDeposited, _data.swapFee, _config ); require(swapOutput >= _minOutputQuantity, "Output qty < minimum qty"); require(swapOutput > 0, "Zero output quantity"); //4. Settle the swap //4.1. Decrease output bal uint256 maxCache = _getCacheDetails(_data, _config.supply); _withdrawTokens( swapOutput, _data.bAssetPersonal[_output.idx], cachedBassetData[_output.idx], _recipient, maxCache ); _data.bAssetData[_output.idx].vaultBalance = cachedBassetData[_output.idx].vaultBalance - SafeCast.toUint128(swapOutput); // Save new surplus to storage _data.surplus += scaledFee; } /*************************************** REDEEM ****************************************/ /** * @notice Burns a specified quantity of the senders mAsset in return for a bAsset. The output amount is derived * from the invariant. Supports redemption into either the fAsset, mAsset or assets in the mAsset basket. * @param _data Masset storage state * @param _config Core config for use in the invariant validator * @param _output Data on bAsset to withdraw * @param _inputQuantity Quantity of mAsset to burn * @param _minOutputQuantity Minimum bAsset quantity to receive for the burnt mAsset. This protects against slippage. * @param _recipient Address to transfer the withdrawn bAssets to. * @return bAssetQuantity Quanity of bAsset units received for the burnt mAsset * @return scaledFee Fee paid, in mAsset terms */ function redeem( MassetData storage _data, InvariantConfig calldata _config, Asset calldata _output, uint256 _inputQuantity, uint256 _minOutputQuantity, address _recipient ) external returns (uint256 bAssetQuantity, uint256 scaledFee) { // Load the bAsset data from storage into memory BassetData[] memory cachedBassetData = _data.bAssetData; // Calculate redemption quantities (bAssetQuantity, scaledFee) = computeRedeem( cachedBassetData, _output.idx, _inputQuantity, _config, _data.swapFee ); require(bAssetQuantity >= _minOutputQuantity, "bAsset qty < min qty"); require(bAssetQuantity > 0, "Output == 0"); // Apply fees, burn mAsset and return bAsset to recipient _data.surplus += scaledFee; // 2.0. Transfer the Bassets to the recipient uint256 maxCache = _getCacheDetails(_data, _config.supply - _inputQuantity + scaledFee); _withdrawTokens( bAssetQuantity, _data.bAssetPersonal[_output.idx], cachedBassetData[_output.idx], _recipient, maxCache ); // 3.0. Set vault balance _data.bAssetData[_output.idx].vaultBalance = cachedBassetData[_output.idx].vaultBalance - SafeCast.toUint128(bAssetQuantity); } /** * @dev Credits a recipient with a proportionate amount of bAssets, relative to current vault * balance levels and desired mAsset quantity. Burns the mAsset as payment. Only fAsset & mAsset are supported in this path. * @param _data Masset storage state * @param _config Core config for use in the invariant validator * @param _inputQuantity Quantity of mAsset to redeem * @param _minOutputQuantities Min units of output to receive * @param _recipient Address to credit the withdrawn bAssets * @return scaledFee Fee collected in mAsset terms * @return outputs Array of output asset addresses * @return outputQuantities Array of output asset quantities */ function redeemProportionately( MassetData storage _data, InvariantConfig calldata _config, uint256 _inputQuantity, uint256[] calldata _minOutputQuantities, address _recipient ) external returns ( uint256 scaledFee, address[] memory outputs, uint256[] memory outputQuantities ) { // Load the bAsset data from storage into memory BassetData[] memory cachedBassetData = _data.bAssetData; // Calculate mAsset redemption quantities uint256 deductedInput; (deductedInput, scaledFee) = _getDeducted( cachedBassetData, _config, _inputQuantity, _data.redemptionFee ); _data.surplus += scaledFee; // Calc cache and total mAsset circulating uint256 maxCache = _getCacheDetails(_data, _config.supply - _inputQuantity + scaledFee); uint256 len = cachedBassetData.length; outputs = new address[](len); outputQuantities = new uint256[](len); for (uint256 i = 0; i < len; i++) { // Get amount out, proportionate to redemption quantity uint256 amountOut = (cachedBassetData[i].vaultBalance * deductedInput) / _config.supply; require(amountOut > 1, "Output == 0"); amountOut -= 1; require(amountOut >= _minOutputQuantities[i], "bAsset qty < min qty"); // reduce vaultBalance _data.bAssetData[i].vaultBalance = cachedBassetData[i].vaultBalance - SafeCast.toUint128(amountOut); // Set output in array BassetPersonal memory personal = _data.bAssetPersonal[i]; (outputQuantities[i], outputs[i]) = (amountOut, personal.addr); // Transfer the bAsset to the recipient _withdrawTokens(amountOut, personal, cachedBassetData[i], _recipient, maxCache); } } /** @dev Internal func to get the deducted input to avoid stack depth error */ function _getDeducted( BassetData[] memory _bData, InvariantConfig memory _config, uint256 _input, uint256 _redemptionFee ) internal pure returns (uint256 deductedInput, uint256 scaledFee) { deductedInput = _input; // If supply > k, deduct recolFee (uint256 price, ) = computePrice(_bData, _config); if (price < 1e18) { deductedInput -= ((_input * _config.recolFee) / 1e18); } scaledFee = deductedInput.mulTruncate(_redemptionFee); deductedInput -= scaledFee; } /** * @dev Credits a recipient with a certain quantity of selected bAssets, in exchange for burning the * relative mAsset quantity from the sender. Only fAsset & mAsset (0,1) are supported in this path. * @param _data Masset storage state * @param _config Core config for use in the invariant validator * @param _indices Indices of the bAssets to receive * @param _outputQuantities Units of the bAssets to receive * @param _maxMassetQuantity Maximum mAsset quantity to burn for the received bAssets. This protects against slippage. * @param _recipient Address to receive the withdrawn bAssets * @return mAssetQuantity Quantity of mAsset units to burn as payment * @return fee Fee collected, in mAsset terms */ function redeemExactBassets( MassetData storage _data, InvariantConfig memory _config, uint8[] calldata _indices, uint256[] calldata _outputQuantities, uint256 _maxMassetQuantity, address _recipient ) external returns (uint256 mAssetQuantity, uint256 fee) { // Load bAsset data from storage to memory BassetData[] memory cachedBassetData = _data.bAssetData; (mAssetQuantity, fee) = computeRedeemExact( cachedBassetData, _indices, _outputQuantities, _config, _data.swapFee ); require(mAssetQuantity <= _maxMassetQuantity, "Redeem mAsset qty > max quantity"); // Apply fees, burn mAsset and return bAsset to recipient _data.surplus += fee; // Transfer the Bassets to the recipient and count fees uint256 maxCache = _getCacheDetails(_data, _config.supply - mAssetQuantity + fee); for (uint256 i = 0; i < _indices.length; i++) { uint8 idx = _indices[i]; _withdrawTokens( _outputQuantities[i], _data.bAssetPersonal[idx], cachedBassetData[idx], _recipient, maxCache ); _data.bAssetData[idx].vaultBalance = cachedBassetData[idx].vaultBalance - SafeCast.toUint128(_outputQuantities[i]); } } /*************************************** FORGING - INTERNAL ****************************************/ /** * @dev Deposits a given asset to the system. If there is sufficient room for the asset * in the cache, then just transfer, otherwise reset the cache to the desired mid level by * depositing the delta in the platform */ function _depositTokens( BassetPersonal memory _bAsset, uint256 _bAssetRatio, uint256 _quantity, uint256 _maxCache ) internal returns (uint256 quantityDeposited) { // 0. If integration is 0, short circuit if (_bAsset.integrator == address(0)) { (uint256 received, ) = MassetHelpers.transferReturnBalance( msg.sender, address(this), _bAsset.addr, _quantity ); return received; } // 1 - Send all to PI, using the opportunity to get the cache balance and net amount transferred uint256 cacheBal; (quantityDeposited, cacheBal) = MassetHelpers.transferReturnBalance( msg.sender, _bAsset.integrator, _bAsset.addr, _quantity ); // 2 - Deposit X if necessary // 2.1 - Deposit if xfer fees if (_bAsset.hasTxFee) { uint256 deposited = IPlatformIntegration(_bAsset.integrator).deposit( _bAsset.addr, quantityDeposited, true ); return StableMath.min(deposited, quantityDeposited); } // 2.2 - Else Deposit X if Cache > % // This check is in place to ensure that any token with a txFee is rejected require(quantityDeposited == _quantity, "Asset not fully transferred"); uint256 relativeMaxCache = _maxCache.divRatioPrecisely(_bAssetRatio); if (cacheBal > relativeMaxCache) { uint256 delta = cacheBal - (relativeMaxCache / 2); IPlatformIntegration(_bAsset.integrator).deposit(_bAsset.addr, delta, false); } } /** * @dev Withdraws a given asset from its platformIntegration. If there is sufficient liquidity * in the cache, then withdraw from there, otherwise withdraw from the lending market and reset the * cache to the mid level. */ function _withdrawTokens( uint256 _quantity, BassetPersonal memory _personal, BassetData memory _data, address _recipient, uint256 _maxCache ) internal { if (_quantity == 0) return; // 1.0 If there is no integrator, send from here if (_personal.integrator == address(0)) { IERC20(_personal.addr).safeTransfer(_recipient, _quantity); } // 1.1 If txFee then short circuit - there is no cache else if (_personal.hasTxFee) { IPlatformIntegration(_personal.integrator).withdraw( _recipient, _personal.addr, _quantity, _quantity, true ); } // 1.2. Else, withdraw from either cache or main vault else { uint256 cacheBal = IERC20(_personal.addr).balanceOf(_personal.integrator); // 2.1 - If balance b in cache, simply withdraw if (cacheBal >= _quantity) { IPlatformIntegration(_personal.integrator).withdrawRaw( _recipient, _personal.addr, _quantity ); } // 2.2 - Else reset the cache to X, or as far as possible // - Withdraw X+b from platform // - Send b to user else { uint256 relativeMidCache = _maxCache.divRatioPrecisely(_data.ratio) / 2; uint256 totalWithdrawal = StableMath.min( relativeMidCache + _quantity - cacheBal, _data.vaultBalance - SafeCast.toUint128(cacheBal) ); IPlatformIntegration(_personal.integrator).withdraw( _recipient, _personal.addr, _quantity, totalWithdrawal, false ); } } } /** * @dev Gets the max cache size, given the supply of mAsset * @return maxCache Max units of any given bAsset that should be held in the cache */ function _getCacheDetails(MassetData storage _data, uint256 _supply) internal view returns (uint256 maxCache) { maxCache = (_supply * _data.cacheSize) / 1e18; } /*************************************** INVARIANT ****************************************/ /** * @notice Compute the amount of mAsset received for minting * with `quantity` amount of bAsset index `i`. * @param _bAssets Array of all bAsset Data * @param _i Index of bAsset with which to mint * @param _rawInput Raw amount of bAsset to use in mint * @param _config Generalised invariantConfig stored externally * @return mintAmount Quantity of mAssets minted */ function computeMint( BassetData[] memory _bAssets, uint8 _i, uint256 _rawInput, InvariantConfig memory _config ) public view returns (uint256 mintAmount) { // 1. Get raw reserves (uint256[] memory x, uint256 sum) = _getReserves(_bAssets); // 2. Get value of reserves according to invariant uint256 k0 = _invariant(x, sum, _config.a); uint256 scaledInput = (_rawInput * _bAssets[_i].ratio) / 1e8; // 3. Add deposit to x and sum x[_i] += scaledInput; sum += scaledInput; // 4. Finalise mint require(_inBounds(x, sum, _config.limits), "Exceeds weight limits"); mintAmount = _computeMintOutput(x, sum, k0, _config); } /** * @notice Compute the amount of mAsset received for minting * with the given array of inputs. * @param _bAssets Array of all bAsset Data * @param _indices Indexes of bAssets with which to mint * @param _rawInputs Raw amounts of bAssets to use in mint * @param _config Generalised invariantConfig stored externally * @return mintAmount Quantity of mAssets minted */ function computeMintMulti( BassetData[] memory _bAssets, uint8[] memory _indices, uint256[] memory _rawInputs, InvariantConfig memory _config ) public view returns (uint256 mintAmount) { // 1. Get raw reserves (uint256[] memory x, uint256 sum) = _getReserves(_bAssets); // 2. Get value of reserves according to invariant uint256 k0 = _invariant(x, sum, _config.a); // 3. Add deposits to x and sum uint256 len = _indices.length; uint8 idx; uint256 scaledInput; for (uint256 i = 0; i < len; i++) { idx = _indices[i]; scaledInput = (_rawInputs[i] * _bAssets[idx].ratio) / 1e8; x[idx] += scaledInput; sum += scaledInput; } // 4. Finalise mint require(_inBounds(x, sum, _config.limits), "Exceeds weight limits"); mintAmount = _computeMintOutput(x, sum, k0, _config); } /** * @notice Compute the amount of bAsset received for swapping * `quantity` amount of index `input_idx` to index `output_idx`. * @param _bAssets Array of all bAsset Data * @param _i Index of bAsset to swap IN * @param _o Index of bAsset to swap OUT * @param _rawInput Raw amounts of input bAsset to input * @param _feeRate Swap fee rate to apply to output * @param _config Generalised invariantConfig stored externally * @return bAssetOutputQuantity Raw bAsset output quantity * @return scaledSwapFee Swap fee collected, in mAsset terms */ function computeSwap( BassetData[] memory _bAssets, uint8 _i, uint8 _o, uint256 _rawInput, uint256 _feeRate, InvariantConfig memory _config ) public view returns (uint256 bAssetOutputQuantity, uint256 scaledSwapFee) { // 1. Get raw reserves (uint256[] memory x, uint256 sum) = _getReserves(_bAssets); // 2. Get value of reserves according to invariant uint256 k0 = _invariant(x, sum, _config.a); // 3. Add deposits to x and sum uint256 scaledInput = (_rawInput * _bAssets[_i].ratio) / 1e8; x[_i] += scaledInput; sum += scaledInput; // 4. Calc total mAsset q uint256 k2; (k2, scaledSwapFee) = _getSwapFee(k0, _invariant(x, sum, _config.a), _feeRate, _config); // 5. Calc output bAsset uint256 newOutputReserve = _solveInvariant(x, _config.a, _o, k2); require(newOutputReserve < x[_o], "Zero swap output"); uint256 output = x[_o] - newOutputReserve - 1; bAssetOutputQuantity = (output * 1e8) / _bAssets[_o].ratio; // 6. Check for bounds x[_o] -= output; sum -= output; require(_inBounds(x, sum, _config.limits), "Exceeds weight limits"); } /** @dev Gets swap fee and scales to avoid stack depth errors in computeSwap */ function _getSwapFee( uint256 _k0, uint256 _k1, uint256 _feeRate, InvariantConfig memory _config ) internal pure returns (uint256 k2, uint256 scaledSwapFee) { uint256 minted = _k1 - _k0; // Under col? Deduct fee if (_config.supply > _k0) { minted -= ((minted * _config.recolFee) / 1e18); } // base swap fee scaledSwapFee = (minted * _feeRate) / 1e18; k2 = _k1 - minted + scaledSwapFee; // swap fee in lpToken terms scaledSwapFee = (scaledSwapFee * _config.supply) / _k0; } /** * @notice Compute the amount of bAsset index `i` received for * redeeming `quantity` amount of mAsset. * @param _bAssets Array of all bAsset Data * @param _o Index of output bAsset * @param _grossMassetQuantity Net amount of mAsset to redeem * @param _config Generalised invariantConfig stored externally * @return rawOutputUnits Raw bAsset output returned */ function computeRedeem( BassetData[] memory _bAssets, uint8 _o, uint256 _grossMassetQuantity, InvariantConfig memory _config, uint256 _feeRate ) public view returns (uint256 rawOutputUnits, uint256 scaledFee) { // 1. Get raw reserves (uint256[] memory x, uint256 sum) = _getReserves(_bAssets); // 2. Get value of reserves according to invariant uint256 k0 = _invariant(x, sum, _config.a); uint256 redemption; (redemption, scaledFee) = _getFee(_grossMassetQuantity, _config, _feeRate, k0); uint256 kFinal = (k0 * (_config.supply - redemption)) / _config.supply + 1; // 3. Compute bAsset output uint256 newOutputReserve = _solveInvariant(x, _config.a, _o, kFinal); uint256 output = x[_o] - newOutputReserve - 1; rawOutputUnits = (output * 1e8) / _bAssets[_o].ratio; // 4. Check for max weight x[_o] -= output; sum -= output; require(_inBounds(x, sum, _config.limits), "Exceeds weight limits"); } function _getFee( uint256 _grossMassetQuantity, InvariantConfig memory _config, uint256 _feeRate, uint256 _k0 ) internal pure returns (uint256 redemption, uint256 scaledFee) { redemption = _grossMassetQuantity; if (_config.supply > _k0) { redemption -= ((redemption * _config.recolFee) / 1e18); } scaledFee = redemption.mulTruncate(_feeRate); redemption -= scaledFee; } /** * @notice Compute the amount of mAsset required to redeem * a given selection of bAssets. * @param _bAssets Array of all bAsset Data * @param _indices Indexes of output bAssets * @param _rawOutputs Desired raw bAsset outputs * @param _config Generalised invariantConfig stored externally * @return grossMasset Amount of mAsset required to redeem bAssets * @return fee Fee to subtract from gross */ function computeRedeemExact( BassetData[] memory _bAssets, uint8[] memory _indices, uint256[] memory _rawOutputs, InvariantConfig memory _config, uint256 _feeRate ) public view returns (uint256 grossMasset, uint256 fee) { // 1. Get raw reserves (uint256[] memory x, uint256 sum) = _getReserves(_bAssets); // 2. Get value of reserves according to invariant uint256 k0 = _invariant(x, sum, _config.a); // 3. Sub deposits from x and sum uint256 len = _indices.length; uint256 ratioed; for (uint256 i = 0; i < len; i++) { ratioed = (_rawOutputs[i] * _bAssets[_indices[i]].ratio) / 1e8; x[_indices[i]] -= ratioed; sum -= ratioed; } require(_inBounds(x, sum, _config.limits), "Exceeds weight limits"); // 4. Get new value of reserves according to invariant uint256 k1 = _invariant(x, sum, _config.a); // 5. Total mAsset is the difference between values uint256 redeemed = (_config.supply * (k0 - k1)) / k0; require(redeemed > 1e6, "Must redeem > 1e6 units"); grossMasset = redeemed.divPrecisely(1e18 - _feeRate); fee = grossMasset - redeemed; grossMasset += 1; if (_config.supply > k0) { grossMasset = ((grossMasset * 1e18) / (1e18 - _config.recolFee)); } } /** * @notice Gets the price of the mAsset, and invariant value k * @param _bAssets Array of all bAsset Data * @param _config Generalised InvariantConfig stored externally * @return price Price of an mAsset * @return k Total value of basket, k */ function computePrice(BassetData[] memory _bAssets, InvariantConfig memory _config) public pure returns (uint256 price, uint256 k) { (uint256[] memory x, uint256 sum) = _getReserves(_bAssets); k = _invariant(x, sum, _config.a); price = (1e18 * k) / _config.supply; } /*************************************** INTERNAL ****************************************/ /** * @dev Computes the actual mint output after adding mint inputs * to the vault balances. * @param _x Scaled vaultBalances * @param _sum Sum of vaultBalances, to avoid another loop * @param _k Previous value of invariant, k, before addition * @param _config Generalised InvariantConfig stored externally * @return mintAmount Amount of value added to invariant, in mAsset terms */ function _computeMintOutput( uint256[] memory _x, uint256 _sum, uint256 _k, InvariantConfig memory _config ) internal pure returns (uint256 mintAmount) { // 1. Get value of reserves according to invariant uint256 kFinal = _invariant(_x, _sum, _config.a); // 2. Total minted is the difference between values, with respect to total supply if (_config.supply == 0) { mintAmount = kFinal - _k; } else { mintAmount = (_config.supply * (kFinal - _k)) / _k; } // 3. Deviation? deduct recolFee of 0.5 bps if (_config.supply > _k) { mintAmount -= ((mintAmount * _config.recolFee) / 1e18); } } /** * @dev Simply scaled raw reserve values and returns the sum * @param _bAssets All bAssets * @return x Scaled vault balances * @return sum Sum of scaled vault balances */ function _getReserves(BassetData[] memory _bAssets) internal pure returns (uint256[] memory x, uint256 sum) { uint256 len = _bAssets.length; x = new uint256[](len); uint256 r; for (uint256 i = 0; i < len; i++) { BassetData memory bAsset = _bAssets[i]; r = (bAsset.vaultBalance * bAsset.ratio) / 1e8; x[i] = r; sum += r; } } /** * @dev Checks that no bAsset reserves exceed max weight * @param _x Scaled bAsset reserves * @param _sum Sum of x, precomputed * @param _limits Config object containing max and min weights * @return inBounds Bool, true if all assets are within bounds */ function _inBounds( uint256[] memory _x, uint256 _sum, WeightLimits memory _limits ) internal pure returns (bool inBounds) { uint256 len = _x.length; inBounds = true; uint256 w; for (uint256 i = 0; i < len; i++) { w = (_x[i] * 1e18) / _sum; if (w > _limits.max || w < _limits.min) return false; } } /*************************************** INVARIANT ****************************************/ /** * @dev Compute the invariant f(x) for a given array of supplies `x`. * @param _x Scaled vault balances * @param _sum Sum of scaled vault balances * @param _a Precise amplification coefficient * @return k Cumulative value of all assets according to the invariant */ function _invariant( uint256[] memory _x, uint256 _sum, uint256 _a ) internal pure returns (uint256 k) { uint256 len = _x.length; if (_sum == 0) return 0; uint256 nA = _a * len; uint256 kPrev; k = _sum; for (uint256 i = 0; i < 256; i++) { uint256 kP = k; for (uint256 j = 0; j < len; j++) { kP = (kP * k) / (_x[j] * len); } kPrev = k; k = (((nA * _sum) / A_PRECISION + (kP * len)) * k) / (((nA - A_PRECISION) * k) / A_PRECISION + ((len + 1) * kP)); if (_hasConverged(k, kPrev)) { return k; } } revert("Invariant did not converge"); } /** * @dev Checks if a given solution has converged within a factor of 1 * @param _k Current solution k * @param _kPrev Previous iteration solution * @return hasConverged Bool, true if diff abs(k, kPrev) <= 1 */ function _hasConverged(uint256 _k, uint256 _kPrev) internal pure returns (bool) { if (_kPrev > _k) { return (_kPrev - _k) <= 1; } else { return (_k - _kPrev) <= 1; } } /** * @dev Solves the invariant for _i with respect to target K, given an array of reserves. * @param _x Scaled reserve balances * @param _a Precise amplification coefficient * @param _idx Index of asset for which to solve * @param _targetK Target invariant value K * @return y New reserve of _i */ function _solveInvariant( uint256[] memory _x, uint256 _a, uint8 _idx, uint256 _targetK ) internal pure returns (uint256 y) { uint256 len = _x.length; require(_idx >= 0 && _idx < len, "Invalid index"); (uint256 sum_, uint256 nA, uint256 kP) = (0, _a * len, _targetK); for (uint256 i = 0; i < len; i++) { if (i != _idx) { sum_ += _x[i]; kP = (kP * _targetK) / (_x[i] * len); } } uint256 c = (((kP * _targetK) * A_PRECISION) / nA) / len; uint256 g = (_targetK * (nA - A_PRECISION)) / nA; uint256 b = 0; if (g > sum_) { b = g - sum_; y = (Root.sqrt((b**2) + (4 * c)) + b) / 2 + 1; } else { b = sum_ - g; y = (Root.sqrt((b**2) + (4 * c)) - b) / 2 + 1; } if (y < 1e8) revert("Invalid solution"); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"components":[{"internalType":"uint128","name":"ratio","type":"uint128"},{"internalType":"uint128","name":"vaultBalance","type":"uint128"}],"internalType":"struct BassetData[]","name":"_bAssets","type":"tuple[]"},{"internalType":"uint8","name":"_i","type":"uint8"},{"internalType":"uint256","name":"_rawInput","type":"uint256"},{"components":[{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"a","type":"uint256"},{"components":[{"internalType":"uint128","name":"min","type":"uint128"},{"internalType":"uint128","name":"max","type":"uint128"}],"internalType":"struct WeightLimits","name":"limits","type":"tuple"},{"internalType":"uint256","name":"recolFee","type":"uint256"}],"internalType":"struct InvariantConfig","name":"_config","type":"tuple"}],"name":"computeMint","outputs":[{"internalType":"uint256","name":"mintAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint128","name":"ratio","type":"uint128"},{"internalType":"uint128","name":"vaultBalance","type":"uint128"}],"internalType":"struct BassetData[]","name":"_bAssets","type":"tuple[]"},{"internalType":"uint8[]","name":"_indices","type":"uint8[]"},{"internalType":"uint256[]","name":"_rawInputs","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"a","type":"uint256"},{"components":[{"internalType":"uint128","name":"min","type":"uint128"},{"internalType":"uint128","name":"max","type":"uint128"}],"internalType":"struct WeightLimits","name":"limits","type":"tuple"},{"internalType":"uint256","name":"recolFee","type":"uint256"}],"internalType":"struct InvariantConfig","name":"_config","type":"tuple"}],"name":"computeMintMulti","outputs":[{"internalType":"uint256","name":"mintAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint128","name":"ratio","type":"uint128"},{"internalType":"uint128","name":"vaultBalance","type":"uint128"}],"internalType":"struct BassetData[]","name":"_bAssets","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"a","type":"uint256"},{"components":[{"internalType":"uint128","name":"min","type":"uint128"},{"internalType":"uint128","name":"max","type":"uint128"}],"internalType":"struct WeightLimits","name":"limits","type":"tuple"},{"internalType":"uint256","name":"recolFee","type":"uint256"}],"internalType":"struct InvariantConfig","name":"_config","type":"tuple"}],"name":"computePrice","outputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"k","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint128","name":"ratio","type":"uint128"},{"internalType":"uint128","name":"vaultBalance","type":"uint128"}],"internalType":"struct BassetData[]","name":"_bAssets","type":"tuple[]"},{"internalType":"uint8","name":"_o","type":"uint8"},{"internalType":"uint256","name":"_grossMassetQuantity","type":"uint256"},{"components":[{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"a","type":"uint256"},{"components":[{"internalType":"uint128","name":"min","type":"uint128"},{"internalType":"uint128","name":"max","type":"uint128"}],"internalType":"struct WeightLimits","name":"limits","type":"tuple"},{"internalType":"uint256","name":"recolFee","type":"uint256"}],"internalType":"struct InvariantConfig","name":"_config","type":"tuple"},{"internalType":"uint256","name":"_feeRate","type":"uint256"}],"name":"computeRedeem","outputs":[{"internalType":"uint256","name":"rawOutputUnits","type":"uint256"},{"internalType":"uint256","name":"scaledFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint128","name":"ratio","type":"uint128"},{"internalType":"uint128","name":"vaultBalance","type":"uint128"}],"internalType":"struct BassetData[]","name":"_bAssets","type":"tuple[]"},{"internalType":"uint8[]","name":"_indices","type":"uint8[]"},{"internalType":"uint256[]","name":"_rawOutputs","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"a","type":"uint256"},{"components":[{"internalType":"uint128","name":"min","type":"uint128"},{"internalType":"uint128","name":"max","type":"uint128"}],"internalType":"struct WeightLimits","name":"limits","type":"tuple"},{"internalType":"uint256","name":"recolFee","type":"uint256"}],"internalType":"struct InvariantConfig","name":"_config","type":"tuple"},{"internalType":"uint256","name":"_feeRate","type":"uint256"}],"name":"computeRedeemExact","outputs":[{"internalType":"uint256","name":"grossMasset","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint128","name":"ratio","type":"uint128"},{"internalType":"uint128","name":"vaultBalance","type":"uint128"}],"internalType":"struct BassetData[]","name":"_bAssets","type":"tuple[]"},{"internalType":"uint8","name":"_i","type":"uint8"},{"internalType":"uint8","name":"_o","type":"uint8"},{"internalType":"uint256","name":"_rawInput","type":"uint256"},{"internalType":"uint256","name":"_feeRate","type":"uint256"},{"components":[{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"a","type":"uint256"},{"components":[{"internalType":"uint128","name":"min","type":"uint128"},{"internalType":"uint128","name":"max","type":"uint128"}],"internalType":"struct WeightLimits","name":"limits","type":"tuple"},{"internalType":"uint256","name":"recolFee","type":"uint256"}],"internalType":"struct InvariantConfig","name":"_config","type":"tuple"}],"name":"computeSwap","outputs":[{"internalType":"uint256","name":"bAssetOutputQuantity","type":"uint256"},{"internalType":"uint256","name":"scaledSwapFee","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6142f261003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100be5760003560e01c8063b3ffbf311161007b578063b3ffbf3114610191578063b995a2b5146101a4578063bf9f08b2146101b7578063ccf4ddcc146101ca578063d38e18e9146101ea578063ee679672146101fd576100be565b806307aa92c8146100c35780630ce8bc9b146100fd5780632c51918f1461011e57806361ec51541461013e5780637c1449941461015e5780638c420a9714610171575b600080fd5b8180156100cf57600080fd5b506100e36100de366004613de8565b61022c565b604080519283526020830191909152015b60405180910390f35b61011061010b366004613a54565b610601565b6040519081526020016100f4565b81801561012a57600080fd5b506100e3610139366004613c5b565b610707565b81801561014a57600080fd5b506100e3610159366004613d25565b610c20565b6100e361016c366004613ab0565b610f45565b81801561017d57600080fd5b5061011061018c366004613cd3565b6110e0565b6100e361019f366004613969565b6113a4565b6100e36101b2366004613b0e565b61163a565b6101106101c53660046138d3565b6118bf565b8180156101d657600080fd5b506101106101e5366004613bc9565b611a39565b6100e36101f8366004613a08565b611e80565b81801561020957600080fd5b5061021d610218366004613d7d565b611ece565b6040516100f493929190613f3b565b60008060008a600501805480602002602001604051908101604052809291908181526020016000905b8282101561029e57600084815260209081902060408051808201909152908401546001600160801b038082168352600160801b9091041681830152825260019092019101610255565b505050509050610326818a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c918291850190849080828437600081840152601f19601f820116905080830192505050505050508d8f600001546113a4565b9093509150848311156103805760405162461bcd60e51b815260206004820181905260248201527f52656465656d206d417373657420717479203e206d6178207175616e7469747960448201526064015b60405180910390fd5b818b60030160008282546103949190614046565b9250508190555060006103c18c84868e600001516103b2919061421c565b6103bc9190614046565b612382565b905060005b898110156105f15760008b8b838181106103f057634e487b7160e01b600052603260045260246000fd5b90506020020160208101906104059190613ea3565b905061052a8a8a8481811061042a57634e487b7160e01b600052603260045260246000fd5b905060200201358f6004018360ff168154811061045757634e487b7160e01b600052603260045260246000fd5b600091825260209182902060408051608081018252600290930290910180546001600160a01b03908116845260018201549081169484019490945260ff600160a01b8504811615159284019290925291926060840191600160a81b9091041660078111156104d557634e487b7160e01b600052602160045260246000fd5b60078111156104f457634e487b7160e01b600052602160045260246000fd5b81525050868460ff168151811061051b57634e487b7160e01b600052603260045260246000fd5b60200260200101518a876123ae565b6105598a8a8481811061054d57634e487b7160e01b600052603260045260246000fd5b9050602002013561266c565b848260ff168151811061057c57634e487b7160e01b600052603260045260246000fd5b60200260200101516020015161059291906141f4565b8e6005018260ff16815481106105b857634e487b7160e01b600052603260045260246000fd5b600091825260209091200180546001600160801b03928316600160801b02921691909117905550806105e98161425f565b9150506103c6565b5050509850989650505050505050565b600080600061060f876126d9565b915091506000610624838387602001516127ed565b905060006305f5e100898960ff168151811061065057634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160801b03168861067091906141d5565b61067a9190614084565b905080848960ff16815181106106a057634e487b7160e01b600052603260045260246000fd5b602002602001018181516106b49190614046565b9052506106c18184614046565b92506106d284848860400151612983565b6106ee5760405162461bcd60e51b815260040161037790613f0c565b6106fa84848489612a2d565b9998505050505050505050565b600080600089600501805480602002602001604051908101604052809291908181526020016000905b8282101561077957600084815260209081902060408051808201909152908401546001600160801b038082168352600160801b9091041681830152825260019092019101610730565b50929350600092506108b191505060048c0161079860208c018c613ea3565b60ff16815481106107b957634e487b7160e01b600052603260045260246000fd5b600091825260209182902060408051608081018252600290930290910180546001600160a01b03908116845260018201549081169484019490945260ff600160a01b8504811615159284019290925291926060840191600160a81b90910416600781111561083757634e487b7160e01b600052602160045260246000fd5b600781111561085657634e487b7160e01b600052602160045260246000fd5b9052508361086760208d018d613ea3565b60ff168151811061088857634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160801b0316896108ac8f8f60000135612382565b612abf565b90506108bc8161266c565b826108ca60208c018c613ea3565b60ff16815181106108eb57634e487b7160e01b600052603260045260246000fd5b602002602001015160200151610901919061401b565b60058c0161091260208c018c613ea3565b60ff168154811061093357634e487b7160e01b600052603260045260246000fd5b60009182526020918290200180546001600160801b03938416600160801b0293169290921790915561099190839061096d908c018c613ea3565b61097a60208c018c613ea3565b848f600001548f8036038101906101b29190613bae565b9094509250858410156109e65760405162461bcd60e51b815260206004820152601860248201527f4f757470757420717479203c206d696e696d756d2071747900000000000000006044820152606401610377565b60008411610a2d5760405162461bcd60e51b81526020600482015260146024820152735a65726f206f7574707574207175616e7469747960601b6044820152606401610377565b6000610a3a8c8c35612382565b9050610b508560048e01610a5160208d018d613ea3565b60ff1681548110610a7257634e487b7160e01b600052603260045260246000fd5b600091825260209182902060408051608081018252600290930290910180546001600160a01b03908116845260018201549081169484019490945260ff600160a01b8504811615159284019290925291926060840191600160a81b909104166007811115610af057634e487b7160e01b600052602160045260246000fd5b6007811115610b0f57634e487b7160e01b600052602160045260246000fd5b90525085610b2060208e018e613ea3565b60ff1681518110610b4157634e487b7160e01b600052603260045260246000fd5b602002602001015189856123ae565b610b598561266c565b83610b6760208c018c613ea3565b60ff1681518110610b8857634e487b7160e01b600052603260045260246000fd5b602002602001015160200151610b9e91906141f4565b60058d01610baf60208c018c613ea3565b60ff1681548110610bd057634e487b7160e01b600052603260045260246000fd5b6000918252602082200180546001600160801b03938416600160801b0293169290921790915560038d018054869290610c0a908490614046565b9250508190555050505097509795505050505050565b600080600088600501805480602002602001604051908101604052809291908181526020016000905b82821015610c9257600084815260209081902060408051808201909152908401546001600160801b038082168352600160801b9091041681830152825260019092019101610c49565b50929350610cc49250839150610cad905060208a018a613ea3565b88610cbd368d90038d018d613bae565b8d54610f45565b909350915084831015610d105760405162461bcd60e51b815260206004820152601460248201527362417373657420717479203c206d696e2071747960601b6044820152606401610377565b60008311610d4e5760405162461bcd60e51b815260206004820152600b60248201526a04f7574707574203d3d20360ac1b6044820152606401610377565b81896003016000828254610d629190614046565b9091555060009050610d7a8a846103b28a8d3561421c565b9050610e908460048c01610d9160208c018c613ea3565b60ff1681548110610db257634e487b7160e01b600052603260045260246000fd5b600091825260209182902060408051608081018252600290930290910180546001600160a01b03908116845260018201549081169484019490945260ff600160a01b8504811615159284019290925291926060840191600160a81b909104166007811115610e3057634e487b7160e01b600052602160045260246000fd5b6007811115610e4f57634e487b7160e01b600052602160045260246000fd5b90525084610e6060208d018d613ea3565b60ff1681518110610e8157634e487b7160e01b600052603260045260246000fd5b602002602001015188856123ae565b610e998461266c565b82610ea760208b018b613ea3565b60ff1681518110610ec857634e487b7160e01b600052603260045260246000fd5b602002602001015160200151610ede91906141f4565b60058b01610eef60208b018b613ea3565b60ff1681548110610f1057634e487b7160e01b600052603260045260246000fd5b600091825260209091200180546001600160801b03928316600160801b02921691909117905550919890975095505050505050565b600080600080610f54896126d9565b915091506000610f69838389602001516127ed565b90506000610f7989898985612cdb565b8951909650909150600090610f8e838261421c565b610f9890856141d5565b610fa29190614084565b610fad906001614046565b90506000610fc1868b602001518e85612d3a565b90506000600182888f60ff1681518110610feb57634e487b7160e01b600052603260045260246000fd5b6020026020010151610ffd919061421c565b611007919061421c565b90508d8d60ff168151811061102c57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160801b0316816305f5e10061105191906141d5565b61105b9190614084565b985080878e60ff168151811061108157634e487b7160e01b600052603260045260246000fd5b60200260200101818151611095919061421c565b9052506110a2818761421c565b95506110b387878d60400151612983565b6110cf5760405162461bcd60e51b815260040161037790613f0c565b505050505050509550959350505050565b60008086600501805480602002602001604051908101604052809291908181526020016000905b8282101561115057600084815260209081902060408051808201909152908401546001600160801b038082168352600160801b9091041681830152825260019092019101611107565b50929350600092506112839150506004890161116f6020890189613ea3565b60ff168154811061119057634e487b7160e01b600052603260045260246000fd5b600091825260209182902060408051608081018252600290930290910180546001600160a01b03908116845260018201549081169484019490945260ff600160a01b8504811615159284019290925291926060840191600160a81b90910416600781111561120e57634e487b7160e01b600052602160045260246000fd5b600781111561122d57634e487b7160e01b600052602160045260246000fd5b9052508361123e60208a018a613ea3565b60ff168151811061125f57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160801b0316876108ac8c8c60000135612382565b90506112a6826112966020890189613ea3565b8361010b368c90038c018c613bae565b9250838310156112f25760405162461bcd60e51b81526020600482015260176024820152764d696e74207175616e74697479203c206d696e2071747960481b6044820152606401610377565b6112fb8161266c565b826113096020890189613ea3565b60ff168151811061132a57634e487b7160e01b600052603260045260246000fd5b602002602001015160200151611340919061401b565b600589016113516020890189613ea3565b60ff168154811061137257634e487b7160e01b600052603260045260246000fd5b600091825260209091200180546001600160801b03928316600160801b02921691909117905550909695505050505050565b6000806000806113b3896126d9565b9150915060006113c8838389602001516127ed565b89519091506000805b828110156114fb576305f5e1008d8d83815181106113ff57634e487b7160e01b600052603260045260246000fd5b602002602001015160ff168151811061142857634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160801b03168c838151811061145d57634e487b7160e01b600052603260045260246000fd5b602002602001015161146f91906141d5565b6114799190614084565b915081868d838151811061149d57634e487b7160e01b600052603260045260246000fd5b602002602001015160ff16815181106114c657634e487b7160e01b600052603260045260246000fd5b602002602001018181516114da919061421c565b9052506114e7828661421c565b9450806114f38161425f565b9150506113d1565b5061150b85858b60400151612983565b6115275760405162461bcd60e51b815260040161037790613f0c565b600061153886868c602001516127ed565b9050600084611547838261421c565b8c5161155391906141d5565b61155d9190614084565b9050620f424081116115b15760405162461bcd60e51b815260206004820152601760248201527f4d7573742072656465656d203e2031653620756e6974730000000000000000006044820152606401610377565b6115cd6115c68b670de0b6b3a764000061421c565b8290612f8e565b98506115d9818a61421c565b97506115e660018a614046565b9850848b6000015111156110cf5760608b015161160b90670de0b6b3a764000061421c565b61161d8a670de0b6b3a76400006141d5565b6116279190614084565b9850505050505050509550959350505050565b6000806000806116498a6126d9565b91509150600061165e838388602001516127ed565b905060006305f5e1008c8c60ff168151811061168a57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160801b03168a6116aa91906141d5565b6116b49190614084565b905080848c60ff16815181106116da57634e487b7160e01b600052603260045260246000fd5b602002602001018181516116ee9190614046565b9052506116fb8184614046565b925060006117198361171287878c602001516127ed565b8b8b612fa9565b80975081925050506000611733868a602001518e85612d3a565b9050858c60ff168151811061175857634e487b7160e01b600052603260045260246000fd5b602002602001015181106117a15760405162461bcd60e51b815260206004820152601060248201526f16995c9bc81cddd85c081bdd5d1c1d5d60821b6044820152606401610377565b6000600182888f60ff16815181106117c957634e487b7160e01b600052603260045260246000fd5b60200260200101516117db919061421c565b6117e5919061421c565b90508e8d60ff168151811061180a57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160801b0316816305f5e10061182f91906141d5565b6118399190614084565b985080878e60ff168151811061185f57634e487b7160e01b600052603260045260246000fd5b60200260200101818151611873919061421c565b905250611880818761421c565b955061189187878c60400151612983565b6118ad5760405162461bcd60e51b815260040161037790613f0c565b50505050505050965096945050505050565b60008060006118cd876126d9565b9150915060006118e2838387602001516127ed565b8751909150600080805b838110156119f2578a818151811061191457634e487b7160e01b600052603260045260246000fd5b602002602001015192506305f5e1008c8460ff168151811061194657634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160801b03168b838151811061197b57634e487b7160e01b600052603260045260246000fd5b602002602001015161198d91906141d5565b6119979190614084565b915081878460ff16815181106119bd57634e487b7160e01b600052603260045260246000fd5b602002602001018181516119d19190614046565b9052506119de8287614046565b9550806119ea8161425f565b9150506118ec565b50611a0286868a60400151612983565b611a1e5760405162461bcd60e51b815260040161037790613f0c565b611a2a8686868b612a2d565b9b9a5050505050505050505050565b60008481816001600160401b03811115611a6357634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611a8c578160200160208202803683370190505b50905060008a600501805480602002602001604051908101604052809291908181526020016000905b82821015611afe57600084815260209081902060408051808201909152908401546001600160801b038082168352600160801b9091041681830152825260019092019101611ab5565b5050505090506000611b148c8c60000135612382565b905060005b84811015611d85576000898983818110611b4357634e487b7160e01b600052603260045260246000fd5b905060200201351115611d735760008b8b83818110611b7257634e487b7160e01b600052603260045260246000fd5b9050602002016020810190611b879190613ea3565b90506000848260ff1681518110611bae57634e487b7160e01b600052603260045260246000fd5b60200260200101519050611cb98f6004018360ff1681548110611be157634e487b7160e01b600052603260045260246000fd5b600091825260209182902060408051608081018252600290930290910180546001600160a01b03908116845260018201549081169484019490945260ff600160a01b8504811615159284019290925291926060840191600160a81b909104166007811115611c5f57634e487b7160e01b600052602160045260246000fd5b6007811115611c7e57634e487b7160e01b600052602160045260246000fd5b90525082516001600160801b03168d8d87818110611cac57634e487b7160e01b600052603260045260246000fd5b9050602002013587612abf565b868481518110611cd957634e487b7160e01b600052603260045260246000fd5b602002602001018181525050611d15868481518110611d0857634e487b7160e01b600052603260045260246000fd5b602002602001015161266c565b8160200151611d24919061401b565b8f6005018360ff1681548110611d4a57634e487b7160e01b600052603260045260246000fd5b600091825260209091200180546001600160801b03928316600160801b02921691909117905550505b80611d7d8161425f565b915050611b19565b50611dde828b8b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050858e8036038101906101c59190613bae565b945085851015611e2a5760405162461bcd60e51b81526020600482015260176024820152764d696e74207175616e74697479203c206d696e2071747960481b6044820152606401610377565b60008511611e715760405162461bcd60e51b81526020600482015260146024820152735a65726f206d4173736574207175616e7469747960601b6044820152606401610377565b50505050979650505050505050565b600080600080611e8f866126d9565b91509150611ea2828287602001516127ed565b8551909350611eb984670de0b6b3a76400006141d5565b611ec39190614084565b935050509250929050565b6000606080600089600501805480602002602001604051908101604052809291908181526020016000905b82821015611f4257600084815260209081902060408051808201909152908401546001600160801b038082168352600160801b9091041681830152825260019092019101611ef9565b5050505090506000611f6a828b803603810190611f5f9190613bae565b8b8e60010154613050565b8096508192505050848b6003016000828254611f869190614046565b9091555060009050611f9e8c876103b28d8f3561421c565b8351909150806001600160401b03811115611fc957634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611ff2578160200160208202803683370190505b509550806001600160401b0381111561201b57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612044578160200160208202803683370190505b50945060005b818110156123715760008d600001358587848151811061207a57634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160801b031661209991906141d5565b6120a39190614084565b9050600181116120e35760405162461bcd60e51b815260206004820152600b60248201526a04f7574707574203d3d20360ac1b6044820152606401610377565b6120ee60018261421c565b90508b8b8381811061211057634e487b7160e01b600052603260045260246000fd5b9050602002013581101561215d5760405162461bcd60e51b815260206004820152601460248201527362417373657420717479203c206d696e2071747960601b6044820152606401610377565b6121668161266c565b86838151811061218657634e487b7160e01b600052603260045260246000fd5b60200260200101516020015161219c91906141f4565b8f60050183815481106121bf57634e487b7160e01b600052603260045260246000fd5b9060005260206000200160000160106101000a8154816001600160801b0302191690836001600160801b0316021790555060008f600401838154811061221557634e487b7160e01b600052603260045260246000fd5b600091825260209182902060408051608081018252600290930290910180546001600160a01b03908116845260018201549081169484019490945260ff600160a01b8504811615159284019290925291926060840191600160a81b90910416600781111561229357634e487b7160e01b600052602160045260246000fd5b60078111156122b257634e487b7160e01b600052602160045260246000fd5b8152505090508181600001518985815181106122de57634e487b7160e01b600052603260045260246000fd5b602002602001018b868151811061230557634e487b7160e01b600052603260045260246000fd5b60200260200101826001600160a01b03166001600160a01b031681525082815250505061235c828289868151811061234d57634e487b7160e01b600052603260045260246000fd5b60200260200101518e896123ae565b505080806123699061425f565b91505061204a565b505050505096509650969350505050565b6000670de0b6b3a764000083600201548361239d91906141d5565b6123a79190614084565b9392505050565b846123b857612665565b60208401516001600160a01b03166123e55783516123e0906001600160a01b031683876130c3565b612665565b836040015115612473576020840151845160405163c89fc72f60e01b81526001600160a01b038581166004830152918216602482015260448101889052606481018890526001608482015291169063c89fc72f9060a401600060405180830381600087803b15801561245657600080fd5b505af115801561246a573d6000803e3d6000fd5b50505050612665565b835160208501516040516370a0823160e01b81526001600160a01b03918216600482015260009291909116906370a082319060240160206040518083038186803b1580156124c057600080fd5b505afa1580156124d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f89190613e8b565b9050858110612577576020850151855160405163a4e2859560e01b81526001600160a01b03868116600483015291821660248201526044810189905291169063a4e2859590606401600060405180830381600087803b15801561255a57600080fd5b505af115801561256e573d6000803e3d6000fd5b50505050612663565b83516000906002906125939085906001600160801b031661312b565b61259d9190614084565b905060006125df836125af8a85614046565b6125b9919061421c565b6125c28561266c565b88602001516125d191906141f4565b6001600160801b031661313c565b6020880151885160405163c89fc72f60e01b81526001600160a01b0389811660048301529182166024820152604481018c90526064810184905260006084820152929350169063c89fc72f9060a401600060405180830381600087803b15801561264857600080fd5b505af115801561265c573d6000803e3d6000fd5b5050505050505b505b5050505050565b6000600160801b82106126d15760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b6064820152608401610377565b50805b919050565b8051606090600090806001600160401b0381111561270757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612730578160200160208202803683370190505b5092506000805b828110156127e557600086828151811061276157634e487b7160e01b600052603260045260246000fd5b602002602001015190506305f5e1008160000151826020015161278491906141af565b61278e919061405e565b6001600160801b03169250828683815181106127ba57634e487b7160e01b600052603260045260246000fd5b60209081029190910101526127cf8386614046565b94505080806127dd9061425f565b915050612737565b505050915091565b8251600090836128015760009150506123a7565b600061280d82856141d5565b9050600085935060005b61010081101561293a578460005b8581101561288857858a828151811061284e57634e487b7160e01b600052603260045260246000fd5b602002602001015161286091906141d5565b61286a88846141d5565b6128749190614084565b9150806128808161425f565b915050612825565b5085925080612898866001614046565b6128a291906141d5565b6064876128af828861421c565b6128b991906141d5565b6128c39190614084565b6128cd9190614046565b866128d887846141d5565b60646128e48c896141d5565b6128ee9190614084565b6128f89190614046565b61290291906141d5565b61290c9190614084565b95506129188684613151565b156129275750505050506123a7565b50806129328161425f565b915050612817565b5060405162461bcd60e51b815260206004820152601a60248201527f496e76617269616e7420646964206e6f7420636f6e76657267650000000000006044820152606401610377565b82516001906000805b82811015612a2357858782815181106129b557634e487b7160e01b600052603260045260246000fd5b6020026020010151670de0b6b3a76400006129d091906141d5565b6129da9190614084565b915084602001516001600160801b0316821180612a00575084516001600160801b031682105b15612a1157600093505050506123a7565b80612a1b8161425f565b91505061298c565b5050509392505050565b600080612a3f868685602001516127ed565b8351909150612a5957612a52848261421c565b9150612a7d565b83612a64818361421c565b8451612a7091906141d5565b612a7a9190614084565b91505b8251841015612ab657670de0b6b3a7640000836060015183612a9f91906141d5565b612aa99190614084565b612ab3908361421c565b91505b50949350505050565b60208401516000906001600160a01b0316612af0576000612ae6333088600001518761317c565b509150612cd39050565b6000612b0633876020015188600001518761317c565b6040880151919350915015612bbf57602086015186516040516307dba22560e31b81526001600160a01b03918216600482015260248101859052600160448201526000929190911690633edd112890606401602060405180830381600087803b158015612b7257600080fd5b505af1158015612b86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612baa9190613e8b565b9050612bb6818461313c565b92505050612cd3565b838214612c0e5760405162461bcd60e51b815260206004820152601b60248201527f4173736574206e6f742066756c6c79207472616e7366657272656400000000006044820152606401610377565b6000612c1a848761312b565b905080821115612cd0576000612c31600283614084565b612c3b908461421c565b602089015189516040516307dba22560e31b81526001600160a01b03918216600482015260248101849052600060448201529293501690633edd112890606401602060405180830381600087803b158015612c9557600080fd5b505af1158015612ca9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ccd9190613e8b565b50505b50505b949350505050565b82518490600090831015612d1957670de0b6b3a7640000856060015183612d0291906141d5565b612d0c9190614084565b612d16908361421c565b91505b612d238285613299565b9050612d2f818361421c565b915094509492505050565b8351600090808460ff1610612d815760405162461bcd60e51b815260206004820152600d60248201526c092dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610377565b6000808080612d90858a6141d5565b8792509250925060005b84811015612e3d578760ff168114612e2b57898181518110612dcc57634e487b7160e01b600052603260045260246000fd5b602002602001015184612ddf9190614046565b9350848a8281518110612e0257634e487b7160e01b600052603260045260246000fd5b6020026020010151612e1491906141d5565b612e1e88846141d5565b612e289190614084565b91505b80612e358161425f565b915050612d9a565b50600084836064612e4e8a866141d5565b612e5891906141d5565b612e629190614084565b612e6c9190614084565b9050600083612e7c60648261421c565b612e86908a6141d5565b612e909190614084565b9050600085821115612ef957612ea6868361421c565b9050600281612ed3612eb98660046141d5565b612ec46002866140de565b612ece9190614046565b6132ae565b612edd9190614046565b612ee79190614084565b612ef2906001614046565b9750612f38565b612f03828761421c565b9050600281612f16612eb98660046141d5565b612f20919061421c565b612f2a9190614084565b612f35906001614046565b97505b6305f5e100881015612f7f5760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b21039b7b63aba34b7b760811b6044820152606401610377565b50505050505050949350505050565b60008161239d670de0b6b3a7640000856141d5565b92915050565b60008080612fb7878761421c565b90508684600001511115612ff557670de0b6b3a7640000846060015182612fde91906141d5565b612fe89190614084565b612ff2908261421c565b90505b670de0b6b3a764000061300886836141d5565b6130129190614084565b91508161301f828861421c565b6130299190614046565b8451909350879061303a90846141d5565b6130449190614084565b91505094509492505050565b8160008061305e8787611e80565b509050670de0b6b3a76400008110156130a157670de0b6b3a764000086606001518661308a91906141d5565b6130949190614084565b61309e908461421c565b92505b6130ab8385613299565b91506130b7828461421c565b92505094509492505050565b6040516001600160a01b03831660248201526044810182905261312690849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261342d565b505050565b60008161239d6305f5e100856141d5565b600081831161314b57826123a7565b50919050565b600082821115613170576001613167848461421c565b11159050612fa3565b6001613167838561421c565b6040516370a0823160e01b81526001600160a01b03848116600483015260009182918291908616906370a082319060240160206040518083038186803b1580156131c557600080fd5b505afa1580156131d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131fd9190613e8b565b90506132146001600160a01b0386168888876134ff565b6040516370a0823160e01b81526001600160a01b0387811660048301528616906370a082319060240160206040518083038186803b15801561325557600080fd5b505afa158015613269573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061328d9190613e8b565b91506130b7818361421c565b60006123a78383670de0b6b3a764000061353d565b6000816132bd575060006126d4565b816001600160801b82106132d65760809190911c9060401b5b6801000000000000000082106132f15760409190911c9060201b5b64010000000082106133085760209190911c9060101b5b62010000821061331d5760109190911c9060081b5b61010082106133315760089190911c9060041b5b601082106133445760049190911c9060021b5b600882106133505760011b5b600161335c8286614084565b6133669083614046565b901c905060016133768286614084565b6133809083614046565b901c905060016133908286614084565b61339a9083614046565b901c905060016133aa8286614084565b6133b49083614046565b901c905060016133c48286614084565b6133ce9083614046565b901c905060016133de8286614084565b6133e89083614046565b901c905060016133f88286614084565b6134029083614046565b901c905060006134128286614084565b90508082106134215780613423565b815b93505050506126d4565b6000613482826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166135549092919063ffffffff16565b80519091501561312657808060200190518101906134a09190613b8e565b6131265760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610377565b6040516001600160a01b03808516602483015283166044820152606481018290526135379085906323b872dd60e01b906084016130ef565b50505050565b60008161354a84866141d5565b612cd39190614084565b6060612cd3848460008585843b6135ad5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610377565b600080866001600160a01b031685876040516135c99190613ebd565b60006040518083038185875af1925050503d8060008114613606576040519150601f19603f3d011682016040523d82523d6000602084013e61360b565b606091505b509150915061361b828286613626565b979650505050505050565b606083156136355750816123a7565b8251156136455782518084602001fd5b8160405162461bcd60e51b81526004016103779190613ed9565b80356001600160a01b03811681146126d457600080fd5b600082601f830112613686578081fd5b8135602061369b61369683613ff8565b613fc8565b828152818101908583016040808602880185018910156136b9578687fd5b865b868110156136df576136cd8a8461380e565b855293850193918101916001016136bb565b509198975050505050505050565b60008083601f8401126136fe578182fd5b5081356001600160401b03811115613714578182fd5b602083019150836020808302850101111561372e57600080fd5b9250929050565b600082601f830112613745578081fd5b8135602061375561369683613ff8565b8281528181019085830183850287018401881015613771578586fd5b855b8581101561378f57813584529284019290840190600101613773565b5090979650505050505050565b600082601f8301126137ac578081fd5b813560206137bc61369683613ff8565b82815281810190858301838502870184018810156137d8578586fd5b855b8581101561378f576137eb826138c2565b845292840192908401906001016137da565b60006060828403121561314b578081fd5b60006040828403121561381f578081fd5b6138296040613fc8565b9050613834826138ab565b8152613842602083016138ab565b602082015292915050565b600060a0828403121561314b578081fd5b600060a0828403121561386f578081fd5b6138796080613fc8565b90508135815260208201356020820152613896836040840161380e565b60408201526080820135606082015292915050565b80356001600160801b03811681146126d457600080fd5b803560ff811681146126d457600080fd5b60008060008061010085870312156138e9578384fd5b84356001600160401b03808211156138ff578586fd5b61390b88838901613676565b95506020870135915080821115613920578485fd5b61392c8883890161379c565b94506040870135915080821115613941578384fd5b5061394e87828801613735565b92505061395e866060870161385e565b905092959194509250565b60008060008060006101208688031215613981578081fd5b85356001600160401b0380821115613997578283fd5b6139a389838a01613676565b965060208801359150808211156139b8578283fd5b6139c489838a0161379c565b955060408801359150808211156139d9578283fd5b506139e688828901613735565b9350506139f6876060880161385e565b94979396509194610100013592915050565b60008060c08385031215613a1a578182fd5b82356001600160401b03811115613a2f578283fd5b613a3b85828601613676565b925050613a4b846020850161385e565b90509250929050565b6000806000806101008587031215613a6a578182fd5b84356001600160401b03811115613a7f578283fd5b613a8b87828801613676565b945050613a9a602086016138c2565b92506040850135915061395e866060870161385e565b60008060008060006101208688031215613ac8578283fd5b85356001600160401b03811115613add578384fd5b613ae988828901613676565b955050613af8602087016138c2565b9350604086013592506139f6876060880161385e565b6000806000806000806101408789031215613b27578384fd5b86356001600160401b03811115613b3c578485fd5b613b4889828a01613676565b965050613b57602088016138c2565b9450613b65604088016138c2565b93506060870135925060808701359150613b828860a0890161385e565b90509295509295509295565b600060208284031215613b9f578081fd5b815180151581146123a7578182fd5b600060a08284031215613bbf578081fd5b6123a7838361385e565b6000806000806000806000610120888a031215613be4578485fd5b87359650613bf58960208a0161384d565b955060c08801356001600160401b0380821115613c10578687fd5b613c1c8b838c016136ed565b909750955060e08a0135915080821115613c34578283fd5b50613c418a828b016136ed565b989b979a5095989497959661010090950135949350505050565b60008060008060008060006101e0888a031215613c76578081fd5b87359650613c878960208a0161384d565b9550613c968960c08a016137fd565b9450613ca6896101208a016137fd565b935061018088013592506101a08801359150613cc56101c0890161365f565b905092959891949750929550565b60008060008060006101608688031215613ceb578283fd5b85359450613cfc876020880161384d565b9350613d0b8760c088016137fd565b949793965093946101208101359450610140013592915050565b6000806000806000806101808789031215613d3e578384fd5b86359550613d4f886020890161384d565b9450613d5e8860c089016137fd565b935061012087013592506101408701359150613b82610160880161365f565b6000806000806000806101208789031215613d96578384fd5b86359550613da7886020890161384d565b945060c0870135935060e08701356001600160401b03811115613dc8578283fd5b613dd489828a016136ed565b9094509250613b829050610100880161365f565b600080600080600080600080610140898b031215613e04578182fd5b88359750613e158a60208b0161385e565b965060c08901356001600160401b0380821115613e30578384fd5b613e3c8c838d016136ed565b909850965060e08b0135915080821115613e54578384fd5b50613e618b828c016136ed565b9095509350506101008901359150613e7c6101208a0161365f565b90509295985092959890939650565b600060208284031215613e9c578081fd5b5051919050565b600060208284031215613eb4578081fd5b6123a7826138c2565b60008251613ecf818460208701614233565b9190910192915050565b6000602082528251806020840152613ef8816040850160208701614233565b601f01601f19169190910160400192915050565b6020808252601590820152744578636565647320776569676874206c696d69747360581b604082015260600190565b60006060820185835260206060818501528186518084526080860191508288019350845b81811015613f845784516001600160a01b031683529383019391830191600101613f5f565b505084810360408601528551808252908201925081860190845b81811015613fba57825185529383019391830191600101613f9e565b509298975050505050505050565b604051601f8201601f191681016001600160401b0381118282101715613ff057613ff06142a6565b604052919050565b60006001600160401b03821115614011576140116142a6565b5060209081020190565b60006001600160801b0380831681851680830382111561403d5761403d61427a565b01949350505050565b600082198211156140595761405961427a565b500190565b60006001600160801b038084168061407857614078614290565b92169190910492915050565b60008261409357614093614290565b500490565b80825b60018086116140aa57506140d5565b8187048211156140bc576140bc61427a565b808616156140c957918102915b9490941c93800261409b565b94509492505050565b60006123a760001960ff8516846000826140fa575060016123a7565b81614107575060006123a7565b816001811461411d576002811461412757614154565b60019150506123a7565b60ff8411156141385761413861427a565b6001841b91508482111561414e5761414e61427a565b506123a7565b5060208310610133831016604e8410600b8410161715614187575081810a838111156141825761418261427a565b6123a7565b6141948484846001614098565b8086048211156141a6576141a661427a565b02949350505050565b60006001600160801b03808316818516818304811182151516156141a6576141a661427a565b60008160001904831182151516156141ef576141ef61427a565b500290565b60006001600160801b03838116908316818110156142145761421461427a565b039392505050565b60008282101561422e5761422e61427a565b500390565b60005b8381101561424e578181015183820152602001614236565b838111156135375750506000910152565b60006000198214156142735761427361427a565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea2646970667358221220f78cb1fc5e5f9d3d51d2ceab0af6d29268e939f879fbfcba8b52c10ff7bbad2364736f6c63430008020033
Deployed Bytecode
0x73b9cca2b53e8d7bc4cbddccb66d20b411b87d213f30146080604052600436106100be5760003560e01c8063b3ffbf311161007b578063b3ffbf3114610191578063b995a2b5146101a4578063bf9f08b2146101b7578063ccf4ddcc146101ca578063d38e18e9146101ea578063ee679672146101fd576100be565b806307aa92c8146100c35780630ce8bc9b146100fd5780632c51918f1461011e57806361ec51541461013e5780637c1449941461015e5780638c420a9714610171575b600080fd5b8180156100cf57600080fd5b506100e36100de366004613de8565b61022c565b604080519283526020830191909152015b60405180910390f35b61011061010b366004613a54565b610601565b6040519081526020016100f4565b81801561012a57600080fd5b506100e3610139366004613c5b565b610707565b81801561014a57600080fd5b506100e3610159366004613d25565b610c20565b6100e361016c366004613ab0565b610f45565b81801561017d57600080fd5b5061011061018c366004613cd3565b6110e0565b6100e361019f366004613969565b6113a4565b6100e36101b2366004613b0e565b61163a565b6101106101c53660046138d3565b6118bf565b8180156101d657600080fd5b506101106101e5366004613bc9565b611a39565b6100e36101f8366004613a08565b611e80565b81801561020957600080fd5b5061021d610218366004613d7d565b611ece565b6040516100f493929190613f3b565b60008060008a600501805480602002602001604051908101604052809291908181526020016000905b8282101561029e57600084815260209081902060408051808201909152908401546001600160801b038082168352600160801b9091041681830152825260019092019101610255565b505050509050610326818a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c918291850190849080828437600081840152601f19601f820116905080830192505050505050508d8f600001546113a4565b9093509150848311156103805760405162461bcd60e51b815260206004820181905260248201527f52656465656d206d417373657420717479203e206d6178207175616e7469747960448201526064015b60405180910390fd5b818b60030160008282546103949190614046565b9250508190555060006103c18c84868e600001516103b2919061421c565b6103bc9190614046565b612382565b905060005b898110156105f15760008b8b838181106103f057634e487b7160e01b600052603260045260246000fd5b90506020020160208101906104059190613ea3565b905061052a8a8a8481811061042a57634e487b7160e01b600052603260045260246000fd5b905060200201358f6004018360ff168154811061045757634e487b7160e01b600052603260045260246000fd5b600091825260209182902060408051608081018252600290930290910180546001600160a01b03908116845260018201549081169484019490945260ff600160a01b8504811615159284019290925291926060840191600160a81b9091041660078111156104d557634e487b7160e01b600052602160045260246000fd5b60078111156104f457634e487b7160e01b600052602160045260246000fd5b81525050868460ff168151811061051b57634e487b7160e01b600052603260045260246000fd5b60200260200101518a876123ae565b6105598a8a8481811061054d57634e487b7160e01b600052603260045260246000fd5b9050602002013561266c565b848260ff168151811061057c57634e487b7160e01b600052603260045260246000fd5b60200260200101516020015161059291906141f4565b8e6005018260ff16815481106105b857634e487b7160e01b600052603260045260246000fd5b600091825260209091200180546001600160801b03928316600160801b02921691909117905550806105e98161425f565b9150506103c6565b5050509850989650505050505050565b600080600061060f876126d9565b915091506000610624838387602001516127ed565b905060006305f5e100898960ff168151811061065057634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160801b03168861067091906141d5565b61067a9190614084565b905080848960ff16815181106106a057634e487b7160e01b600052603260045260246000fd5b602002602001018181516106b49190614046565b9052506106c18184614046565b92506106d284848860400151612983565b6106ee5760405162461bcd60e51b815260040161037790613f0c565b6106fa84848489612a2d565b9998505050505050505050565b600080600089600501805480602002602001604051908101604052809291908181526020016000905b8282101561077957600084815260209081902060408051808201909152908401546001600160801b038082168352600160801b9091041681830152825260019092019101610730565b50929350600092506108b191505060048c0161079860208c018c613ea3565b60ff16815481106107b957634e487b7160e01b600052603260045260246000fd5b600091825260209182902060408051608081018252600290930290910180546001600160a01b03908116845260018201549081169484019490945260ff600160a01b8504811615159284019290925291926060840191600160a81b90910416600781111561083757634e487b7160e01b600052602160045260246000fd5b600781111561085657634e487b7160e01b600052602160045260246000fd5b9052508361086760208d018d613ea3565b60ff168151811061088857634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160801b0316896108ac8f8f60000135612382565b612abf565b90506108bc8161266c565b826108ca60208c018c613ea3565b60ff16815181106108eb57634e487b7160e01b600052603260045260246000fd5b602002602001015160200151610901919061401b565b60058c0161091260208c018c613ea3565b60ff168154811061093357634e487b7160e01b600052603260045260246000fd5b60009182526020918290200180546001600160801b03938416600160801b0293169290921790915561099190839061096d908c018c613ea3565b61097a60208c018c613ea3565b848f600001548f8036038101906101b29190613bae565b9094509250858410156109e65760405162461bcd60e51b815260206004820152601860248201527f4f757470757420717479203c206d696e696d756d2071747900000000000000006044820152606401610377565b60008411610a2d5760405162461bcd60e51b81526020600482015260146024820152735a65726f206f7574707574207175616e7469747960601b6044820152606401610377565b6000610a3a8c8c35612382565b9050610b508560048e01610a5160208d018d613ea3565b60ff1681548110610a7257634e487b7160e01b600052603260045260246000fd5b600091825260209182902060408051608081018252600290930290910180546001600160a01b03908116845260018201549081169484019490945260ff600160a01b8504811615159284019290925291926060840191600160a81b909104166007811115610af057634e487b7160e01b600052602160045260246000fd5b6007811115610b0f57634e487b7160e01b600052602160045260246000fd5b90525085610b2060208e018e613ea3565b60ff1681518110610b4157634e487b7160e01b600052603260045260246000fd5b602002602001015189856123ae565b610b598561266c565b83610b6760208c018c613ea3565b60ff1681518110610b8857634e487b7160e01b600052603260045260246000fd5b602002602001015160200151610b9e91906141f4565b60058d01610baf60208c018c613ea3565b60ff1681548110610bd057634e487b7160e01b600052603260045260246000fd5b6000918252602082200180546001600160801b03938416600160801b0293169290921790915560038d018054869290610c0a908490614046565b9250508190555050505097509795505050505050565b600080600088600501805480602002602001604051908101604052809291908181526020016000905b82821015610c9257600084815260209081902060408051808201909152908401546001600160801b038082168352600160801b9091041681830152825260019092019101610c49565b50929350610cc49250839150610cad905060208a018a613ea3565b88610cbd368d90038d018d613bae565b8d54610f45565b909350915084831015610d105760405162461bcd60e51b815260206004820152601460248201527362417373657420717479203c206d696e2071747960601b6044820152606401610377565b60008311610d4e5760405162461bcd60e51b815260206004820152600b60248201526a04f7574707574203d3d20360ac1b6044820152606401610377565b81896003016000828254610d629190614046565b9091555060009050610d7a8a846103b28a8d3561421c565b9050610e908460048c01610d9160208c018c613ea3565b60ff1681548110610db257634e487b7160e01b600052603260045260246000fd5b600091825260209182902060408051608081018252600290930290910180546001600160a01b03908116845260018201549081169484019490945260ff600160a01b8504811615159284019290925291926060840191600160a81b909104166007811115610e3057634e487b7160e01b600052602160045260246000fd5b6007811115610e4f57634e487b7160e01b600052602160045260246000fd5b90525084610e6060208d018d613ea3565b60ff1681518110610e8157634e487b7160e01b600052603260045260246000fd5b602002602001015188856123ae565b610e998461266c565b82610ea760208b018b613ea3565b60ff1681518110610ec857634e487b7160e01b600052603260045260246000fd5b602002602001015160200151610ede91906141f4565b60058b01610eef60208b018b613ea3565b60ff1681548110610f1057634e487b7160e01b600052603260045260246000fd5b600091825260209091200180546001600160801b03928316600160801b02921691909117905550919890975095505050505050565b600080600080610f54896126d9565b915091506000610f69838389602001516127ed565b90506000610f7989898985612cdb565b8951909650909150600090610f8e838261421c565b610f9890856141d5565b610fa29190614084565b610fad906001614046565b90506000610fc1868b602001518e85612d3a565b90506000600182888f60ff1681518110610feb57634e487b7160e01b600052603260045260246000fd5b6020026020010151610ffd919061421c565b611007919061421c565b90508d8d60ff168151811061102c57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160801b0316816305f5e10061105191906141d5565b61105b9190614084565b985080878e60ff168151811061108157634e487b7160e01b600052603260045260246000fd5b60200260200101818151611095919061421c565b9052506110a2818761421c565b95506110b387878d60400151612983565b6110cf5760405162461bcd60e51b815260040161037790613f0c565b505050505050509550959350505050565b60008086600501805480602002602001604051908101604052809291908181526020016000905b8282101561115057600084815260209081902060408051808201909152908401546001600160801b038082168352600160801b9091041681830152825260019092019101611107565b50929350600092506112839150506004890161116f6020890189613ea3565b60ff168154811061119057634e487b7160e01b600052603260045260246000fd5b600091825260209182902060408051608081018252600290930290910180546001600160a01b03908116845260018201549081169484019490945260ff600160a01b8504811615159284019290925291926060840191600160a81b90910416600781111561120e57634e487b7160e01b600052602160045260246000fd5b600781111561122d57634e487b7160e01b600052602160045260246000fd5b9052508361123e60208a018a613ea3565b60ff168151811061125f57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160801b0316876108ac8c8c60000135612382565b90506112a6826112966020890189613ea3565b8361010b368c90038c018c613bae565b9250838310156112f25760405162461bcd60e51b81526020600482015260176024820152764d696e74207175616e74697479203c206d696e2071747960481b6044820152606401610377565b6112fb8161266c565b826113096020890189613ea3565b60ff168151811061132a57634e487b7160e01b600052603260045260246000fd5b602002602001015160200151611340919061401b565b600589016113516020890189613ea3565b60ff168154811061137257634e487b7160e01b600052603260045260246000fd5b600091825260209091200180546001600160801b03928316600160801b02921691909117905550909695505050505050565b6000806000806113b3896126d9565b9150915060006113c8838389602001516127ed565b89519091506000805b828110156114fb576305f5e1008d8d83815181106113ff57634e487b7160e01b600052603260045260246000fd5b602002602001015160ff168151811061142857634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160801b03168c838151811061145d57634e487b7160e01b600052603260045260246000fd5b602002602001015161146f91906141d5565b6114799190614084565b915081868d838151811061149d57634e487b7160e01b600052603260045260246000fd5b602002602001015160ff16815181106114c657634e487b7160e01b600052603260045260246000fd5b602002602001018181516114da919061421c565b9052506114e7828661421c565b9450806114f38161425f565b9150506113d1565b5061150b85858b60400151612983565b6115275760405162461bcd60e51b815260040161037790613f0c565b600061153886868c602001516127ed565b9050600084611547838261421c565b8c5161155391906141d5565b61155d9190614084565b9050620f424081116115b15760405162461bcd60e51b815260206004820152601760248201527f4d7573742072656465656d203e2031653620756e6974730000000000000000006044820152606401610377565b6115cd6115c68b670de0b6b3a764000061421c565b8290612f8e565b98506115d9818a61421c565b97506115e660018a614046565b9850848b6000015111156110cf5760608b015161160b90670de0b6b3a764000061421c565b61161d8a670de0b6b3a76400006141d5565b6116279190614084565b9850505050505050509550959350505050565b6000806000806116498a6126d9565b91509150600061165e838388602001516127ed565b905060006305f5e1008c8c60ff168151811061168a57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160801b03168a6116aa91906141d5565b6116b49190614084565b905080848c60ff16815181106116da57634e487b7160e01b600052603260045260246000fd5b602002602001018181516116ee9190614046565b9052506116fb8184614046565b925060006117198361171287878c602001516127ed565b8b8b612fa9565b80975081925050506000611733868a602001518e85612d3a565b9050858c60ff168151811061175857634e487b7160e01b600052603260045260246000fd5b602002602001015181106117a15760405162461bcd60e51b815260206004820152601060248201526f16995c9bc81cddd85c081bdd5d1c1d5d60821b6044820152606401610377565b6000600182888f60ff16815181106117c957634e487b7160e01b600052603260045260246000fd5b60200260200101516117db919061421c565b6117e5919061421c565b90508e8d60ff168151811061180a57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160801b0316816305f5e10061182f91906141d5565b6118399190614084565b985080878e60ff168151811061185f57634e487b7160e01b600052603260045260246000fd5b60200260200101818151611873919061421c565b905250611880818761421c565b955061189187878c60400151612983565b6118ad5760405162461bcd60e51b815260040161037790613f0c565b50505050505050965096945050505050565b60008060006118cd876126d9565b9150915060006118e2838387602001516127ed565b8751909150600080805b838110156119f2578a818151811061191457634e487b7160e01b600052603260045260246000fd5b602002602001015192506305f5e1008c8460ff168151811061194657634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160801b03168b838151811061197b57634e487b7160e01b600052603260045260246000fd5b602002602001015161198d91906141d5565b6119979190614084565b915081878460ff16815181106119bd57634e487b7160e01b600052603260045260246000fd5b602002602001018181516119d19190614046565b9052506119de8287614046565b9550806119ea8161425f565b9150506118ec565b50611a0286868a60400151612983565b611a1e5760405162461bcd60e51b815260040161037790613f0c565b611a2a8686868b612a2d565b9b9a5050505050505050505050565b60008481816001600160401b03811115611a6357634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611a8c578160200160208202803683370190505b50905060008a600501805480602002602001604051908101604052809291908181526020016000905b82821015611afe57600084815260209081902060408051808201909152908401546001600160801b038082168352600160801b9091041681830152825260019092019101611ab5565b5050505090506000611b148c8c60000135612382565b905060005b84811015611d85576000898983818110611b4357634e487b7160e01b600052603260045260246000fd5b905060200201351115611d735760008b8b83818110611b7257634e487b7160e01b600052603260045260246000fd5b9050602002016020810190611b879190613ea3565b90506000848260ff1681518110611bae57634e487b7160e01b600052603260045260246000fd5b60200260200101519050611cb98f6004018360ff1681548110611be157634e487b7160e01b600052603260045260246000fd5b600091825260209182902060408051608081018252600290930290910180546001600160a01b03908116845260018201549081169484019490945260ff600160a01b8504811615159284019290925291926060840191600160a81b909104166007811115611c5f57634e487b7160e01b600052602160045260246000fd5b6007811115611c7e57634e487b7160e01b600052602160045260246000fd5b90525082516001600160801b03168d8d87818110611cac57634e487b7160e01b600052603260045260246000fd5b9050602002013587612abf565b868481518110611cd957634e487b7160e01b600052603260045260246000fd5b602002602001018181525050611d15868481518110611d0857634e487b7160e01b600052603260045260246000fd5b602002602001015161266c565b8160200151611d24919061401b565b8f6005018360ff1681548110611d4a57634e487b7160e01b600052603260045260246000fd5b600091825260209091200180546001600160801b03928316600160801b02921691909117905550505b80611d7d8161425f565b915050611b19565b50611dde828b8b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050858e8036038101906101c59190613bae565b945085851015611e2a5760405162461bcd60e51b81526020600482015260176024820152764d696e74207175616e74697479203c206d696e2071747960481b6044820152606401610377565b60008511611e715760405162461bcd60e51b81526020600482015260146024820152735a65726f206d4173736574207175616e7469747960601b6044820152606401610377565b50505050979650505050505050565b600080600080611e8f866126d9565b91509150611ea2828287602001516127ed565b8551909350611eb984670de0b6b3a76400006141d5565b611ec39190614084565b935050509250929050565b6000606080600089600501805480602002602001604051908101604052809291908181526020016000905b82821015611f4257600084815260209081902060408051808201909152908401546001600160801b038082168352600160801b9091041681830152825260019092019101611ef9565b5050505090506000611f6a828b803603810190611f5f9190613bae565b8b8e60010154613050565b8096508192505050848b6003016000828254611f869190614046565b9091555060009050611f9e8c876103b28d8f3561421c565b8351909150806001600160401b03811115611fc957634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611ff2578160200160208202803683370190505b509550806001600160401b0381111561201b57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612044578160200160208202803683370190505b50945060005b818110156123715760008d600001358587848151811061207a57634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160801b031661209991906141d5565b6120a39190614084565b9050600181116120e35760405162461bcd60e51b815260206004820152600b60248201526a04f7574707574203d3d20360ac1b6044820152606401610377565b6120ee60018261421c565b90508b8b8381811061211057634e487b7160e01b600052603260045260246000fd5b9050602002013581101561215d5760405162461bcd60e51b815260206004820152601460248201527362417373657420717479203c206d696e2071747960601b6044820152606401610377565b6121668161266c565b86838151811061218657634e487b7160e01b600052603260045260246000fd5b60200260200101516020015161219c91906141f4565b8f60050183815481106121bf57634e487b7160e01b600052603260045260246000fd5b9060005260206000200160000160106101000a8154816001600160801b0302191690836001600160801b0316021790555060008f600401838154811061221557634e487b7160e01b600052603260045260246000fd5b600091825260209182902060408051608081018252600290930290910180546001600160a01b03908116845260018201549081169484019490945260ff600160a01b8504811615159284019290925291926060840191600160a81b90910416600781111561229357634e487b7160e01b600052602160045260246000fd5b60078111156122b257634e487b7160e01b600052602160045260246000fd5b8152505090508181600001518985815181106122de57634e487b7160e01b600052603260045260246000fd5b602002602001018b868151811061230557634e487b7160e01b600052603260045260246000fd5b60200260200101826001600160a01b03166001600160a01b031681525082815250505061235c828289868151811061234d57634e487b7160e01b600052603260045260246000fd5b60200260200101518e896123ae565b505080806123699061425f565b91505061204a565b505050505096509650969350505050565b6000670de0b6b3a764000083600201548361239d91906141d5565b6123a79190614084565b9392505050565b846123b857612665565b60208401516001600160a01b03166123e55783516123e0906001600160a01b031683876130c3565b612665565b836040015115612473576020840151845160405163c89fc72f60e01b81526001600160a01b038581166004830152918216602482015260448101889052606481018890526001608482015291169063c89fc72f9060a401600060405180830381600087803b15801561245657600080fd5b505af115801561246a573d6000803e3d6000fd5b50505050612665565b835160208501516040516370a0823160e01b81526001600160a01b03918216600482015260009291909116906370a082319060240160206040518083038186803b1580156124c057600080fd5b505afa1580156124d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f89190613e8b565b9050858110612577576020850151855160405163a4e2859560e01b81526001600160a01b03868116600483015291821660248201526044810189905291169063a4e2859590606401600060405180830381600087803b15801561255a57600080fd5b505af115801561256e573d6000803e3d6000fd5b50505050612663565b83516000906002906125939085906001600160801b031661312b565b61259d9190614084565b905060006125df836125af8a85614046565b6125b9919061421c565b6125c28561266c565b88602001516125d191906141f4565b6001600160801b031661313c565b6020880151885160405163c89fc72f60e01b81526001600160a01b0389811660048301529182166024820152604481018c90526064810184905260006084820152929350169063c89fc72f9060a401600060405180830381600087803b15801561264857600080fd5b505af115801561265c573d6000803e3d6000fd5b5050505050505b505b5050505050565b6000600160801b82106126d15760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b6064820152608401610377565b50805b919050565b8051606090600090806001600160401b0381111561270757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612730578160200160208202803683370190505b5092506000805b828110156127e557600086828151811061276157634e487b7160e01b600052603260045260246000fd5b602002602001015190506305f5e1008160000151826020015161278491906141af565b61278e919061405e565b6001600160801b03169250828683815181106127ba57634e487b7160e01b600052603260045260246000fd5b60209081029190910101526127cf8386614046565b94505080806127dd9061425f565b915050612737565b505050915091565b8251600090836128015760009150506123a7565b600061280d82856141d5565b9050600085935060005b61010081101561293a578460005b8581101561288857858a828151811061284e57634e487b7160e01b600052603260045260246000fd5b602002602001015161286091906141d5565b61286a88846141d5565b6128749190614084565b9150806128808161425f565b915050612825565b5085925080612898866001614046565b6128a291906141d5565b6064876128af828861421c565b6128b991906141d5565b6128c39190614084565b6128cd9190614046565b866128d887846141d5565b60646128e48c896141d5565b6128ee9190614084565b6128f89190614046565b61290291906141d5565b61290c9190614084565b95506129188684613151565b156129275750505050506123a7565b50806129328161425f565b915050612817565b5060405162461bcd60e51b815260206004820152601a60248201527f496e76617269616e7420646964206e6f7420636f6e76657267650000000000006044820152606401610377565b82516001906000805b82811015612a2357858782815181106129b557634e487b7160e01b600052603260045260246000fd5b6020026020010151670de0b6b3a76400006129d091906141d5565b6129da9190614084565b915084602001516001600160801b0316821180612a00575084516001600160801b031682105b15612a1157600093505050506123a7565b80612a1b8161425f565b91505061298c565b5050509392505050565b600080612a3f868685602001516127ed565b8351909150612a5957612a52848261421c565b9150612a7d565b83612a64818361421c565b8451612a7091906141d5565b612a7a9190614084565b91505b8251841015612ab657670de0b6b3a7640000836060015183612a9f91906141d5565b612aa99190614084565b612ab3908361421c565b91505b50949350505050565b60208401516000906001600160a01b0316612af0576000612ae6333088600001518761317c565b509150612cd39050565b6000612b0633876020015188600001518761317c565b6040880151919350915015612bbf57602086015186516040516307dba22560e31b81526001600160a01b03918216600482015260248101859052600160448201526000929190911690633edd112890606401602060405180830381600087803b158015612b7257600080fd5b505af1158015612b86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612baa9190613e8b565b9050612bb6818461313c565b92505050612cd3565b838214612c0e5760405162461bcd60e51b815260206004820152601b60248201527f4173736574206e6f742066756c6c79207472616e7366657272656400000000006044820152606401610377565b6000612c1a848761312b565b905080821115612cd0576000612c31600283614084565b612c3b908461421c565b602089015189516040516307dba22560e31b81526001600160a01b03918216600482015260248101849052600060448201529293501690633edd112890606401602060405180830381600087803b158015612c9557600080fd5b505af1158015612ca9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ccd9190613e8b565b50505b50505b949350505050565b82518490600090831015612d1957670de0b6b3a7640000856060015183612d0291906141d5565b612d0c9190614084565b612d16908361421c565b91505b612d238285613299565b9050612d2f818361421c565b915094509492505050565b8351600090808460ff1610612d815760405162461bcd60e51b815260206004820152600d60248201526c092dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610377565b6000808080612d90858a6141d5565b8792509250925060005b84811015612e3d578760ff168114612e2b57898181518110612dcc57634e487b7160e01b600052603260045260246000fd5b602002602001015184612ddf9190614046565b9350848a8281518110612e0257634e487b7160e01b600052603260045260246000fd5b6020026020010151612e1491906141d5565b612e1e88846141d5565b612e289190614084565b91505b80612e358161425f565b915050612d9a565b50600084836064612e4e8a866141d5565b612e5891906141d5565b612e629190614084565b612e6c9190614084565b9050600083612e7c60648261421c565b612e86908a6141d5565b612e909190614084565b9050600085821115612ef957612ea6868361421c565b9050600281612ed3612eb98660046141d5565b612ec46002866140de565b612ece9190614046565b6132ae565b612edd9190614046565b612ee79190614084565b612ef2906001614046565b9750612f38565b612f03828761421c565b9050600281612f16612eb98660046141d5565b612f20919061421c565b612f2a9190614084565b612f35906001614046565b97505b6305f5e100881015612f7f5760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b21039b7b63aba34b7b760811b6044820152606401610377565b50505050505050949350505050565b60008161239d670de0b6b3a7640000856141d5565b92915050565b60008080612fb7878761421c565b90508684600001511115612ff557670de0b6b3a7640000846060015182612fde91906141d5565b612fe89190614084565b612ff2908261421c565b90505b670de0b6b3a764000061300886836141d5565b6130129190614084565b91508161301f828861421c565b6130299190614046565b8451909350879061303a90846141d5565b6130449190614084565b91505094509492505050565b8160008061305e8787611e80565b509050670de0b6b3a76400008110156130a157670de0b6b3a764000086606001518661308a91906141d5565b6130949190614084565b61309e908461421c565b92505b6130ab8385613299565b91506130b7828461421c565b92505094509492505050565b6040516001600160a01b03831660248201526044810182905261312690849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261342d565b505050565b60008161239d6305f5e100856141d5565b600081831161314b57826123a7565b50919050565b600082821115613170576001613167848461421c565b11159050612fa3565b6001613167838561421c565b6040516370a0823160e01b81526001600160a01b03848116600483015260009182918291908616906370a082319060240160206040518083038186803b1580156131c557600080fd5b505afa1580156131d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131fd9190613e8b565b90506132146001600160a01b0386168888876134ff565b6040516370a0823160e01b81526001600160a01b0387811660048301528616906370a082319060240160206040518083038186803b15801561325557600080fd5b505afa158015613269573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061328d9190613e8b565b91506130b7818361421c565b60006123a78383670de0b6b3a764000061353d565b6000816132bd575060006126d4565b816001600160801b82106132d65760809190911c9060401b5b6801000000000000000082106132f15760409190911c9060201b5b64010000000082106133085760209190911c9060101b5b62010000821061331d5760109190911c9060081b5b61010082106133315760089190911c9060041b5b601082106133445760049190911c9060021b5b600882106133505760011b5b600161335c8286614084565b6133669083614046565b901c905060016133768286614084565b6133809083614046565b901c905060016133908286614084565b61339a9083614046565b901c905060016133aa8286614084565b6133b49083614046565b901c905060016133c48286614084565b6133ce9083614046565b901c905060016133de8286614084565b6133e89083614046565b901c905060016133f88286614084565b6134029083614046565b901c905060006134128286614084565b90508082106134215780613423565b815b93505050506126d4565b6000613482826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166135549092919063ffffffff16565b80519091501561312657808060200190518101906134a09190613b8e565b6131265760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610377565b6040516001600160a01b03808516602483015283166044820152606481018290526135379085906323b872dd60e01b906084016130ef565b50505050565b60008161354a84866141d5565b612cd39190614084565b6060612cd3848460008585843b6135ad5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610377565b600080866001600160a01b031685876040516135c99190613ebd565b60006040518083038185875af1925050503d8060008114613606576040519150601f19603f3d011682016040523d82523d6000602084013e61360b565b606091505b509150915061361b828286613626565b979650505050505050565b606083156136355750816123a7565b8251156136455782518084602001fd5b8160405162461bcd60e51b81526004016103779190613ed9565b80356001600160a01b03811681146126d457600080fd5b600082601f830112613686578081fd5b8135602061369b61369683613ff8565b613fc8565b828152818101908583016040808602880185018910156136b9578687fd5b865b868110156136df576136cd8a8461380e565b855293850193918101916001016136bb565b509198975050505050505050565b60008083601f8401126136fe578182fd5b5081356001600160401b03811115613714578182fd5b602083019150836020808302850101111561372e57600080fd5b9250929050565b600082601f830112613745578081fd5b8135602061375561369683613ff8565b8281528181019085830183850287018401881015613771578586fd5b855b8581101561378f57813584529284019290840190600101613773565b5090979650505050505050565b600082601f8301126137ac578081fd5b813560206137bc61369683613ff8565b82815281810190858301838502870184018810156137d8578586fd5b855b8581101561378f576137eb826138c2565b845292840192908401906001016137da565b60006060828403121561314b578081fd5b60006040828403121561381f578081fd5b6138296040613fc8565b9050613834826138ab565b8152613842602083016138ab565b602082015292915050565b600060a0828403121561314b578081fd5b600060a0828403121561386f578081fd5b6138796080613fc8565b90508135815260208201356020820152613896836040840161380e565b60408201526080820135606082015292915050565b80356001600160801b03811681146126d457600080fd5b803560ff811681146126d457600080fd5b60008060008061010085870312156138e9578384fd5b84356001600160401b03808211156138ff578586fd5b61390b88838901613676565b95506020870135915080821115613920578485fd5b61392c8883890161379c565b94506040870135915080821115613941578384fd5b5061394e87828801613735565b92505061395e866060870161385e565b905092959194509250565b60008060008060006101208688031215613981578081fd5b85356001600160401b0380821115613997578283fd5b6139a389838a01613676565b965060208801359150808211156139b8578283fd5b6139c489838a0161379c565b955060408801359150808211156139d9578283fd5b506139e688828901613735565b9350506139f6876060880161385e565b94979396509194610100013592915050565b60008060c08385031215613a1a578182fd5b82356001600160401b03811115613a2f578283fd5b613a3b85828601613676565b925050613a4b846020850161385e565b90509250929050565b6000806000806101008587031215613a6a578182fd5b84356001600160401b03811115613a7f578283fd5b613a8b87828801613676565b945050613a9a602086016138c2565b92506040850135915061395e866060870161385e565b60008060008060006101208688031215613ac8578283fd5b85356001600160401b03811115613add578384fd5b613ae988828901613676565b955050613af8602087016138c2565b9350604086013592506139f6876060880161385e565b6000806000806000806101408789031215613b27578384fd5b86356001600160401b03811115613b3c578485fd5b613b4889828a01613676565b965050613b57602088016138c2565b9450613b65604088016138c2565b93506060870135925060808701359150613b828860a0890161385e565b90509295509295509295565b600060208284031215613b9f578081fd5b815180151581146123a7578182fd5b600060a08284031215613bbf578081fd5b6123a7838361385e565b6000806000806000806000610120888a031215613be4578485fd5b87359650613bf58960208a0161384d565b955060c08801356001600160401b0380821115613c10578687fd5b613c1c8b838c016136ed565b909750955060e08a0135915080821115613c34578283fd5b50613c418a828b016136ed565b989b979a5095989497959661010090950135949350505050565b60008060008060008060006101e0888a031215613c76578081fd5b87359650613c878960208a0161384d565b9550613c968960c08a016137fd565b9450613ca6896101208a016137fd565b935061018088013592506101a08801359150613cc56101c0890161365f565b905092959891949750929550565b60008060008060006101608688031215613ceb578283fd5b85359450613cfc876020880161384d565b9350613d0b8760c088016137fd565b949793965093946101208101359450610140013592915050565b6000806000806000806101808789031215613d3e578384fd5b86359550613d4f886020890161384d565b9450613d5e8860c089016137fd565b935061012087013592506101408701359150613b82610160880161365f565b6000806000806000806101208789031215613d96578384fd5b86359550613da7886020890161384d565b945060c0870135935060e08701356001600160401b03811115613dc8578283fd5b613dd489828a016136ed565b9094509250613b829050610100880161365f565b600080600080600080600080610140898b031215613e04578182fd5b88359750613e158a60208b0161385e565b965060c08901356001600160401b0380821115613e30578384fd5b613e3c8c838d016136ed565b909850965060e08b0135915080821115613e54578384fd5b50613e618b828c016136ed565b9095509350506101008901359150613e7c6101208a0161365f565b90509295985092959890939650565b600060208284031215613e9c578081fd5b5051919050565b600060208284031215613eb4578081fd5b6123a7826138c2565b60008251613ecf818460208701614233565b9190910192915050565b6000602082528251806020840152613ef8816040850160208701614233565b601f01601f19169190910160400192915050565b6020808252601590820152744578636565647320776569676874206c696d69747360581b604082015260600190565b60006060820185835260206060818501528186518084526080860191508288019350845b81811015613f845784516001600160a01b031683529383019391830191600101613f5f565b505084810360408601528551808252908201925081860190845b81811015613fba57825185529383019391830191600101613f9e565b509298975050505050505050565b604051601f8201601f191681016001600160401b0381118282101715613ff057613ff06142a6565b604052919050565b60006001600160401b03821115614011576140116142a6565b5060209081020190565b60006001600160801b0380831681851680830382111561403d5761403d61427a565b01949350505050565b600082198211156140595761405961427a565b500190565b60006001600160801b038084168061407857614078614290565b92169190910492915050565b60008261409357614093614290565b500490565b80825b60018086116140aa57506140d5565b8187048211156140bc576140bc61427a565b808616156140c957918102915b9490941c93800261409b565b94509492505050565b60006123a760001960ff8516846000826140fa575060016123a7565b81614107575060006123a7565b816001811461411d576002811461412757614154565b60019150506123a7565b60ff8411156141385761413861427a565b6001841b91508482111561414e5761414e61427a565b506123a7565b5060208310610133831016604e8410600b8410161715614187575081810a838111156141825761418261427a565b6123a7565b6141948484846001614098565b8086048211156141a6576141a661427a565b02949350505050565b60006001600160801b03808316818516818304811182151516156141a6576141a661427a565b60008160001904831182151516156141ef576141ef61427a565b500290565b60006001600160801b03838116908316818110156142145761421461427a565b039392505050565b60008282101561422e5761422e61427a565b500390565b60005b8381101561424e578181015183820152602001614236565b838111156135375750506000910152565b60006000198214156142735761427361427a565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea2646970667358221220f78cb1fc5e5f9d3d51d2ceab0af6d29268e939f879fbfcba8b52c10ff7bbad2364736f6c63430008020033
Deployed Bytecode Sourcemap
33530:36362:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47462:1483;;;;;;;;;;-1:-1:-1;47462:1483:0;;;;;:::i;:::-;;:::i;:::-;;;;25942:25:1;;;25998:2;25983:18;;25976:34;;;;25915:18;47462:1483:0;;;;;;;;54478:761;;;;;;:::i;:::-;;:::i;:::-;;;24457:25:1;;;24445:2;24430:18;54478:761:0;24412:76:1;38740:1881:0;;;;;;;;;;-1:-1:-1;38740:1881:0;;;;;:::i;:::-;;:::i;41607:1463::-;;;;;;;;;;-1:-1:-1;41607:1463:0;;;;;:::i;:::-;;:::i;59808:1083::-;;;;;;:::i;:::-;;:::i;34408:1171::-;;;;;;;;;;-1:-1:-1;34408:1171:0;;;;;:::i;:::-;;:::i;61893:1438::-;;;;;;:::i;:::-;;:::i;57344:1281::-;;;;;;:::i;:::-;;:::i;55690:980::-;;;;;;:::i;:::-;;:::i;36288:1510::-;;;;;;;;;;-1:-1:-1;36288:1510:0;;;;;:::i;:::-;;:::i;63640:330::-;;;;;;:::i;:::-;;:::i;43884:2030::-;;;;;;;;;;-1:-1:-1;43884:2030:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;47462:1483::-;47740:22;47764:11;47840:36;47879:5;:16;;47840:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47840:55:0;;;;;-1:-1:-1;;;47840:55:0;;;;;;;;;;;;;;;;;;;;;;;;;47932:165;47965:16;47996:8;;47932:165;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;47932:165:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48019:17:0;;-1:-1:-1;48019:17:0;;;;47932:165;;;48019:17;;47932:165;48019:17;47932:165;;;;;;;;;;;;;;;;;;;;;;;;;;48051:7;48073:5;:13;;;47932:18;:165::i;:::-;47908:189;;-1:-1:-1;47908:189:0;-1:-1:-1;48116:36:0;;;;48108:81;;;;-1:-1:-1;;;48108:81:0;;24144:2:1;48108:81:0;;;24126:21:1;;;24163:18;;;24156:30;24222:34;24202:18;;;24195:62;24274:18;;48108:81:0;;;;;;;;;48284:3;48267:5;:13;;;:20;;;;;;;:::i;:::-;;;;;;;;48363:16;48382:62;48399:5;48440:3;48423:14;48406:7;:14;;;:31;;;;:::i;:::-;:37;;;;:::i;:::-;48382:16;:62::i;:::-;48363:81;;48460:9;48455:483;48475:19;;;48455:483;;;48516:9;48528:8;;48537:1;48528:11;;;;;-1:-1:-1;;;48528:11:0;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48516:23;;48554:209;48588:17;;48606:1;48588:20;;;;;-1:-1:-1;;;48588:20:0;;;;;;;;;;;;;;;48627:5;:20;;48648:3;48627:25;;;;;;;;-1:-1:-1;;;48627:25:0;;;;;;;;;;;;;;;;;;48554:209;;;;;;;;48627:25;;;;;;;48554:209;;-1:-1:-1;;;;;48554:209:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;48554:209:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;48554:209:0;;;;;;;;;;-1:-1:-1;;;48554:209:0;;;;;;;;;;;;;;;-1:-1:-1;;;48554:209:0;;;;;;;;;;;;;48671:16;48688:3;48671:21;;;;;;;;-1:-1:-1;;;48671:21:0;;;;;;;;;;;;;;;48711:10;48740:8;48554:15;:209::i;:::-;48886:40;48905:17;;48923:1;48905:20;;;;;-1:-1:-1;;;48905:20:0;;;;;;;;;;;;;;;48886:18;:40::i;:::-;48832:16;48849:3;48832:21;;;;;;;;-1:-1:-1;;;48832:21:0;;;;;;;;;;;;;;;:34;;;:94;;;;:::i;:::-;48778:5;:16;;48795:3;48778:21;;;;;;;;-1:-1:-1;;;48778:21:0;;;;;;;;;;;;;;;;;;:148;;-1:-1:-1;;;;;48778:148:0;;;-1:-1:-1;;;48778:148:0;;;;;;;;;-1:-1:-1;48496:3:0;;;;:::i;:::-;;;;48455:483;;;;47462:1483;;;;;;;;;;;;;:::o;54478:761::-;54654:18;54718;54738:11;54753:22;54766:8;54753:12;:22::i;:::-;54717:58;;;;54846:10;54859:29;54870:1;54873:3;54878:7;:9;;;54859:10;:29::i;:::-;54846:42;;54899:19;54956:3;54934:8;54943:2;54934:12;;;;;;;;-1:-1:-1;;;54934:12:0;;;;;;;;;;;;;;;:18;;;-1:-1:-1;;;;;54922:30:0;:9;:30;;;;:::i;:::-;54921:38;;;;:::i;:::-;54899:60;;55021:11;55012:1;55014:2;55012:5;;;;;;;;-1:-1:-1;;;55012:5:0;;;;;;;;;;;;;;:20;;;;;;;:::i;:::-;;;-1:-1:-1;55043:18:0;55050:11;55043:18;;:::i;:::-;;;55109:33;55119:1;55122:3;55127:7;:14;;;55109:9;:33::i;:::-;55101:67;;;;-1:-1:-1;;;55101:67:0;;;;;;;:::i;:::-;55192:39;55211:1;55214:3;55219:2;55223:7;55192:18;:39::i;:::-;55179:52;54478:761;-1:-1:-1;;;;;;;;;54478:761:0:o;38740:1881::-;39021:18;39041:17;39071:36;39110:5;:16;;39071:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;39071:55:0;;;;;-1:-1:-1;;;39071:55:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;39071:55:0;;-1:-1:-1;39177:25:0;;-1:-1:-1;39218:224:0;;-1:-1:-1;;39251:20:0;;;39272:10;;;;:6;:10;:::i;:::-;39251:32;;;;;;;;-1:-1:-1;;;39251:32:0;;;;;;;;;;;;;;;;;;39218:224;;;;;;;;39251:32;;;;;;;39218:224;;-1:-1:-1;;;;;39218:224:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;39218:224:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;39218:224:0;;;;;;;;;;-1:-1:-1;;;39218:224:0;;;;;;;;;;;;;;;-1:-1:-1;;;39218:224:0;;;;;;;;;;;-1:-1:-1;39302:16:0;39319:10;;;;:6;:10;:::i;:::-;39302:28;;;;;;;;-1:-1:-1;;;39302:28:0;;;;;;;;;;;;;;;:34;;;-1:-1:-1;;;;;39218:224:0;39355:14;39388:39;39405:5;39412:7;:14;;;39388:16;:39::i;:::-;39218:14;:224::i;:::-;39177:265;;39609:37;39628:17;39609:18;:37::i;:::-;39552:16;39569:10;;;;:6;:10;:::i;:::-;39552:28;;;;;;;;-1:-1:-1;;;39552:28:0;;;;;;;;;;;;;;;:41;;;:94;;;;:::i;:::-;39495:16;;;39512:10;;;;:6;:10;:::i;:::-;39495:28;;;;;;;;-1:-1:-1;;;39495:28:0;;;;;;;;;;;;;;;;;;;:151;;-1:-1:-1;;;;;39495:151:0;;;-1:-1:-1;;;39495:151:0;;;;;;;;;;39718:186;;39744:16;;39775:10;;;;:6;:10;:::i;:::-;39800:11;;;;:7;:11;:::i;:::-;39826:17;39858:5;:13;;;39886:7;39718:186;;;;;;;;;;:::i;:::-;39692:212;;-1:-1:-1;39692:212:0;-1:-1:-1;39923:32:0;;;;39915:69;;;;-1:-1:-1;;;39915:69:0;;20174:2:1;39915:69:0;;;20156:21:1;20213:2;20193:18;;;20186:30;20252:26;20232:18;;;20225:54;20296:18;;39915:69:0;20146:174:1;39915:69:0;40016:1;40003:10;:14;39995:47;;;;-1:-1:-1;;;39995:47:0;;23795:2:1;39995:47:0;;;23777:21:1;23834:2;23814:18;;;23807:30;-1:-1:-1;;;23853:18:1;;;23846:50;23913:18;;39995:47:0;23767:170:1;39995:47:0;40119:16;40138:39;40155:5;40162:14;;40138:16;:39::i;:::-;40119:58;-1:-1:-1;40188:191:0;40218:10;40243:20;;;40264:11;;;;:7;:11;:::i;:::-;40243:33;;;;;;;;-1:-1:-1;;;40243:33:0;;;;;;;;;;;;;;;;;;40188:191;;;;;;;;40243:33;;;;;;;40188:191;;-1:-1:-1;;;;;40188:191:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;40188:191:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;40188:191:0;;;;;;;;;;-1:-1:-1;;;40188:191:0;;;;;;;;;;;;;;;-1:-1:-1;;;40188:191:0;;;;;;;;;;;-1:-1:-1;40291:16:0;40308:11;;;;:7;:11;:::i;:::-;40291:29;;;;;;;;-1:-1:-1;;;40291:29:0;;;;;;;;;;;;;;;40335:10;40360:8;40188:15;:191::i;:::-;40506:30;40525:10;40506:18;:30::i;:::-;40448:16;40465:11;;;;:7;:11;:::i;:::-;40448:29;;;;;;;;-1:-1:-1;;;40448:29:0;;;;;;;;;;;;;;;:42;;;:88;;;;:::i;:::-;40390:16;;;40407:11;;;;:7;:11;:::i;:::-;40390:29;;;;;;;;-1:-1:-1;;;40390:29:0;;;;;;;;;;;;;;;;;:146;;-1:-1:-1;;;;;40390:146:0;;;-1:-1:-1;;;40390:146:0;;;;;;;;;;40587:13;;;:26;;40604:9;;40390:29;40587:26;;40604:9;;40587:26;:::i;:::-;;;;;;;;38740:1881;;;;;;;;;;;;;:::o;41607:1463::-;41858:22;41882:17;41970:36;42009:5;:16;;41970:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;41970:55:0;;;;;-1:-1:-1;;;41970:55:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;41970:55:0;;-1:-1:-1;42110:160:0;;-1:-1:-1;41970:55:0;;-1:-1:-1;42169:11:0;;-1:-1:-1;42169:11:0;;;:7;:11;:::i;:::-;42195:14;42110:160;;;;;;;42224:7;42110:160;:::i;:::-;42246:13;;42110;:160::i;:::-;42080:190;;-1:-1:-1;42080:190:0;-1:-1:-1;42289:36:0;;;;42281:69;;;;-1:-1:-1;;;42281:69:0;;19417:2:1;42281:69:0;;;19399:21:1;19456:2;19436:18;;;19429:30;-1:-1:-1;;;19475:18:1;;;19468:50;19535:18;;42281:69:0;19389:170:1;42281:69:0;42386:1;42369:14;:18;42361:42;;;;-1:-1:-1;;;42361:42:0;;21635:2:1;42361:42:0;;;21617:21:1;21674:2;21654:18;;;21647:30;-1:-1:-1;;;21693:18:1;;;21686:41;21744:18;;42361:42:0;21607:161:1;42361:42:0;42498:9;42481:5;:13;;;:26;;;;;;;:::i;:::-;;;;-1:-1:-1;42573:16:0;;-1:-1:-1;42592:68:0;42609:5;42650:9;42616:31;42633:14;42616;;:31;:::i;42592:68::-;42573:87;-1:-1:-1;42671:195:0;42701:14;42730:20;;;42751:11;;;;:7;:11;:::i;:::-;42730:33;;;;;;;;-1:-1:-1;;;42730:33:0;;;;;;;;;;;;;;;;;;42671:195;;;;;;;;42730:33;;;;;;;42671:195;;-1:-1:-1;;;;;42671:195:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;42671:195:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;42671:195:0;;;;;;;;;;-1:-1:-1;;;42671:195:0;;;;;;;;;;;;;;;-1:-1:-1;;;42671:195:0;;;;;;;;;;;-1:-1:-1;42778:16:0;42795:11;;;;:7;:11;:::i;:::-;42778:29;;;;;;;;-1:-1:-1;;;42778:29:0;;;;;;;;;;;;;;;42822:10;42847:8;42671:15;:195::i;:::-;43028:34;43047:14;43028:18;:34::i;:::-;42970:16;42987:11;;;;:7;:11;:::i;:::-;42970:29;;;;;;;;-1:-1:-1;;;42970:29:0;;;;;;;;;;;;;;;:42;;;:92;;;;:::i;:::-;42912:16;;;42929:11;;;;:7;:11;:::i;:::-;42912:29;;;;;;;;-1:-1:-1;;;42912:29:0;;;;;;;;;;;;;;;;;;:150;;-1:-1:-1;;;;;42912:150:0;;;-1:-1:-1;;;42912:150:0;;;;;;;;;-1:-1:-1;41607:1463:0;;;;-1:-1:-1;41607:1463:0;-1:-1:-1;;;;;;41607:1463:0:o;59808:1083::-;60024:22;60048:17;60111:18;60131:11;60146:22;60159:8;60146:12;:22::i;:::-;60110:58;;;;60239:10;60252:29;60263:1;60266:3;60271:7;:9;;;60252:10;:29::i;:::-;60239:42;;60292:18;60347:52;60355:20;60377:7;60386:8;60396:2;60347:7;:52::i;:::-;60466:14;;60321:78;;-1:-1:-1;60321:78:0;;-1:-1:-1;60410:14:0;;60434:27;60321:78;60466:14;60434:27;:::i;:::-;60428:34;;:2;:34;:::i;:::-;60427:53;;;;:::i;:::-;:57;;60483:1;60427:57;:::i;:::-;60410:74;;60532:24;60559:41;60575:1;60578:7;:9;;;60589:2;60593:6;60559:15;:41::i;:::-;60532:68;;60611:14;60655:1;60636:16;60628:1;60630:2;60628:5;;;;;;;;-1:-1:-1;;;60628:5:0;;;;;;;;;;;;;;;:24;;;;:::i;:::-;:28;;;;:::i;:::-;60611:45;;60701:8;60710:2;60701:12;;;;;;;;-1:-1:-1;;;60701:12:0;;;;;;;;;;;;;;;:18;;;-1:-1:-1;;;;;60684:35:0;60685:6;60694:3;60685:12;;;;:::i;:::-;60684:35;;;;:::i;:::-;60667:52;;60775:6;60766:1;60768:2;60766:5;;;;;;;;-1:-1:-1;;;60766:5:0;;;;;;;;;;;;;;:15;;;;;;;:::i;:::-;;;-1:-1:-1;60792:13:0;60799:6;60792:13;;:::i;:::-;;;60824:33;60834:1;60837:3;60842:7;:14;;;60824:9;:33::i;:::-;60816:67;;;;-1:-1:-1;;;60816:67:0;;;;;;;:::i;:::-;59808:1083;;;;;;;;;;;;;;;:::o;34408:1171::-;34627:18;34658:36;34697:5;:16;;34658:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;34658:55:0;;;;;-1:-1:-1;;;34658:55:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;34658:55:0;;-1:-1:-1;34809:25:0;;-1:-1:-1;34850:224:0;;-1:-1:-1;;34883:20:0;;;34904:10;;;;:6;:10;:::i;:::-;34883:32;;;;;;;;-1:-1:-1;;;34883:32:0;;;;;;;;;;;;;;;;;;34850:224;;;;;;;;34883:32;;;;;;;34850:224;;-1:-1:-1;;;;;34850:224:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;34850:224:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;34850:224:0;;;;;;;;;;-1:-1:-1;;;34850:224:0;;;;;;;;;;;;;;;-1:-1:-1;;;34850:224:0;;;;;;;;;;;-1:-1:-1;34934:16:0;34951:10;;;;:6;:10;:::i;:::-;34934:28;;;;;;;;-1:-1:-1;;;34934:28:0;;;;;;;;;;;;;;;:34;;;-1:-1:-1;;;;;34850:224:0;34987:14;35020:39;35037:5;35044:7;:14;;;35020:16;:39::i;34850:224::-;34809:265;-1:-1:-1;35184:69:0;35196:16;35214:10;;;;:6;:10;:::i;:::-;35226:17;35184:69;;;;;;;35245:7;35184:69;:::i;:::-;35171:82;;35286:18;35272:10;:32;;35264:68;;;;-1:-1:-1;;;35264:68:0;;18368:2:1;35264:68:0;;;18350:21:1;18407:2;18387:18;;;18380:30;-1:-1:-1;;;18426:18:1;;;18419:53;18489:18;;35264:68:0;18340:173:1;35264:68:0;35534:37;35553:17;35534:18;:37::i;:::-;35477:16;35494:10;;;;:6;:10;:::i;:::-;35477:28;;;;;;;;-1:-1:-1;;;35477:28:0;;;;;;;;;;;;;;;:41;;;:94;;;;:::i;:::-;35420:16;;;35437:10;;;;:6;:10;:::i;:::-;35420:28;;;;;;;;-1:-1:-1;;;35420:28:0;;;;;;;;;;;;;;;;;;:151;;-1:-1:-1;;;;;35420:151:0;;;-1:-1:-1;;;35420:151:0;;;;;;;;;-1:-1:-1;34408:1171:0;;;-1:-1:-1;;;;;;34408:1171:0:o;61893:1438::-;62129:19;62150:11;62207:18;62227:11;62242:22;62255:8;62242:12;:22::i;:::-;62206:58;;;;62335:10;62348:29;62359:1;62362:3;62367:7;:9;;;62348:10;:29::i;:::-;62445:15;;62335:42;;-1:-1:-1;62431:11:0;;62497:192;62521:3;62517:1;:7;62497:192;;;62605:3;62574:8;62583;62592:1;62583:11;;;;;;-1:-1:-1;;;62583:11:0;;;;;;;;;;;;;;;62574:21;;;;;;;;-1:-1:-1;;;62574:21:0;;;;;;;;;;;;;;;:27;;;-1:-1:-1;;;;;62557:44:0;:11;62569:1;62557:14;;;;;;-1:-1:-1;;;62557:14:0;;;;;;;;;;;;;;;:44;;;;:::i;:::-;62556:52;;;;:::i;:::-;62546:62;;62641:7;62623:1;62625:8;62634:1;62625:11;;;;;;-1:-1:-1;;;62625:11:0;;;;;;;;;;;;;;;62623:14;;;;;;;;-1:-1:-1;;;62623:14:0;;;;;;;;;;;;;;:25;;;;;;;:::i;:::-;;;-1:-1:-1;62663:14:0;62670:7;62663:14;;:::i;:::-;;-1:-1:-1;62526:3:0;;;;:::i;:::-;;;;62497:192;;;;62707:33;62717:1;62720:3;62725:7;:14;;;62707:9;:33::i;:::-;62699:67;;;;-1:-1:-1;;;62699:67:0;;;;;;;:::i;:::-;62841:10;62854:29;62865:1;62868:3;62873:7;:9;;;62854:10;:29::i;:::-;62841:42;-1:-1:-1;62955:16:0;63005:2;62993:7;62841:42;63005:2;62993:7;:::i;:::-;62975:14;;:26;;;;:::i;:::-;62974:33;;;;:::i;:::-;62955:52;;63037:3;63026:8;:14;63018:50;;;;-1:-1:-1;;;63018:50:0;;21975:2:1;63018:50:0;;;21957:21:1;22014:2;21994:18;;;21987:30;22053:25;22033:18;;;22026:53;22096:18;;63018:50:0;21947:173:1;63018:50:0;63093:38;63115:15;63122:8;63115:4;:15;:::i;:::-;63093:8;;:21;:38::i;:::-;63079:52;-1:-1:-1;63148:22:0;63162:8;63079:52;63148:22;:::i;:::-;63142:28;-1:-1:-1;63181:16:0;63196:1;63181:16;;:::i;:::-;;;63229:2;63212:7;:14;;;:19;63208:116;;;63294:16;;;;63287:23;;:4;:23;:::i;:::-;63264:18;:11;63278:4;63264:18;:::i;:::-;63263:48;;;;:::i;:::-;63248:64;;61893:1438;;;;;;;;;;;;;;;:::o;57344:1281::-;57566:28;57596:21;57663:18;57683:11;57698:22;57711:8;57698:12;:22::i;:::-;57662:58;;;;57791:10;57804:29;57815:1;57818:3;57823:7;:9;;;57804:10;:29::i;:::-;57791:42;;57885:19;57942:3;57920:8;57929:2;57920:12;;;;;;;;-1:-1:-1;;;57920:12:0;;;;;;;;;;;;;;;:18;;;-1:-1:-1;;;;;57908:30:0;:9;:30;;;;:::i;:::-;57907:38;;;;:::i;:::-;57885:60;;57965:11;57956:1;57958:2;57956:5;;;;;;;;-1:-1:-1;;;57956:5:0;;;;;;;;;;;;;;:20;;;;;;;:::i;:::-;;;-1:-1:-1;57987:18:0;57994:11;57987:18;;:::i;:::-;;;58051:10;58094:65;58106:2;58110:29;58121:1;58124:3;58129:7;:9;;;58110:10;:29::i;:::-;58141:8;58151:7;58094:11;:65::i;:::-;58072:87;;;;;;;;58204:24;58231:37;58247:1;58250:7;:9;;;58261:2;58265;58231:15;:37::i;:::-;58204:64;;58306:1;58308:2;58306:5;;;;;;;;-1:-1:-1;;;58306:5:0;;;;;;;;;;;;;;;58287:16;:24;58279:53;;;;-1:-1:-1;;;58279:53:0;;18023:2:1;58279:53:0;;;18005:21:1;18062:2;18042:18;;;18035:30;-1:-1:-1;;;18081:18:1;;;18074:46;18137:18;;58279:53:0;17995:166:1;58279:53:0;58343:14;58387:1;58368:16;58360:1;58362:2;58360:5;;;;;;;;-1:-1:-1;;;58360:5:0;;;;;;;;;;;;;;;:24;;;;:::i;:::-;:28;;;;:::i;:::-;58343:45;;58439:8;58448:2;58439:12;;;;;;;;-1:-1:-1;;;58439:12:0;;;;;;;;;;;;;;;:18;;;-1:-1:-1;;;;;58422:35:0;58423:6;58432:3;58423:12;;;;:::i;:::-;58422:35;;;;:::i;:::-;58399:58;;58509:6;58500:1;58502:2;58500:5;;;;;;;;-1:-1:-1;;;58500:5:0;;;;;;;;;;;;;;:15;;;;;;;:::i;:::-;;;-1:-1:-1;58526:13:0;58533:6;58526:13;;:::i;:::-;;;58558:33;58568:1;58571:3;58576:7;:14;;;58558:9;:33::i;:::-;58550:67;;;;-1:-1:-1;;;58550:67:0;;;;;;;:::i;:::-;57344:1281;;;;;;;;;;;;;;;;:::o;55690:980::-;55896:18;55960;55980:11;55995:22;56008:8;55995:12;:22::i;:::-;55959:58;;;;56088:10;56101:29;56112:1;56115:3;56120:7;:9;;;56101:10;:29::i;:::-;56198:15;;56088:42;;-1:-1:-1;56184:11:0;;;56274:219;56298:3;56294:1;:7;56274:219;;;56329:8;56338:1;56329:11;;;;;;-1:-1:-1;;;56329:11:0;;;;;;;;;;;;;;;56323:17;;56409:3;56386:8;56395:3;56386:13;;;;;;;;-1:-1:-1;;;56386:13:0;;;;;;;;;;;;;;;:19;;;-1:-1:-1;;;;;56370:35:0;:10;56381:1;56370:13;;;;;;-1:-1:-1;;;56370:13:0;;;;;;;;;;;;;;;:35;;;;:::i;:::-;56369:43;;;;:::i;:::-;56355:57;;56437:11;56427:1;56429:3;56427:6;;;;;;;;-1:-1:-1;;;56427:6:0;;;;;;;;;;;;;;:21;;;;;;;:::i;:::-;;;-1:-1:-1;56463:18:0;56470:11;56463:18;;:::i;:::-;;-1:-1:-1;56303:3:0;;;;:::i;:::-;;;;56274:219;;;;56540:33;56550:1;56553:3;56558:7;:14;;;56540:9;:33::i;:::-;56532:67;;;;-1:-1:-1;;;56532:67:0;;;;;;;:::i;:::-;56623:39;56642:1;56645:3;56650:2;56654:7;56623:18;:39::i;:::-;56610:52;55690:980;-1:-1:-1;;;;;;;;;;;55690:980:0:o;36288:1510::-;36529:18;36574:8;36529:18;36574:8;-1:-1:-1;;;;;36639:18:0;;;;;-1:-1:-1;;;36639:18:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36639:18:0;;36600:57;;36668:36;36707:5;:16;;36668:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;36668:55:0;;;;;-1:-1:-1;;;36668:55:0;;;;;;;;;;;;;;;;;;;;;;;;;36734:16;36753:39;36770:5;36777:7;:14;;;36753:16;:39::i;:::-;36734:58;;36892:9;36887:608;36911:3;36907:1;:7;36887:608;;;36962:1;36940:16;;36957:1;36940:19;;;;;-1:-1:-1;;;36940:19:0;;;;;;;;;;;;;;;:23;36936:548;;;36984:9;36996:8;;37005:1;36996:11;;;;;-1:-1:-1;;;36996:11:0;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;36984:23;;37026;37052:16;37069:3;37052:21;;;;;;;;-1:-1:-1;;;37052:21:0;;;;;;;;;;;;;;;37026:47;;37117:188;37154:5;:20;;37175:3;37154:25;;;;;;;;-1:-1:-1;;;37154:25:0;;;;;;;;;;;;;;;;;;37117:188;;;;;;;;37154:25;;;;;;;37117:188;;-1:-1:-1;;;;;37117:188:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;37117:188:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;37117:188:0;;;;;;;;;;-1:-1:-1;;;37117:188:0;;;;;;;;;;;;;;;-1:-1:-1;;;37117:188:0;;;;;;;;;;;-1:-1:-1;37202:11:0;;-1:-1:-1;;;;;37117:188:0;37236:16;;37253:1;37236:19;;;;;-1:-1:-1;;;37236:19:0;;;;;;;;;;;;;;;37278:8;37117:14;:188::i;:::-;37092:19;37112:1;37092:22;;;;;;-1:-1:-1;;;37092:22:0;;;;;;;;;;;;;;:213;;;;;37426:42;37445:19;37465:1;37445:22;;;;;;-1:-1:-1;;;37445:22:0;;;;;;;;;;;;;;;37426:18;:42::i;:::-;37384:5;:18;;;:84;;;;:::i;:::-;37326:5;:16;;37343:3;37326:21;;;;;;;;-1:-1:-1;;;37326:21:0;;;;;;;;;;;;;;;;;;:142;;-1:-1:-1;;;;;37326:142:0;;;-1:-1:-1;;;37326:142:0;;;;;;;;;-1:-1:-1;;36936:548:0;36916:3;;;;:::i;:::-;;;;36887:608;;;;37579:74;37596:16;37614:8;;37579:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37624:19;37645:7;37579:74;;;;;;;;;;:::i;:::-;37566:87;;37686:18;37672:10;:32;;37664:68;;;;-1:-1:-1;;;37664:68:0;;18368:2:1;37664:68:0;;;18350:21:1;18407:2;18387:18;;;18380:30;-1:-1:-1;;;18426:18:1;;;18419:53;18489:18;;37664:68:0;18340:173:1;37664:68:0;37764:1;37751:10;:14;37743:47;;;;-1:-1:-1;;;37743:47:0;;22327:2:1;37743:47:0;;;22309:21:1;22366:2;22346:18;;;22339:30;-1:-1:-1;;;22385:18:1;;;22378:50;22445:18;;37743:47:0;22299:170:1;37743:47:0;36288:1510;;;;;;;;;;;;;:::o;63640:330::-;63772:13;63787:9;63815:18;63835:11;63850:22;63863:8;63850:12;:22::i;:::-;63814:58;;;;63887:29;63898:1;63901:3;63906:7;:9;;;63887:10;:29::i;:::-;63948:14;;63883:33;;-1:-1:-1;63936:8:0;63883:33;63936:4;:8;:::i;:::-;63935:27;;;;:::i;:::-;63927:35;;63640:330;;;;;;;:::o;43884:2030::-;44162:17;44194:24;44233:33;44352:36;44391:5;:16;;44352:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;44352:55:0;;;;;-1:-1:-1;;;44352:55:0;;;;;;;;;;;;;;;;;;;;;;;;;44471:21;44532:139;44559:16;44590:7;44532:139;;;;;;;;;;:::i;:::-;44612:14;44641:5;:19;;;44532:12;:139::i;:::-;44503:168;;;;;;;;44701:9;44684:5;:13;;;:26;;;;;;;:::i;:::-;;;;-1:-1:-1;44775:16:0;;-1:-1:-1;44794:68:0;44811:5;44852:9;44818:31;44835:14;44818;;:31;:::i;44794:68::-;44889:23;;44775:87;;-1:-1:-1;44889:23:0;-1:-1:-1;;;;;44933:18:0;;;;;-1:-1:-1;;;44933:18:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44933:18:0;;44923:28;;44995:3;-1:-1:-1;;;;;44981:18:0;;;;;-1:-1:-1;;;44981:18:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44981:18:0;;44962:37;;45015:9;45010:897;45034:3;45030:1;:7;45010:897;;;45128:17;45201:7;:14;;;45184:13;45149:16;45166:1;45149:19;;;;;;-1:-1:-1;;;45149:19:0;;;;;;;;;;;;;;;:32;;;-1:-1:-1;;;;;45149:48:0;;;;;:::i;:::-;45148:67;;;;:::i;:::-;45128:87;;45250:1;45238:9;:13;45230:37;;;;-1:-1:-1;;;45230:37:0;;21635:2:1;45230:37:0;;;21617:21:1;21674:2;21654:18;;;21647:30;-1:-1:-1;;;21693:18:1;;;21686:41;21744:18;;45230:37:0;21607:161:1;45230:37:0;45282:14;45295:1;45282:14;;:::i;:::-;;;45332:20;;45353:1;45332:23;;;;;-1:-1:-1;;;45332:23:0;;;;;;;;;;;;;;;45319:9;:36;;45311:69;;;;-1:-1:-1;;;45311:69:0;;19417:2:1;45311:69:0;;;19399:21:1;19456:2;19436:18;;;19429:30;-1:-1:-1;;;19475:18:1;;;19468:50;19535:18;;45311:69:0;19389:170:1;45311:69:0;45535:29;45554:9;45535:18;:29::i;:::-;45483:16;45500:1;45483:19;;;;;;-1:-1:-1;;;45483:19:0;;;;;;;;;;;;;;;:32;;;:81;;;;:::i;:::-;45431:5;:16;;45448:1;45431:19;;;;;;-1:-1:-1;;;45431:19:0;;;;;;;;;;;;;;;;:32;;;:133;;;;;-1:-1:-1;;;;;45431:133:0;;;;;-1:-1:-1;;;;;45431:133:0;;;;;;45615:30;45648:5;:20;;45669:1;45648:23;;;;;;-1:-1:-1;;;45648:23:0;;;;;;;;;;;;;;;;;;45615:56;;;;;;;;45648:23;;;;;;;45615:56;;-1:-1:-1;;;;;45615:56:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;45615:56:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;45615:56:0;;;;;;;;;;-1:-1:-1;;;45615:56:0;;;;;;;;;;;;;;;-1:-1:-1;;;45615:56:0;;;;;;;;;;;;;;;45723:9;45734:8;:13;;;45687:16;45704:1;45687:19;;;;;;-1:-1:-1;;;45687:19:0;;;;;;;;;;;;;;45708:7;45716:1;45708:10;;;;;;-1:-1:-1;;;45708:10:0;;;;;;;;;;;;;;45686:62;-1:-1:-1;;;;;45686:62:0;-1:-1:-1;;;;;45686:62:0;;;;;;;;;;45816:79;45832:9;45843:8;45853:16;45870:1;45853:19;;;;;;-1:-1:-1;;;45853:19:0;;;;;;;;;;;;;;;45874:10;45886:8;45816:15;:79::i;:::-;45010:897;;45039:3;;;;;:::i;:::-;;;;45010:897;;;;43884:2030;;;;;;;;;;;;;;:::o;53688:206::-;53807:16;53882:4;53863:5;:15;;;53853:7;:25;;;;:::i;:::-;53852:34;;;;:::i;:::-;53841:45;53688:206;-1:-1:-1;;;53688:206:0:o;51446:2060::-;51663:14;51659:27;;51679:7;;51659:27;51760:20;;;;-1:-1:-1;;;;;51760:34:0;51756:1743;;51818:14;;51811:58;;-1:-1:-1;;;;;51811:35:0;51847:10;51859:9;51811:35;:58::i;:::-;51756:1743;;;51964:9;:18;;;51960:1539;;;52020:20;;;;52098:14;;51999:207;;-1:-1:-1;;;51999:207:0;;-1:-1:-1;;;;;16569:15:1;;;51999:207:0;;;16551:34:1;16621:15;;;16601:18;;;16594:43;16653:18;;;16646:34;;;16696:18;;;16689:34;;;52187:4:0;16739:19:1;;;16732:51;51999::0;;;;;16485:19:1;;51999:207:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51960:1539;;;52338:14;;52364:20;;;;52331:54;;-1:-1:-1;;;52331:54:0;;-1:-1:-1;;;;;15836:32:1;;;52331:54:0;;;15818:51:1;52312:16:0;;52331:32;;;;;;;15791:18:1;;52331:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52312:73;;52477:9;52465:8;:21;52461:1027;;52528:20;;;;52617:14;;52507:175;;-1:-1:-1;;;52507:175:0;;-1:-1:-1;;;;;16138:15:1;;;52507:175:0;;;16120:34:1;16190:15;;;16170:18;;;16163:43;16222:18;;;16215:34;;;52507:54:0;;;;;16055:18:1;;52507:175:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52461:1027;;;52952:11;;52897:24;;52967:1;;52924:40;;:9;;-1:-1:-1;;;;;52924:40:0;:27;:40::i;:::-;:44;;;;:::i;:::-;52897:71;-1:-1:-1;52987:23:0;53034:179;53106:8;53075:28;53094:9;52897:71;53075:28;:::i;:::-;:39;;;;:::i;:::-;53162:28;53181:8;53162:18;:28::i;:::-;53141:5;:18;;;:49;;;;:::i;:::-;-1:-1:-1;;;;;53034:179:0;:14;:179::i;:::-;53255:20;;;;53341:14;;53234:238;;-1:-1:-1;;;53234:238:0;;-1:-1:-1;;;;;16569:15:1;;;53234:238:0;;;16551:34:1;16621:15;;;16601:18;;;16594:43;16653:18;;;16646:34;;;16696:18;;;16689:34;;;53341:14:0;16739:19:1;;;16732:51;52987:226:0;;-1:-1:-1;53234:51:0;;;;16485:19:1;;53234:238:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52461:1027;;;51960:1539;;51446:2060;;;;;:::o;19117:184::-;19174:7;-1:-1:-1;;;19202:5:0;:14;19194:67;;;;-1:-1:-1;;;19194:67:0;;19766:2:1;19194:67:0;;;19748:21:1;19805:2;19785:18;;;19778:30;19844:34;19824:18;;;19817:62;-1:-1:-1;;;19895:18:1;;;19888:37;19942:19;;19194:67:0;19738:229:1;19194:67:0;-1:-1:-1;19287:5:0;19117:184;;;;:::o;65557:457::-;65722:15;;65659:18;;65679:11;;65722:15;-1:-1:-1;;;;;65752:18:0;;;;;-1:-1:-1;;;65752:18:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65752:18:0;-1:-1:-1;65748:22:0;-1:-1:-1;65781:9:0;;65801:206;65825:3;65821:1;:7;65801:206;;;65850:24;65877:8;65886:1;65877:11;;;;;;-1:-1:-1;;;65877:11:0;;;;;;;;;;;;;;;65850:38;;65946:3;65930:6;:12;;;65908:6;:19;;;:34;;;;:::i;:::-;65907:42;;;;:::i;:::-;-1:-1:-1;;;;;65903:46:0;;;65971:1;65964;65966;65964:4;;;;;;-1:-1:-1;;;65964:4:0;;;;;;;;;;;;;;;;;;:8;65987;65994:1;65987:8;;:::i;:::-;;;65801:206;65830:3;;;;;:::i;:::-;;;;65801:206;;;;65557:457;;;;;:::o;67227:809::-;67387:9;;67351;;67413;67409:23;;67431:1;67424:8;;;;;67409:23;67445:10;67458:8;67463:3;67458:2;:8;:::i;:::-;67445:21;;67477:13;67505:4;67501:8;;67527:9;67522:458;67546:3;67542:1;:7;67522:458;;;67584:1;67571:10;67600:98;67624:3;67620:1;:7;67600:98;;;67678:3;67670:2;67673:1;67670:5;;;;;;-1:-1:-1;;;67670:5:0;;;;;;;;;;;;;;;:11;;;;:::i;:::-;67659:6;67664:1;67659:2;:6;:::i;:::-;67658:24;;;;:::i;:::-;67653:29;-1:-1:-1;67629:3:0;;;;:::i;:::-;;;;67600:98;;;-1:-1:-1;67720:1:0;;-1:-1:-1;67878:2:0;67867:7;:3;67873:1;67867:7;:::i;:::-;67866:14;;;;:::i;:::-;33667:3;67846:1;67826:16;33667:3;67826:2;:16;:::i;:::-;67825:22;;;;:::i;:::-;67824:38;;;;:::i;:::-;:57;;;;:::i;:::-;67801:1;67788:8;67793:3;67788:2;:8;:::i;:::-;33667:3;67760:9;67765:4;67760:2;:9;:::i;:::-;67759:25;;;;:::i;:::-;:38;;;;:::i;:::-;67758:44;;;;:::i;:::-;67757:125;;;;:::i;:::-;67736:146;;67901:23;67915:1;67918:5;67901:13;:23::i;:::-;67897:72;;;67945:8;;;;;;;67897:72;-1:-1:-1;67551:3:0;;;;:::i;:::-;;;;67522:458;;;-1:-1:-1;67992:36:0;;-1:-1:-1;;;67992:36:0;;19062:2:1;67992:36:0;;;19044:21:1;19101:2;19081:18;;;19074:30;19140:28;19120:18;;;19113:56;19186:18;;67992:36:0;19034:176:1;66351:406:0;66531:9;;66562:4;;66491:13;;66597:153;66621:3;66617:1;:7;66597:153;;;66667:4;66651:2;66654:1;66651:5;;;;;;-1:-1:-1;;;66651:5:0;;;;;;;;;;;;;;;66659:4;66651:12;;;;:::i;:::-;66650:21;;;;:::i;:::-;66646:25;;66694:7;:11;;;-1:-1:-1;;;;;66690:15:0;:1;:15;:34;;;-1:-1:-1;66713:11:0;;-1:-1:-1;;;;;66709:15:0;;;66690:34;66686:52;;;66733:5;66726:12;;;;;;;66686:52;66626:3;;;;:::i;:::-;;;;66597:153;;;;66351:406;;;;;;;:::o;64578:749::-;64751:18;64842:14;64859:31;64870:2;64874:4;64880:7;:9;;;64859:10;:31::i;:::-;64996:14;;64842:48;;-1:-1:-1;64992:159:0;;65045:11;65054:2;65045:6;:11;:::i;:::-;65032:24;;64992:159;;;65137:2;65121:11;65137:2;65121:6;:11;:::i;:::-;65103:14;;:30;;;;:::i;:::-;65102:37;;;;:::i;:::-;65089:50;;64992:159;65218:14;;:19;-1:-1:-1;65214:106:0;;;65303:4;65283:7;:16;;;65270:10;:29;;;;:::i;:::-;65269:38;;;;:::i;:::-;65254:54;;;;:::i;:::-;;;65214:106;64578:749;;;;;;;:::o;49336:1847::-;49604:18;;;;49512:25;;-1:-1:-1;;;;;49604:32:0;49600:325;;49654:16;49693:190;49751:10;49792:4;49820:7;:12;;;49855:9;49693:35;:190::i;:::-;-1:-1:-1;49653:230:0;-1:-1:-1;49898:15:0;;-1:-1:-1;49898:15:0;49600:325;50043:16;50102:155;50152:10;50177:7;:18;;;50210:7;:12;;;50237:9;50102:35;:155::i;:::-;50352:16;;;;50070:187;;-1:-1:-1;50070:187:0;-1:-1:-1;50348:323:0;;;50443:18;;;;50493:12;;50422:169;;-1:-1:-1;;;50422:169:0;;-1:-1:-1;;;;;17287:32:1;;;50422:169:0;;;17269:51:1;17336:18;;;17329:34;;;50568:4:0;17379:18:1;;;17372:50;50385:17:0;;50422:48;;;;;;;17242:18:1;;50422:169:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50385:206;;50615:44;50630:9;50641:17;50615:14;:44::i;:::-;50608:51;;;;;;50348:323;50841:9;50820:17;:30;50812:70;;;;-1:-1:-1;;;50812:70:0;;21279:2:1;50812:70:0;;;21261:21:1;21318:2;21298:18;;;21291:30;21357:29;21337:18;;;21330:57;21404:18;;50812:70:0;21251:177:1;50812:70:0;50895:24;50922:41;:9;50950:12;50922:27;:41::i;:::-;50895:68;;50991:16;50980:8;:27;50976:200;;;51024:13;51052:20;51071:1;51052:16;:20;:::i;:::-;51040:33;;:8;:33;:::i;:::-;51109:18;;;;51137:12;;51088:76;;-1:-1:-1;;;51088:76:0;;-1:-1:-1;;;;;17287:32:1;;;51088:76:0;;;17269:51:1;17336:18;;;17329:34;;;51137:12:0;17379:18:1;;;17372:50;51024:49:0;;-1:-1:-1;51088:48:0;;;;17242:18:1;;51088:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;50976:200;;49336:1847;;;;;;;;;:::o;60899:473::-;61173:14;;61138:20;;61075:18;;61173:20;-1:-1:-1;61169:107:0;;;61259:4;61239:7;:16;;;61226:10;:29;;;;:::i;:::-;61225:38;;;;:::i;:::-;61210:54;;;;:::i;:::-;;;61169:107;61298:32;:10;61321:8;61298:22;:32::i;:::-;61286:44;-1:-1:-1;61341:23:0;61286:44;61341:23;;:::i;:::-;;;60899:473;;;;;;;:::o;68921:968::-;69111:9;;69075;;69159:3;69152:4;:10;;;69131:49;;;;-1:-1:-1;;;69131:49:0;;18720:2:1;69131:49:0;;;18702:21:1;18759:2;18739:18;;;18732:30;-1:-1:-1;;;18778:18:1;;;18771:43;18831:18;;69131:49:0;18692:163:1;69131:49:0;69194:12;;;;69238:8;69243:3;69238:2;:8;:::i;:::-;69248;69193:64;;;;;;69275:9;69270:178;69294:3;69290:1;:7;69270:178;;;69328:4;69323:9;;:1;:9;69319:118;;69361:2;69364:1;69361:5;;;;;;-1:-1:-1;;;69361:5:0;;;;;;;;;;;;;;;69353:13;;;;;:::i;:::-;;;69417:3;69409:2;69412:1;69409:5;;;;;;-1:-1:-1;;;69409:5:0;;;;;;;;;;;;;;;:11;;;;:::i;:::-;69391:13;69396:8;69391:2;:13;:::i;:::-;69390:31;;;;:::i;:::-;69385:36;;69319:118;69299:3;;;;:::i;:::-;;;;69270:178;;;-1:-1:-1;69460:9:0;69513:3;69507:2;33667:3;69475:13;69480:8;69475:2;:13;:::i;:::-;69474:29;;;;:::i;:::-;69473:36;;;;:::i;:::-;69472:44;;;;:::i;:::-;69460:56;-1:-1:-1;69527:9:0;69573:2;69552:16;33667:3;69573:2;69552:16;:::i;:::-;69540:29;;:8;:29;:::i;:::-;69539:36;;;;:::i;:::-;69527:48;;69586:9;69620:4;69616:1;:8;69612:218;;;69645:8;69649:4;69645:1;:8;:::i;:::-;69641:12;-1:-1:-1;69708:1:0;69641:12;69673:27;69693:5;69697:1;69693;:5;:::i;:::-;69684:4;69687:1;69684;:4;:::i;:::-;69683:16;;;;:::i;:::-;69673:9;:27::i;:::-;:31;;;;:::i;:::-;69672:37;;;;:::i;:::-;:41;;69712:1;69672:41;:::i;:::-;69668:45;;69612:218;;;69750:8;69757:1;69750:4;:8;:::i;:::-;69746:12;-1:-1:-1;69813:1:0;69746:12;69778:27;69798:5;69802:1;69798;:5;:::i;69778:27::-;:31;;;;:::i;:::-;69777:37;;;;:::i;:::-;:41;;69817:1;69777:41;:::i;:::-;69773:45;;69612:218;69850:3;69846:1;:7;69842:39;;;69855:26;;-1:-1:-1;;;69855:26:0;;20527:2:1;69855:26:0;;;20509:21:1;20566:2;20546:18;;;20539:30;-1:-1:-1;;;20585:18:1;;;20578:46;20641:18;;69855:26:0;20499:166:1;69842:39:0;68921:968;;;;;;;;;;;;;:::o;29450:195::-;29517:7;29636:1;29618:14;25694:4;29618:1;:14;:::i;29450:195::-;;;;;:::o;58718:612::-;58881:10;;;58944:9;58950:3;58944;:9;:::i;:::-;58927:26;;59019:3;59002:7;:14;;;:20;58998:99;;;59080:4;59060:7;:16;;;59051:6;:25;;;;:::i;:::-;59050:34;;;;:::i;:::-;59039:46;;;;:::i;:::-;;;58998:99;59171:4;59150:17;59159:8;59150:6;:17;:::i;:::-;59149:26;;;;:::i;:::-;59133:42;-1:-1:-1;59133:42:0;59191:12;59197:6;59191:3;:12;:::i;:::-;:28;;;;:::i;:::-;59301:14;;59186:33;;-1:-1:-1;59319:3:0;;59285:30;;:13;:30;:::i;:::-;59284:38;;;;:::i;:::-;59268:54;;58718:612;;;;;;;;:::o;46006:583::-;46263:6;46194:21;;46343:29;46356:6;46364:7;46343:12;:29::i;:::-;46323:49;;;46395:4;46387:5;:12;46383:98;;;46464:4;46444:7;:16;;;46435:6;:25;;;;:::i;:::-;46434:34;;;;:::i;:::-;46416:53;;;;:::i;:::-;;;46383:98;46503:41;:13;46529:14;46503:25;:41::i;:::-;46491:53;-1:-1:-1;46555:26:0;46491:53;46555:26;;:::i;:::-;;;46006:583;;;;;;;;:::o;15596:177::-;15706:58;;-1:-1:-1;;;;;16986:32:1;;15706:58:0;;;16968:51:1;17035:18;;;17028:34;;;15679:86:0;;15699:5;;-1:-1:-1;;;15729:23:0;16941:18:1;;15706:58:0;;;;-1:-1:-1;;15706:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;15706:58:0;-1:-1:-1;;;;;;15706:58:0;;;;;;;;;;15679:19;:86::i;:::-;15596:177;;;:::o;31542:211::-;31618:9;31740:5;31721:15;26102:3;31721:1;:15;:::i;32072:106::-;32130:7;32161:1;32157;:5;:13;;32169:1;32157:13;;;-1:-1:-1;32165:1:0;32072:106;-1:-1:-1;32072:106:0:o;68315:225::-;68389:4;68419:2;68410:6;:11;68406:127;;;68462:1;68446:11;68455:2;68446:6;:11;:::i;:::-;68445:18;;68438:25;;;;68406:127;68520:1;68504:11;68509:6;68504:2;:11;:::i;24819:473::-;25057:37;;-1:-1:-1;;;25057:37:0;;-1:-1:-1;;;;;15836:32:1;;;25057:37:0;;;15818:51:1;24979:19:0;;;;;;25057:25;;;;;;15791:18:1;;25057:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;25037:57;-1:-1:-1;25105:59:0;-1:-1:-1;;;;;25105:32:0;;25138:7;25147:10;25159:4;25105:32;:59::i;:::-;25194:37;;-1:-1:-1;;;25194:37:0;;-1:-1:-1;;;;;15836:32:1;;;25194:37:0;;;15818:51:1;25194:25:0;;;;;15791:18:1;;25194:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;25175:56;-1:-1:-1;25256:28:0;25275:9;25175:56;25256:28;:::i;27320:135::-;27386:7;27413:34;27430:1;27433;25694:4;27413:16;:34::i;3602:1273::-;3650:9;3676:6;3672:1196;;-1:-1:-1;3691:1:0;3684:8;;3672:1196;3736:1;3764;-1:-1:-1;;;3784:41:0;;3780:119;;3853:3;3846:10;;;;;3881:2;3875:8;3780:119;3923:19;3917:2;:25;3913:102;;3970:2;3963:9;;;;;3997:2;3991:8;3913:102;4039:11;4033:2;:17;4029:94;;4078:2;4071:9;;;;;4105:2;4099:8;4029:94;4147:7;4141:2;:13;4137:89;;4182:2;4175:9;;;;;4209:1;4203:7;4137:89;4250:5;4244:2;:11;4240:86;;4283:1;4276:8;;;;;4309:1;4303:7;4240:86;4350:4;4344:2;:10;4340:85;;4382:1;4375:8;;;;;4408:1;4402:7;4340:85;4449:3;4443:2;:9;4439:57;;4479:1;4473:7;4439:57;4529:1;4519:5;4523:1;4519;:5;:::i;:::-;4515:9;;:1;:9;:::i;:::-;4514:16;;;-1:-1:-1;4564:1:0;4554:5;4514:16;4554:1;:5;:::i;:::-;4550:9;;:1;:9;:::i;:::-;4549:16;;;-1:-1:-1;4599:1:0;4589:5;4549:16;4589:1;:5;:::i;:::-;4585:9;;:1;:9;:::i;:::-;4584:16;;;-1:-1:-1;4634:1:0;4624:5;4584:16;4624:1;:5;:::i;:::-;4620:9;;:1;:9;:::i;:::-;4619:16;;;-1:-1:-1;4669:1:0;4659:5;4619:16;4659:1;:5;:::i;:::-;4655:9;;:1;:9;:::i;:::-;4654:16;;;-1:-1:-1;4704:1:0;4694:5;4654:16;4694:1;:5;:::i;:::-;4690:9;;:1;:9;:::i;:::-;4689:16;;;-1:-1:-1;4739:1:0;4729:5;4689:16;4729:1;:5;:::i;:::-;4725:9;;:1;:9;:::i;:::-;4724:16;;;-1:-1:-1;4792:10:0;4805:5;4724:16;4805:1;:5;:::i;:::-;4792:18;;4844:2;4840:1;:6;:15;;4853:2;4840:15;;;4849:1;4840:15;4825:31;;;;;;;18030:761;18454:23;18480:69;18508:4;18480:69;;;;;;;;;;;;;;;;;18488:5;-1:-1:-1;;;;;18480:27:0;;;:69;;;;;:::i;:::-;18564:17;;18454:95;;-1:-1:-1;18564:21:0;18560:224;;18706:10;18695:30;;;;;;;;;;;;:::i;:::-;18687:85;;;;-1:-1:-1;;;18687:85:0;;23384:2:1;18687:85:0;;;23366:21:1;23423:2;23403:18;;;23396:30;23462:34;23442:18;;;23435:62;-1:-1:-1;;;23513:18:1;;;23506:40;23563:19;;18687:85:0;23356:232:1;15781:205:0;15909:68;;-1:-1:-1;;;;;16138:15:1;;;15909:68:0;;;16120:34:1;16190:15;;16170:18;;;16163:43;16222:18;;;16215:34;;;15882:96:0;;15902:5;;-1:-1:-1;;;15932:27:0;16055:18:1;;15909:68:0;16037:218:1;15882:96:0;15781:205;;;;:::o;27928:286::-;28048:7;28201:5;28192;28196:1;28192;:5;:::i;:::-;28191:15;;;;:::i;11196:195::-;11299:12;11331:52;11353:6;11361:4;11367:1;11370:12;11299;8645:20;;12492:60;;;;-1:-1:-1;;;12492:60:0;;23026:2:1;12492:60:0;;;23008:21:1;23065:2;23045:18;;;23038:30;23104:31;23084:18;;;23077:59;23153:18;;12492:60:0;22998:179:1;12492:60:0;12626:12;12640:23;12667:6;-1:-1:-1;;;;;12667:11:0;12687:5;12695:4;12667:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12625:75;;;;12718:52;12736:7;12745:10;12757:12;12718:17;:52::i;:::-;12711:59;12248:530;-1:-1:-1;;;;;;;12248:530:0:o;14788:742::-;14903:12;14932:7;14928:595;;;-1:-1:-1;14963:10:0;14956:17;;14928:595;15077:17;;:21;15073:439;;15340:10;15334:17;15401:15;15388:10;15384:2;15380:19;15373:44;15288:148;15483:12;15476:20;;-1:-1:-1;;;15476:20:0;;;;;;;;:::i;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:2;;177:1;174;167:12;192:758;;309:3;302:4;294:6;290:17;286:27;276:2;;331:5;324;317:20;276:2;371:6;358:20;397:4;421:70;437:53;487:2;437:53;:::i;:::-;421:70;:::i;:::-;525:15;;;556:12;;;;588:15;;;622:4;657:11;;;645:24;;641:33;;638:42;-1:-1:-1;635:2:1;;;697:5;690;683:20;635:2;723:5;737:184;751:2;748:1;745:9;737:184;;;808:38;842:3;837;808:38;:::i;:::-;796:51;;867:12;;;;899;;;;769:1;762:9;737:184;;;-1:-1:-1;939:5:1;;266:684;-1:-1:-1;;;;;;;;266:684:1:o;955:398::-;;;1082:3;1075:4;1067:6;1063:17;1059:27;1049:2;;1107:8;1097;1090:26;1049:2;-1:-1:-1;1137:20:1;;-1:-1:-1;;;;;1169:30:1;;1166:2;;;1219:8;1209;1202:26;1166:2;1263:4;1255:6;1251:17;1239:29;;1326:3;1319:4;1311;1303:6;1299:17;1291:6;1287:30;1283:41;1280:50;1277:2;;;1343:1;1340;1333:12;1277:2;1039:314;;;;;:::o;1358:704::-;;1465:3;1458:4;1450:6;1446:17;1442:27;1432:2;;1487:5;1480;1473:20;1432:2;1527:6;1514:20;1553:4;1577:70;1593:53;1643:2;1593:53;:::i;1577:70::-;1681:15;;;1712:12;;;;1744:15;;;1790:11;;;1778:24;;1774:33;;1771:42;-1:-1:-1;1768:2:1;;;1830:5;1823;1816:20;1768:2;1856:5;1870:163;1884:2;1881:1;1878:9;1870:163;;;1941:17;;1929:30;;1979:12;;;;2011;;;;1902:1;1895:9;1870:163;;;-1:-1:-1;2051:5:1;;1422:640;-1:-1:-1;;;;;;;1422:640:1:o;2067:706::-;;2172:3;2165:4;2157:6;2153:17;2149:27;2139:2;;2194:5;2187;2180:20;2139:2;2234:6;2221:20;2260:4;2284:70;2300:53;2350:2;2300:53;:::i;2284:70::-;2388:15;;;2419:12;;;;2451:15;;;2497:11;;;2485:24;;2481:33;;2478:42;-1:-1:-1;2475:2:1;;;2537:5;2530;2523:20;2475:2;2563:5;2577:167;2591:2;2588:1;2585:9;2577:167;;;2648:21;2665:3;2648:21;:::i;:::-;2636:34;;2690:12;;;;2722;;;;2609:1;2602:9;2577:167;;2778:161;;2881:2;2872:6;2867:3;2863:16;2859:25;2856:2;;;2901:5;2894;2887:20;2944:304;;3049:4;3037:9;3032:3;3028:19;3024:30;3021:2;;;3071:5;3064;3057:20;3021:2;3097:21;3113:4;3097:21;:::i;:::-;3088:30;;3141:29;3160:9;3141:29;:::i;:::-;3134:5;3127:44;3203:38;3237:2;3226:9;3222:18;3203:38;:::i;:::-;3198:2;3191:5;3187:14;3180:62;3011:237;;;;:::o;3253:172::-;;3366:3;3357:6;3352:3;3348:16;3344:26;3341:2;;;3387:5;3380;3373:20;3430:452;;3540:4;3528:9;3523:3;3519:19;3515:30;3512:2;;;3562:5;3555;3548:20;3512:2;3588:21;3604:4;3588:21;:::i;:::-;3579:30;;3645:9;3632:23;3625:5;3618:38;3716:2;3705:9;3701:18;3688:32;3683:2;3676:5;3672:14;3665:56;3753:53;3802:3;3797:2;3786:9;3782:18;3753:53;:::i;:::-;3748:2;3741:5;3737:14;3730:77;3869:4;3858:9;3854:20;3841:34;3834:4;3827:5;3823:16;3816:60;3502:380;;;;:::o;3887:188::-;3955:20;;-1:-1:-1;;;;;4004:46:1;;3994:57;;3984:2;;4065:1;4062;4055:12;4080:156;4146:20;;4206:4;4195:16;;4185:27;;4175:2;;4226:1;4223;4216:12;4241:1024;;;;;4535:3;4523:9;4514:7;4510:23;4506:33;4503:2;;;4557:6;4549;4542:22;4503:2;4602:9;4589:23;-1:-1:-1;;;;;4672:2:1;4664:6;4661:14;4658:2;;;4693:6;4685;4678:22;4658:2;4721:71;4784:7;4775:6;4764:9;4760:22;4721:71;:::i;:::-;4711:81;;4845:2;4834:9;4830:18;4817:32;4801:48;;4874:2;4864:8;4861:16;4858:2;;;4895:6;4887;4880:22;4858:2;4923:61;4976:7;4965:8;4954:9;4950:24;4923:61;:::i;:::-;4913:71;;5037:2;5026:9;5022:18;5009:32;4993:48;;5066:2;5056:8;5053:16;5050:2;;;5087:6;5079;5072:22;5050:2;;5115:63;5170:7;5159:8;5148:9;5144:24;5115:63;:::i;:::-;5105:73;;;5197:62;5251:7;5246:2;5235:9;5231:18;5197:62;:::i;:::-;5187:72;;4493:772;;;;;;;:::o;5270:1093::-;;;;;;5581:3;5569:9;5560:7;5556:23;5552:33;5549:2;;;5603:6;5595;5588:22;5549:2;5648:9;5635:23;-1:-1:-1;;;;;5718:2:1;5710:6;5707:14;5704:2;;;5739:6;5731;5724:22;5704:2;5767:71;5830:7;5821:6;5810:9;5806:22;5767:71;:::i;:::-;5757:81;;5891:2;5880:9;5876:18;5863:32;5847:48;;5920:2;5910:8;5907:16;5904:2;;;5941:6;5933;5926:22;5904:2;5969:61;6022:7;6011:8;6000:9;5996:24;5969:61;:::i;:::-;5959:71;;6083:2;6072:9;6068:18;6055:32;6039:48;;6112:2;6102:8;6099:16;6096:2;;;6133:6;6125;6118:22;6096:2;;6161:63;6216:7;6205:8;6194:9;6190:24;6161:63;:::i;:::-;6151:73;;;6243:62;6297:7;6292:2;6281:9;6277:18;6243:62;:::i;:::-;5539:824;;;;-1:-1:-1;5539:824:1;;6352:3;6337:19;6324:33;;5539:824;-1:-1:-1;;5539:824:1:o;6368:535::-;;;6580:3;6568:9;6559:7;6555:23;6551:33;6548:2;;;6602:6;6594;6587:22;6548:2;6647:9;6634:23;-1:-1:-1;;;;;6672:6:1;6669:30;6666:2;;;6717:6;6709;6702:22;6666:2;6745:71;6808:7;6799:6;6788:9;6784:22;6745:71;:::i;:::-;6735:81;;;6835:62;6889:7;6884:2;6873:9;6869:18;6835:62;:::i;:::-;6825:72;;6538:365;;;;;:::o;6908:673::-;;;;;7152:3;7140:9;7131:7;7127:23;7123:33;7120:2;;;7174:6;7166;7159:22;7120:2;7219:9;7206:23;-1:-1:-1;;;;;7244:6:1;7241:30;7238:2;;;7289:6;7281;7274:22;7238:2;7317:71;7380:7;7371:6;7360:9;7356:22;7317:71;:::i;:::-;7307:81;;;7407:36;7439:2;7428:9;7424:18;7407:36;:::i;:::-;7397:46;;7490:2;7479:9;7475:18;7462:32;7452:42;;7513:62;7567:7;7562:2;7551:9;7547:18;7513:62;:::i;7586:742::-;;;;;;7847:3;7835:9;7826:7;7822:23;7818:33;7815:2;;;7869:6;7861;7854:22;7815:2;7914:9;7901:23;-1:-1:-1;;;;;7939:6:1;7936:30;7933:2;;;7984:6;7976;7969:22;7933:2;8012:71;8075:7;8066:6;8055:9;8051:22;8012:71;:::i;:::-;8002:81;;;8102:36;8134:2;8123:9;8119:18;8102:36;:::i;:::-;8092:46;;8185:2;8174:9;8170:18;8157:32;8147:42;;8208:62;8262:7;8257:2;8246:9;8242:18;8208:62;:::i;8333:813::-;;;;;;;8609:3;8597:9;8588:7;8584:23;8580:33;8577:2;;;8631:6;8623;8616:22;8577:2;8676:9;8663:23;-1:-1:-1;;;;;8701:6:1;8698:30;8695:2;;;8746:6;8738;8731:22;8695:2;8774:71;8837:7;8828:6;8817:9;8813:22;8774:71;:::i;:::-;8764:81;;;8864:36;8896:2;8885:9;8881:18;8864:36;:::i;:::-;8854:46;;8919:36;8951:2;8940:9;8936:18;8919:36;:::i;:::-;8909:46;;9002:2;8991:9;8987:18;8974:32;8964:42;;9053:3;9042:9;9038:19;9025:33;9015:43;;9077:63;9132:7;9126:3;9115:9;9111:19;9077:63;:::i;:::-;9067:73;;8567:579;;;;;;;;:::o;9151:297::-;;9271:2;9259:9;9250:7;9246:23;9242:32;9239:2;;;9292:6;9284;9277:22;9239:2;9329:9;9323:16;9382:5;9375:13;9368:21;9361:5;9358:32;9348:2;;9409:6;9401;9394:22;9453:253;;9597:3;9585:9;9576:7;9572:23;9568:33;9565:2;;;9619:6;9611;9604:22;9565:2;9647:53;9692:7;9681:9;9647:53;:::i;9711:1110::-;;;;;;;;10021:3;10009:9;10000:7;9996:23;9992:33;9989:2;;;10043:6;10035;10028:22;9989:2;10084:9;10071:23;10061:33;;10113:71;10176:7;10171:2;10160:9;10156:18;10113:71;:::i;:::-;10103:81;;10235:3;10224:9;10220:19;10207:33;-1:-1:-1;;;;;10300:2:1;10292:6;10289:14;10286:2;;;10321:6;10313;10306:22;10286:2;10365:70;10427:7;10418:6;10407:9;10403:22;10365:70;:::i;:::-;10454:8;;-1:-1:-1;10339:96:1;-1:-1:-1;10542:3:1;10527:19;;10514:33;;-1:-1:-1;10559:16:1;;;10556:2;;;10593:6;10585;10578:22;10556:2;;10637:72;10701:7;10690:8;10679:9;10675:24;10637:72;:::i;:::-;9979:842;;;;-1:-1:-1;9979:842:1;;;;;;10810:3;10795:19;;;10782:33;;9979:842;-1:-1:-1;;;;9979:842:1:o;10826:817::-;;;;;;;;11150:3;11138:9;11129:7;11125:23;11121:33;11118:2;;;11172:6;11164;11157:22;11118:2;11213:9;11200:23;11190:33;;11242:71;11305:7;11300:2;11289:9;11285:18;11242:71;:::i;:::-;11232:81;;11332:62;11386:7;11380:3;11369:9;11365:19;11332:62;:::i;:::-;11322:72;;11413:62;11467:7;11461:3;11450:9;11446:19;11413:62;:::i;:::-;11403:72;;11522:3;11511:9;11507:19;11494:33;11484:43;;11574:3;11563:9;11559:19;11546:33;11536:43;;11598:39;11632:3;11621:9;11617:19;11598:39;:::i;:::-;11588:49;;11108:535;;;;;;;;;;:::o;11648:620::-;;;;;;11914:3;11902:9;11893:7;11889:23;11885:33;11882:2;;;11936:6;11928;11921:22;11882:2;11977:9;11964:23;11954:33;;12006:71;12069:7;12064:2;12053:9;12049:18;12006:71;:::i;:::-;11996:81;;12096:62;12150:7;12144:3;12133:9;12129:19;12096:62;:::i;:::-;11872:396;;;;-1:-1:-1;12086:72:1;;12205:3;12190:19;;12177:33;;-1:-1:-1;12257:3:1;12242:19;12229:33;;11872:396;-1:-1:-1;;11872:396:1:o;12273:695::-;;;;;;;12556:3;12544:9;12535:7;12531:23;12527:33;12524:2;;;12578:6;12570;12563:22;12524:2;12619:9;12606:23;12596:33;;12648:71;12711:7;12706:2;12695:9;12691:18;12648:71;:::i;:::-;12638:81;;12738:62;12792:7;12786:3;12775:9;12771:19;12738:62;:::i;:::-;12728:72;;12847:3;12836:9;12832:19;12819:33;12809:43;;12899:3;12888:9;12884:19;12871:33;12861:43;;12923:39;12957:3;12946:9;12942:19;12923:39;:::i;12973:840::-;;;;;;;13250:3;13238:9;13229:7;13225:23;13221:33;13218:2;;;13272:6;13264;13257:22;13218:2;13313:9;13300:23;13290:33;;13342:71;13405:7;13400:2;13389:9;13385:18;13342:71;:::i;:::-;13332:81;;13460:3;13449:9;13445:19;13432:33;13422:43;;13516:3;13505:9;13501:19;13488:33;-1:-1:-1;;;;;13536:6:1;13533:30;13530:2;;;13581:6;13573;13566:22;13530:2;13625:70;13687:7;13678:6;13667:9;13663:22;13625:70;:::i;:::-;13714:8;;-1:-1:-1;13599:96:1;-1:-1:-1;13768:39:1;;-1:-1:-1;13802:3:1;13787:19;;13768:39;:::i;13818:1174::-;;;;;;;;;14143:3;14131:9;14122:7;14118:23;14114:33;14111:2;;;14165:6;14157;14150:22;14111:2;14206:9;14193:23;14183:33;;14235:62;14289:7;14284:2;14273:9;14269:18;14235:62;:::i;:::-;14225:72;;14348:3;14337:9;14333:19;14320:33;-1:-1:-1;;;;;14413:2:1;14405:6;14402:14;14399:2;;;14434:6;14426;14419:22;14399:2;14478:70;14540:7;14531:6;14520:9;14516:22;14478:70;:::i;:::-;14567:8;;-1:-1:-1;14452:96:1;-1:-1:-1;14655:3:1;14640:19;;14627:33;;-1:-1:-1;14672:16:1;;;14669:2;;;14706:6;14698;14691:22;14669:2;;14750:72;14814:7;14803:8;14792:9;14788:24;14750:72;:::i;:::-;14841:8;;-1:-1:-1;14724:98:1;-1:-1:-1;;14923:3:1;14908:19;;14895:33;;-1:-1:-1;14947:39:1;14981:3;14966:19;;14947:39;:::i;:::-;14937:49;;14101:891;;;;;;;;;;;:::o;14997:194::-;;15120:2;15108:9;15099:7;15095:23;15091:32;15088:2;;;15141:6;15133;15126:22;15088:2;-1:-1:-1;15169:16:1;;15078:113;-1:-1:-1;15078:113:1:o;15196:192::-;;15306:2;15294:9;15285:7;15281:23;15277:32;15274:2;;;15327:6;15319;15312:22;15274:2;15355:27;15372:9;15355:27;:::i;15393:274::-;;15560:6;15554:13;15576:53;15622:6;15617:3;15610:4;15602:6;15598:17;15576:53;:::i;:::-;15645:16;;;;;15530:137;-1:-1:-1;;15530:137:1:o;17433:383::-;;17582:2;17571:9;17564:21;17614:6;17608:13;17657:6;17652:2;17641:9;17637:18;17630:34;17673:66;17732:6;17727:2;17716:9;17712:18;17707:2;17699:6;17695:15;17673:66;:::i;:::-;17800:2;17779:15;-1:-1:-1;;17775:29:1;17760:45;;;;17807:2;17756:54;;17554:262;-1:-1:-1;;17554:262:1:o;22474:345::-;22676:2;22658:21;;;22715:2;22695:18;;;22688:30;-1:-1:-1;;;22749:2:1;22734:18;;22727:51;22810:2;22795:18;;22648:171::o;24493:1262::-;;24797:2;24786:9;24782:18;24827:6;24816:9;24809:25;24853:2;24891;24886;24875:9;24871:18;24864:30;24914:6;24949;24943:13;24980:6;24972;24965:22;25018:3;25007:9;25003:19;24996:26;;25057:2;25049:6;25045:15;25031:29;;25078:4;25091:195;25105:6;25102:1;25099:13;25091:195;;;25170:13;;-1:-1:-1;;;;;25166:39:1;25154:52;;25261:15;;;;25226:12;;;;25202:1;25120:9;25091:195;;;-1:-1:-1;;25322:19:1;;;25317:2;25302:18;;25295:47;25392:13;;25414:21;;;25453:12;;;;-1:-1:-1;25490:15:1;;;;25525:4;25538:189;25554:8;25549:3;25546:17;25538:189;;;25623:15;;25609:30;;25661:14;;;;25700:17;;;;25582:1;25573:11;25538:189;;;-1:-1:-1;25744:5:1;;24758:997;-1:-1:-1;;;;;;;;24758:997:1:o;26021:275::-;26092:2;26086:9;26157:2;26138:13;;-1:-1:-1;;26134:27:1;26122:40;;-1:-1:-1;;;;;26177:34:1;;26213:22;;;26174:62;26171:2;;;26239:18;;:::i;:::-;26275:2;26268:22;26066:230;;-1:-1:-1;26066:230:1:o;26301:196::-;;-1:-1:-1;;;;;26396:6:1;26393:30;26390:2;;;26426:18;;:::i;:::-;-1:-1:-1;26486:4:1;26467:17;;;26463:28;;26380:117::o;26502:253::-;;-1:-1:-1;;;;;26631:2:1;26628:1;26624:10;26661:2;26658:1;26654:10;26692:3;26688:2;26684:12;26679:3;26676:21;26673:2;;;26700:18;;:::i;:::-;26736:13;;26550:205;-1:-1:-1;;;;26550:205:1:o;26760:128::-;;26831:1;26827:6;26824:1;26821:13;26818:2;;;26837:18;;:::i;:::-;-1:-1:-1;26873:9:1;;26808:80::o;26893:216::-;;-1:-1:-1;;;;;27020:2:1;27017:1;27013:10;27042:3;27032:2;;27049:18;;:::i;:::-;27087:10;;27083:20;;;;;26939:170;-1:-1:-1;;26939:170:1:o;27114:120::-;;27180:1;27170:2;;27185:18;;:::i;:::-;-1:-1:-1;27219:9:1;;27160:74::o;27239:453::-;27335:6;27358:5;27372:314;27421:1;27458:2;27448:8;27445:16;27435:2;;27465:5;;;27435:2;27506:4;27501:3;27497:14;27491:4;27488:24;27485:2;;;27515:18;;:::i;:::-;27565:2;27555:8;27551:17;27548:2;;;27580:16;;;;27548:2;27659:17;;;;;27619:15;;27372:314;;;27316:376;;;;;;;:::o;27697:148::-;;27784:55;-1:-1:-1;;27825:4:1;27811:19;;27805:4;27850:922;27934:8;27924:2;;-1:-1:-1;27975:1:1;27989:5;;27924:2;28023:4;28013:2;;-1:-1:-1;28060:1:1;28074:5;;28013:2;28105:4;28123:1;28118:59;;;;28191:1;28186:183;;;;28098:271;;28118:59;28148:1;28139:10;;28162:5;;;28186:183;28223:3;28213:8;28210:17;28207:2;;;28230:18;;:::i;:::-;28286:1;28276:8;28272:16;28263:25;;28314:3;28307:5;28304:14;28301:2;;;28321:18;;:::i;:::-;28354:5;;;28098:271;;28453:2;28443:8;28440:16;28434:3;28428:4;28425:13;28421:36;28415:2;28405:8;28402:16;28397:2;28391:4;28388:12;28384:35;28381:77;28378:2;;;-1:-1:-1;28490:19:1;;;28525:14;;;28522:2;;;28542:18;;:::i;:::-;28575:5;;28378:2;28622:42;28660:3;28650:8;28644:4;28641:1;28622:42;:::i;:::-;28697:6;28692:3;28688:16;28679:7;28676:29;28673:2;;;28708:18;;:::i;:::-;28746:20;;27914:858;-1:-1:-1;;;;27914:858:1:o;28777:287::-;;-1:-1:-1;;;;;28910:2:1;28907:1;28903:10;28940:2;28937:1;28933:10;28996:3;28992:2;28988:12;28983:3;28980:21;28973:3;28966:11;28959:19;28955:47;28952:2;;;29005:18;;:::i;29069:168::-;;29175:1;29171;29167:6;29163:14;29160:1;29157:21;29152:1;29145:9;29138:17;29134:45;29131:2;;;29182:18;;:::i;:::-;-1:-1:-1;29222:9:1;;29121:116::o;29242:246::-;;-1:-1:-1;;;;;29395:10:1;;;;29365;;29417:12;;;29414:2;;;29432:18;;:::i;:::-;29469:13;;29291:197;-1:-1:-1;;;29291:197:1:o;29493:125::-;;29561:1;29558;29555:8;29552:2;;;29566:18;;:::i;:::-;-1:-1:-1;29603:9:1;;29542:76::o;29623:258::-;29695:1;29705:113;29719:6;29716:1;29713:13;29705:113;;;29795:11;;;29789:18;29776:11;;;29769:39;29741:2;29734:10;29705:113;;;29836:6;29833:1;29830:13;29827:2;;;-1:-1:-1;;29871:1:1;29853:16;;29846:27;29676:205::o;29886:135::-;;-1:-1:-1;;29946:17:1;;29943:2;;;29966:18;;:::i;:::-;-1:-1:-1;30013:1:1;30002:13;;29933:88::o;30026:127::-;30087:10;30082:3;30078:20;30075:1;30068:31;30118:4;30115:1;30108:15;30142:4;30139:1;30132:15;30158:127;30219:10;30214:3;30210:20;30207:1;30200:31;30250:4;30247:1;30240:15;30274:4;30271:1;30264:15;30290:127;30351:10;30346:3;30342:20;30339:1;30332:31;30382:4;30379:1;30372:15;30406:4;30403:1;30396:15
Swarm Source
ipfs://f78cb1fc5e5f9d3d51d2ceab0af6d29268e939f879fbfcba8b52c10ff7bbad23
Loading...
Loading
Loading...
Loading
[ 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.