Source Code
Latest 25 from a total of 83 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Withdraw | 125400608 | 881 days ago | IN | 0 ETH | 0.00003263 | ||||
| Withdraw | 125400485 | 881 days ago | IN | 0 ETH | 0.00003348 | ||||
| Withdraw | 124079863 | 885 days ago | IN | 0 ETH | 0.00003945 | ||||
| Withdraw | 96361483 | 969 days ago | IN | 0 ETH | 0.00008543 | ||||
| Deposit | 95293196 | 972 days ago | IN | 0 ETH | 0.0000569 | ||||
| Deposit | 95292846 | 972 days ago | IN | 0 ETH | 0.00005083 | ||||
| Deposit | 94791207 | 973 days ago | IN | 0 ETH | 0.00005498 | ||||
| Withdraw | 93155767 | 978 days ago | IN | 0 ETH | 0.00008324 | ||||
| Withdraw | 93155485 | 978 days ago | IN | 0 ETH | 0.00008409 | ||||
| Withdraw | 92789999 | 979 days ago | IN | 0 ETH | 0.00006049 | ||||
| Withdraw | 92659783 | 980 days ago | IN | 0 ETH | 0.00008467 | ||||
| Withdraw | 92591130 | 980 days ago | IN | 0 ETH | 0.00006875 | ||||
| Withdraw | 92490932 | 980 days ago | IN | 0 ETH | 0.0000642 | ||||
| Withdraw | 92283097 | 981 days ago | IN | 0 ETH | 0.00009298 | ||||
| Withdraw | 92163850 | 981 days ago | IN | 0 ETH | 0.00007662 | ||||
| Withdraw | 92121238 | 981 days ago | IN | 0 ETH | 0.00008685 | ||||
| Withdraw | 91844614 | 982 days ago | IN | 0 ETH | 0.00007824 | ||||
| Withdraw | 91809946 | 982 days ago | IN | 0 ETH | 0.00008978 | ||||
| Withdraw | 91797397 | 982 days ago | IN | 0 ETH | 0.00008286 | ||||
| Withdraw | 91643321 | 983 days ago | IN | 0 ETH | 0.0001108 | ||||
| Deposit | 91624687 | 983 days ago | IN | 0 ETH | 0.00010711 | ||||
| Inject Rewards | 91602994 | 983 days ago | IN | 0 ETH | 0.00007514 | ||||
| Withdraw | 91602367 | 983 days ago | IN | 0 ETH | 0.00008768 | ||||
| Withdraw | 91519663 | 983 days ago | IN | 0 ETH | 0.00007958 | ||||
| Withdraw | 91518476 | 983 days ago | IN | 0 ETH | 0.00007959 |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
AISEALiquidityPool
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity)
/**
*Submitted for verification at Arbiscan.io on 2023-05-13
*/
// File: @openzeppelin/contracts/utils/math/SafeMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
// File: @openzeppelin/contracts/utils/math/Math.sol
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1);
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}
// File: @openzeppelin/contracts/utils/Context.sol
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
// File: @openzeppelin/contracts/security/Pausable.sol
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
// File: @openzeppelin/contracts/token/ERC20/IERC20.sol
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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 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 `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, 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 `from` to `to` 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 from,
address to,
uint256 amount
) external returns (bool);
}
// File: @openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
// File: @openzeppelin/contracts/utils/Address.sol
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @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
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 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");
(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 functionCallWithValue(target, data, 0, "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");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// 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
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
// File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
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));
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @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
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
// File: @openzeppelin/contracts/access/Ownable.sol
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
// File: @openzeppelin/contracts/utils/structs/EnumerableSet.sol
// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
pragma solidity ^0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableSet.
* ====
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping(bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastValue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastValue;
// Update the index for the moved value
set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
}
// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
// File: contracts/pool/AISEALiquidityPool.sol
pragma solidity =0.8.19;
contract AISEALiquidityPool is Ownable {
using SafeMath for uint256;
using SafeERC20 for IERC20;
using EnumerableSet for EnumerableSet.AddressSet;
struct UserInfo {
uint256 amount; // How many tokens the user has provided.
uint256 rewardDebt; // Reward debt.
}
struct PoolInfo {
IERC20 token; // Address of erc20 token contract.
uint256 allocPoint; // How many allocation points assigned to this pool. Tokens to distribute per second.
uint256 totalDeposit;
uint256 lastRewardTime; // Last timestamp that Tokens distribution occurs.
uint256 accRewardsPerShare; // Accumulated RewardTokens per share, times 1e18.
}
struct PoolView {
uint256 pid;
uint256 allocPoint;
uint256 lastRewardTime;
uint256 rewardsPerSecond;
uint256 accRewardPerShare;
uint256 totalAmount;
address token;
string symbol;
string name;
uint8 decimals;
uint256 startTime;
uint256 bonusEndTime;
uint256 totalReward;
}
struct UserView {
uint256 stakedAmount;
uint256 unclaimedRewards;
uint256 lpBalance;
}
IERC20 public rewardToken;
uint256 public totalReward;
uint256 public maxStakingPerUser;
uint256 public rewardPerSecond;
uint256 public standardRewardInterval = 3 days;
uint256 public BONUS_MULTIPLIER = 1;
PoolInfo[] public poolInfo;
mapping(uint256 => mapping(address => UserInfo)) public userInfo;
uint256 private totalAllocPoint = 0;
uint256 public startTime;
uint256 public bonusEndTime;
EnumerableSet.AddressSet private _pairs;
mapping(address => uint256) public LpOfPid;
EnumerableSet.AddressSet private _callers;
event Deposit(address indexed user, uint256 amount);
event Withdraw(address indexed user, uint256 amount, uint256 rewards);
event EmergencyWithdraw(address indexed user, uint256 amount);
constructor(
IERC20 _rewardToken,
uint256 _rewardPerSecond,
uint256 _startTime,
uint256 _bonusEndTime,
uint256 _maxStakingPerUser
) {
rewardToken = _rewardToken;
rewardPerSecond = _rewardPerSecond;
startTime = _startTime;
bonusEndTime = _bonusEndTime;
maxStakingPerUser = _maxStakingPerUser;
}
function stopReward() public onlyOwner {
bonusEndTime = block.timestamp;
}
function getMultiplier(uint256 _from, uint256 _to) public view returns (uint256) {
if (_to <= bonusEndTime) {
return _to.sub(_from).mul(BONUS_MULTIPLIER);
} else if (_from >= bonusEndTime) {
return 0;
} else {
return bonusEndTime.sub(_from).mul(BONUS_MULTIPLIER);
}
}
function add(uint256 _allocPoint, address _token) public onlyOwner {
require(_token != address(0), "_token is the zero address");
require(!EnumerableSet.contains(_pairs, _token), "_token is already added to the pool");
EnumerableSet.add(_pairs, _token);
massUpdatePools();
uint256 lastRewardTime = block.timestamp > startTime ? block.timestamp : startTime;
totalAllocPoint = totalAllocPoint.add(_allocPoint);
poolInfo.push(
PoolInfo({
token: IERC20(_token),
allocPoint: _allocPoint,
totalDeposit: 0,
lastRewardTime: lastRewardTime,
accRewardsPerShare: 0
})
);
LpOfPid[_token] = poolInfo.length - 1;
}
function set(uint256 _pid, uint256 _allocPoint) public onlyOwner {
require(_pid <= poolInfo.length - 1, "AISEALiquidityPool: Can not find this pool");
massUpdatePools();
totalAllocPoint = totalAllocPoint.sub(poolInfo[_pid].allocPoint).add(_allocPoint);
poolInfo[_pid].allocPoint = _allocPoint;
}
function updateMultiplier(uint256 multiplierNumber) public onlyOwner {
massUpdatePools();
BONUS_MULTIPLIER = multiplierNumber;
}
function setMaxStakingPerUser(uint256 amount) public onlyOwner {
maxStakingPerUser = amount;
}
function setStandardRewardInterval(uint256 interval) public onlyOwner {
require(interval > 0, "AISEALiquidityPool: interval must be greater than 0");
standardRewardInterval = interval;
}
function pendingReward(uint256 _pid, address _user) public view returns (uint256) {
require(_pid <= poolInfo.length - 1, "AISEALiquidityPool: Can not find this pool");
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][_user];
uint256 accRewardsPerShare = pool.accRewardsPerShare;
uint256 lpSupply = pool.totalDeposit;
if (block.timestamp > pool.lastRewardTime && lpSupply != 0) {
uint256 multiplier = getMultiplier(pool.lastRewardTime, block.timestamp);
uint256 tokenReward = multiplier.mul(rewardPerSecond).mul(pool.allocPoint).div(totalAllocPoint);
accRewardsPerShare = accRewardsPerShare.add(tokenReward.mul(1e18).div(lpSupply));
}
return user.amount.mul(accRewardsPerShare).div(1e18).sub(user.rewardDebt);
}
function updatePool(uint256 _pid) public {
PoolInfo storage pool = poolInfo[_pid];
if (block.timestamp <= pool.lastRewardTime) {
return;
}
uint256 lpSupply = pool.totalDeposit;
if (lpSupply == 0) {
pool.lastRewardTime = block.timestamp;
return;
}
uint256 multiplier = getMultiplier(pool.lastRewardTime, block.timestamp);
uint256 tokenReward = multiplier.mul(rewardPerSecond).mul(pool.allocPoint).div(totalAllocPoint);
pool.accRewardsPerShare = pool.accRewardsPerShare.add(tokenReward.mul(1e18).div(lpSupply));
pool.lastRewardTime = block.timestamp;
}
function massUpdatePools() public {
uint256 length = poolInfo.length;
for (uint256 pid = 0; pid < length; ++pid) {
updatePool(pid);
}
}
function deposit(uint256 _pid, uint256 _amount) public {
require(_pid <= poolInfo.length - 1, "AISEALiquidityPool: Can not find this pool");
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
updatePool(_pid);
uint256 reward;
if (user.amount > 0) {
uint256 pending = user.amount.mul(pool.accRewardsPerShare).div(1e18).sub(user.rewardDebt);
if(pending > 0) {
uint256 bal = rewardToken.balanceOf(address(this));
if(bal >= pending) {
reward = pending;
} else {
reward = bal;
}
}
}
if(_amount > 0) {
uint256 oldBal = pool.token.balanceOf(address(this));
pool.token.safeTransferFrom(address(msg.sender), address(this), _amount);
_amount = pool.token.balanceOf(address(this)).sub(oldBal);
require(_amount.add(user.amount) <= maxStakingPerUser, 'AISEALiquidityPool: exceed max stake');
user.amount = user.amount.add(_amount);
pool.totalDeposit = pool.totalDeposit.add(_amount);
}
user.rewardDebt = user.amount.mul(pool.accRewardsPerShare).div(1e18);
if (reward > 0) {
rewardToken.safeTransfer(address(msg.sender), reward);
}
emit Deposit(msg.sender, _amount);
}
function injectRewards(uint256 amount) public onlyCaller {
uint256 remainingSeconds = bonusEndTime > block.timestamp ? bonusEndTime.sub(block.timestamp) : 0;
uint256 rewardsSeconds = standardRewardInterval;
if (remainingSeconds < rewardsSeconds) {
rewardsSeconds = rewardsSeconds - remainingSeconds;
} else {
rewardsSeconds = 0;
}
_injectRewardsWithTime(amount, rewardsSeconds);
}
function injectRewardsWithTime(uint256 amount, uint256 rewardsSeconds) public onlyCaller {
_injectRewardsWithTime(amount, rewardsSeconds);
}
function _injectRewardsWithTime(uint256 amount, uint256 rewardsSeconds) internal {
massUpdatePools();
uint256 oldBal = rewardToken.balanceOf(address(this));
rewardToken.safeTransferFrom(_msgSender(), address(this), amount);
uint256 realAmount = rewardToken.balanceOf(address(this)).sub(oldBal);
uint256 remainingSeconds = bonusEndTime > block.timestamp ? bonusEndTime.sub(block.timestamp) : 0;
uint256 remainingBal = rewardPerSecond.mul(remainingSeconds);
rewardsSeconds = rewardsSeconds.add(remainingSeconds);
remainingBal = remainingBal.add(realAmount);
rewardPerSecond = remainingBal.div(rewardsSeconds);
if(block.timestamp >= startTime) {
bonusEndTime = block.timestamp.add(rewardsSeconds);
} else {
bonusEndTime = startTime.add(rewardsSeconds);
}
totalReward += realAmount;
}
function withdraw(uint256 _pid, uint256 _amount) public {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
require(user.amount >= _amount, "AISEALiquidityPool: Withdraw with insufficient balance");
updatePool(_pid);
uint256 pending = user.amount.mul(pool.accRewardsPerShare).div(1e18).sub(user.rewardDebt);
if(_amount > 0) {
user.amount = user.amount.sub(_amount);
pool.totalDeposit = pool.totalDeposit.sub(_amount);
pool.token.safeTransfer(address(msg.sender), _amount);
}
user.rewardDebt = user.amount.mul(pool.accRewardsPerShare).div(1e18);
uint256 rewards;
if(pending > 0) {
uint256 bal = rewardToken.balanceOf(address(this));
if(bal >= pending) {
rewards = pending;
} else {
rewards = bal;
}
}
rewardToken.safeTransfer(address(msg.sender), rewards);
emit Withdraw(msg.sender, _amount, rewards);
}
function emergencyWithdraw(uint256 _pid) public {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
uint256 amount = user.amount;
if(pool.totalDeposit >= user.amount) {
pool.totalDeposit = pool.totalDeposit.sub(user.amount);
} else {
pool.totalDeposit = 0;
}
user.amount = 0;
user.rewardDebt = 0;
pool.token.safeTransfer(address(msg.sender), amount);
emit EmergencyWithdraw(msg.sender, user.amount);
}
function emergencyRewardWithdraw(uint256 _amount) public onlyOwner {
require(_amount <= rewardToken.balanceOf(address(this)), 'AISEALiquidityPool: not enough token');
rewardToken.safeTransfer(address(msg.sender), _amount);
}
function getPoolView(uint256 pid) public view returns (PoolView memory) {
require(pid < poolInfo.length, "AISEALiquidityPool: pid out of range");
PoolInfo memory pool = poolInfo[pid];
IERC20Metadata token = IERC20Metadata(address(pool.token));
uint256 rewardsPerSecond = pool.allocPoint.mul(rewardPerSecond).div(totalAllocPoint);
return
PoolView({
pid: pid,
allocPoint: pool.allocPoint,
lastRewardTime: pool.lastRewardTime,
accRewardPerShare: pool.accRewardsPerShare,
rewardsPerSecond: rewardsPerSecond,
totalAmount: pool.totalDeposit,
token: address(token),
symbol: token.symbol(),
name: token.name(),
decimals: token.decimals(),
startTime: startTime,
bonusEndTime: bonusEndTime,
totalReward: totalReward
});
}
function getAllPoolViews() external view returns (PoolView[] memory) {
PoolView[] memory views = new PoolView[](poolInfo.length);
for (uint256 i = 0; i < poolInfo.length; i++) {
views[i] = getPoolView(i);
}
return views;
}
function getUserView(address token, address account) public view returns (UserView memory) {
uint256 pid = LpOfPid[token];
UserInfo memory user = userInfo[pid][account];
uint256 unclaimedRewards = pendingReward(pid, account);
uint256 lpBalance = IERC20(token).balanceOf(account);
return
UserView({
stakedAmount: user.amount,
unclaimedRewards: unclaimedRewards,
lpBalance: lpBalance
});
}
function getUserViews(address account) external view returns (UserView[] memory) {
address token;
UserView[] memory views = new UserView[](poolInfo.length);
for (uint256 i = 0; i < poolInfo.length; i++) {
token = address(poolInfo[i].token);
views[i] = getUserView(token, account);
}
return views;
}
function addCaller(address val) public onlyOwner() {
require(val != address(0), "AISEALiquidityPool: val is the zero address");
_callers.add(val);
}
function delCaller(address caller) public onlyOwner returns (bool) {
require(caller != address(0), "AISEALiquidityPool: caller is the zero address");
return _callers.remove(caller);
}
function getCallers() public view returns (address[] memory ret) {
return _callers.values();
}
modifier onlyCaller() {
require(_callers.contains(_msgSender()), "onlyCaller");
_;
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IERC20","name":"_rewardToken","type":"address"},{"internalType":"uint256","name":"_rewardPerSecond","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_bonusEndTime","type":"uint256"},{"internalType":"uint256","name":"_maxStakingPerUser","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewards","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"BONUS_MULTIPLIER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"LpOfPid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"address","name":"_token","type":"address"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"val","type":"address"}],"name":"addCaller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bonusEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"delCaller","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"emergencyRewardWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllPoolViews","outputs":[{"components":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardTime","type":"uint256"},{"internalType":"uint256","name":"rewardsPerSecond","type":"uint256"},{"internalType":"uint256","name":"accRewardPerShare","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"bonusEndTime","type":"uint256"},{"internalType":"uint256","name":"totalReward","type":"uint256"}],"internalType":"struct AISEALiquidityPool.PoolView[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCallers","outputs":[{"internalType":"address[]","name":"ret","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_from","type":"uint256"},{"internalType":"uint256","name":"_to","type":"uint256"}],"name":"getMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"getPoolView","outputs":[{"components":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardTime","type":"uint256"},{"internalType":"uint256","name":"rewardsPerSecond","type":"uint256"},{"internalType":"uint256","name":"accRewardPerShare","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"bonusEndTime","type":"uint256"},{"internalType":"uint256","name":"totalReward","type":"uint256"}],"internalType":"struct AISEALiquidityPool.PoolView","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"getUserView","outputs":[{"components":[{"internalType":"uint256","name":"stakedAmount","type":"uint256"},{"internalType":"uint256","name":"unclaimedRewards","type":"uint256"},{"internalType":"uint256","name":"lpBalance","type":"uint256"}],"internalType":"struct AISEALiquidityPool.UserView","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getUserViews","outputs":[{"components":[{"internalType":"uint256","name":"stakedAmount","type":"uint256"},{"internalType":"uint256","name":"unclaimedRewards","type":"uint256"},{"internalType":"uint256","name":"lpBalance","type":"uint256"}],"internalType":"struct AISEALiquidityPool.UserView[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"injectRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rewardsSeconds","type":"uint256"}],"name":"injectRewardsWithTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxStakingPerUser","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"totalDeposit","type":"uint256"},{"internalType":"uint256","name":"lastRewardTime","type":"uint256"},{"internalType":"uint256","name":"accRewardsPerShare","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardPerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMaxStakingPerUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"interval","type":"uint256"}],"name":"setStandardRewardInterval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"standardRewardInterval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stopReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"multiplierNumber","type":"uint256"}],"name":"updateMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040526203f480600555600160065560006009553480156200002257600080fd5b506040516200498738038062004987833981810160405281019062000048919062000255565b620000686200005c620000d060201b60201c565b620000d860201b60201c565b84600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508360048190555082600a8190555081600b81905550806003819055505050505050620002dd565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620001ce82620001a1565b9050919050565b6000620001e282620001c1565b9050919050565b620001f481620001d5565b81146200020057600080fd5b50565b6000815190506200021481620001e9565b92915050565b6000819050919050565b6200022f816200021a565b81146200023b57600080fd5b50565b6000815190506200024f8162000224565b92915050565b600080600080600060a086880312156200027457620002736200019c565b5b6000620002848882890162000203565b955050602062000297888289016200023e565b9450506040620002aa888289016200023e565b9350506060620002bd888289016200023e565b9250506080620002d0888289016200023e565b9150509295509295909350565b61469a80620002ed6000396000f3fe608060405234801561001057600080fd5b50600436106102275760003560e01c8063750142e611610130578063a2ea0c10116100b8578063dd8d4c401161007c578063dd8d4c401461063f578063e2bbb1581461065d578063ee1a629514610679578063f2fde38b14610697578063f7c618c1146106b357610227565b8063a2ea0c1014610587578063aa50d351146105a5578063b0c7044b146105c1578063c372e312146105f1578063d0c9bb591461060f57610227565b80638da5cb5b116100ff5780638da5cb5b146104ba5780638dbb1e3a146104d85780638f10369a1461050857806393f1a40b1461052657806398969e821461055757610227565b8063750142e61461045657806378e979251461047457806380dc0672146104925780638aa285501461049c57610227565b806351eb05a6116101b3578063647573321161018257806364757332146103c65780636ccdf9ff146103e4578063715018a61461041457806373566f021461041e578063747293fb1461043a57610227565b806351eb05a6146103685780635312ea8e146103845780635ffe6146146103a0578063630b5ba1146103bc57610227565b8063231a418c116101fa578063231a418c146102c85780632b8bbbe8146102f85780633279beab146103145780633bdc8a1f14610330578063441a3e701461034c57610227565b8063122058391461022c5780631526fe27146102485780631ab06ee51461027c578063225b87c414610298575b600080fd5b61024660048036038101906102419190612f27565b6106d1565b005b610262600480360381019061025d9190612f27565b6106e3565b604051610273959493929190612fe2565b60405180910390f35b61029660048036038101906102919190613035565b610749565b005b6102b260048036038101906102ad91906130b3565b61082d565b6040516102bf91906131e0565b60405180910390f35b6102e260048036038101906102dd91906130b3565b61092b565b6040516102ef919061321d565b60405180910390f35b610312600480360381019061030d9190613238565b6109bf565b005b61032e60048036038101906103299190612f27565b610bfc565b005b61034a60048036038101906103459190612f27565b610d32565b005b61036660048036038101906103619190613035565b610dec565b005b610382600480360381019061037d9190612f27565b61113d565b005b61039e60048036038101906103999190612f27565b611246565b005b6103ba60048036038101906103b59190612f27565b6113c6565b005b6103c46113e0565b005b6103ce611413565b6040516103db9190613515565b60405180910390f35b6103fe60048036038101906103f99190613537565b6114c4565b60405161040b91906135b9565b60405180910390f35b61041c61163a565b005b61043860048036038101906104339190613035565b61164e565b005b610454600480360381019061044f91906130b3565b6116b6565b005b61045e611745565b60405161046b91906135d4565b60405180910390f35b61047c61174b565b60405161048991906135d4565b60405180910390f35b61049a611751565b005b6104a4611762565b6040516104b191906135d4565b60405180910390f35b6104c2611768565b6040516104cf91906135fe565b60405180910390f35b6104f260048036038101906104ed9190613035565b611791565b6040516104ff91906135d4565b60405180910390f35b61051061180e565b60405161051d91906135d4565b60405180910390f35b610540600480360381019061053b9190613238565b611814565b60405161054e929190613619565b60405180910390f35b610571600480360381019061056c9190613238565b611845565b60405161057e91906135d4565b60405180910390f35b61058f611a2c565b60405161059c91906135d4565b60405180910390f35b6105bf60048036038101906105ba9190612f27565b611a32565b005b6105db60048036038101906105d691906130b3565b611a87565b6040516105e891906135d4565b60405180910390f35b6105f9611a9f565b60405161060691906135d4565b60405180910390f35b61062960048036038101906106249190612f27565b611aa5565b6040516106369190613762565b60405180910390f35b610647611dc2565b6040516106549190613833565b60405180910390f35b61067760048036038101906106729190613035565b611dd3565b005b6106816122f9565b60405161068e91906135d4565b60405180910390f35b6106b160048036038101906106ac91906130b3565b6122ff565b005b6106bb612382565b6040516106c89190613855565b60405180910390f35b6106d96123a8565b8060038190555050565b600781815481106106f357600080fd5b90600052602060002090600502016000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154908060020154908060030154908060040154905085565b6107516123a8565b6001600780549050610763919061389f565b8211156107a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161079c90613956565b60405180910390fd5b6107ad6113e0565b6107f9816107eb600785815481106107c8576107c7613976565b5b90600052602060002090600502016001015460095461242690919063ffffffff16565b61243c90919063ffffffff16565b600981905550806007838154811061081457610813613976565b5b9060005260206000209060050201600101819055505050565b606060008060078054905067ffffffffffffffff811115610851576108506139a5565b5b60405190808252806020026020018201604052801561088a57816020015b610877612e3b565b81526020019060019003908161086f5790505b50905060005b60078054905081101561092057600781815481106108b1576108b0613976565b5b906000526020600020906005020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1692506108ef83866114c4565b82828151811061090257610901613976565b5b60200260200101819052508080610918906139d4565b915050610890565b508092505050919050565b60006109356123a8565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036109a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099b90613a8e565b60405180910390fd5b6109b882600f61245290919063ffffffff16565b9050919050565b6109c76123a8565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610a36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2d90613afa565b60405180910390fd5b610a41600c82612482565b15610a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7890613b8c565b60405180910390fd5b610a8c600c826124b2565b50610a956113e0565b6000600a544211610aa857600a54610aaa565b425b9050610ac18360095461243c90919063ffffffff16565b60098190555060076040518060a001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001858152602001600081526020018381526020016000815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015560408201518160020155606082015181600301556080820151816004015550506001600780549050610bb4919061389f565b600e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050565b610c046123a8565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610c5f91906135fe565b602060405180830381865afa158015610c7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca09190613bc1565b811115610ce2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cd990613c60565b60405180910390fd5b610d2f3382600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166124e29092919063ffffffff16565b50565b610d4d610d3d612568565b600f61248290919063ffffffff16565b610d8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d8390613ccc565b60405180910390fd5b600042600b5411610d9e576000610db4565b610db342600b5461242690919063ffffffff16565b5b90506000600554905080821015610dd8578181610dd1919061389f565b9050610ddd565b600090505b610de78382612570565b505050565b600060078381548110610e0257610e01613976565b5b9060005260206000209060050201905060006008600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508281600001541015610ead576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea490613d5e565b60405180910390fd5b610eb68461113d565b6000610f038260010154610ef5670de0b6b3a7640000610ee78760040154876000015461280a90919063ffffffff16565b61282090919063ffffffff16565b61242690919063ffffffff16565b90506000841115610f9c57610f2584836000015461242690919063ffffffff16565b8260000181905550610f4484846002015461242690919063ffffffff16565b8360020181905550610f9b33858560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166124e29092919063ffffffff16565b5b610fd1670de0b6b3a7640000610fc38560040154856000015461280a90919063ffffffff16565b61282090919063ffffffff16565b8260010181905550600080821115611098576000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161104091906135fe565b602060405180830381865afa15801561105d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110819190613bc1565b905082811061109257829150611096565b8091505b505b6110e53382600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166124e29092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568868360405161112d929190613619565b60405180910390a2505050505050565b60006007828154811061115357611152613976565b5b90600052602060002090600502019050806003015442116111745750611243565b60008160020154905060008103611195574282600301819055505050611243565b60006111a5836003015442611791565b905060006111e86009546111da86600101546111cc6004548761280a90919063ffffffff16565b61280a90919063ffffffff16565b61282090919063ffffffff16565b905061122d61121a8461120c670de0b6b3a76400008561280a90919063ffffffff16565b61282090919063ffffffff16565b856004015461243c90919063ffffffff16565b8460040181905550428460030181905550505050505b50565b60006007828154811061125c5761125b613976565b5b9060005260206000209060050201905060006008600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000816000015490508160000154836002015410611300576112f38260000154846002015461242690919063ffffffff16565b836002018190555061130b565b600083600201819055505b600082600001819055506000826001018190555061136e33828560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166124e29092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd969583600001546040516113b891906135d4565b60405180910390a250505050565b6113ce6123a8565b6113d66113e0565b8060068190555050565b6000600780549050905060005b8181101561140f576113fe8161113d565b80611408906139d4565b90506113ed565b5050565b6060600060078054905067ffffffffffffffff811115611436576114356139a5565b5b60405190808252806020026020018201604052801561146f57816020015b61145c612e5c565b8152602001906001900390816114545790505b50905060005b6007805490508110156114bc5761148b81611aa5565b82828151811061149e5761149d613976565b5b602002602001018190525080806114b4906139d4565b915050611475565b508091505090565b6114cc612e3b565b6000600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006008600083815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806040016040529081600082015481526020016001820154815250509050600061158f8386611845565b905060008673ffffffffffffffffffffffffffffffffffffffff166370a08231876040518263ffffffff1660e01b81526004016115cc91906135fe565b602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d9190613bc1565b90506040518060600160405280846000015181526020018381526020018281525094505050505092915050565b6116426123a8565b61164c6000612836565b565b611669611659612568565b600f61248290919063ffffffff16565b6116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169f90613ccc565b60405180910390fd5b6116b28282612570565b5050565b6116be6123a8565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361172d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172490613df0565b60405180910390fd5b61174181600f6124b290919063ffffffff16565b5050565b60025481565b600a5481565b6117596123a8565b42600b81905550565b60065481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600b5482116117ca576117c36006546117b5858561242690919063ffffffff16565b61280a90919063ffffffff16565b9050611808565b600b5483106117dc5760009050611808565b6118056006546117f785600b5461242690919063ffffffff16565b61280a90919063ffffffff16565b90505b92915050565b60045481565b6008602052816000526040600020602052806000526040600020600091509150508060000154908060010154905082565b60006001600780549050611859919061389f565b83111561189b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161189290613956565b60405180910390fd5b6000600784815481106118b1576118b0613976565b5b9060005260206000209060050201905060006008600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008260040154905060008360020154905083600301544211801561193b575060008114155b156119d9576000611950856003015442611791565b9050600061199360095461198588600101546119776004548761280a90919063ffffffff16565b61280a90919063ffffffff16565b61282090919063ffffffff16565b90506119d46119c5846119b7670de0b6b3a76400008561280a90919063ffffffff16565b61282090919063ffffffff16565b8561243c90919063ffffffff16565b935050505b611a208360010154611a12670de0b6b3a7640000611a0486886000015461280a90919063ffffffff16565b61282090919063ffffffff16565b61242690919063ffffffff16565b94505050505092915050565b60055481565b611a3a6123a8565b60008111611a7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a7490613e82565b60405180910390fd5b8060058190555050565b600e6020528060005260406000206000915090505481565b60035481565b611aad612e5c565b6007805490508210611af4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aeb90613f14565b60405180910390fd5b600060078381548110611b0a57611b09613976565b5b90600052602060002090600502016040518060a00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481526020016003820154815260200160048201548152505090506000816000015190506000611bdb600954611bcd600454866020015161280a90919063ffffffff16565b61282090919063ffffffff16565b9050604051806101a00160405280868152602001846020015181526020018460600151815260200182815260200184608001518152602001846040015181526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611c84573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611cad919061402b565b81526020018373ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015611cfd573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611d26919061402b565b81526020018373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9a91906140a0565b60ff168152602001600a548152602001600b5481526020016002548152509350505050919050565b6060611dce600f6128fa565b905090565b6001600780549050611de5919061389f565b821115611e27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1e90613956565b60405180910390fd5b600060078381548110611e3d57611e3c613976565b5b9060005260206000209060050201905060006008600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050611eaa8461113d565b60008082600001541115611fc7576000611f058360010154611ef7670de0b6b3a7640000611ee98860040154886000015461280a90919063ffffffff16565b61282090919063ffffffff16565b61242690919063ffffffff16565b90506000811115611fc5576000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611f6d91906135fe565b602060405180830381865afa158015611f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fae9190613bc1565b9050818110611fbf57819250611fc3565b8092505b505b505b60008411156122105760008360000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161202f91906135fe565b602060405180830381865afa15801561204c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120709190613bc1565b90506120c33330878760000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661291b909392919063ffffffff16565b612173818560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161212491906135fe565b602060405180830381865afa158015612141573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121659190613bc1565b61242690919063ffffffff16565b945060035461218f84600001548761243c90919063ffffffff16565b11156121d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121c79061413f565b60405180910390fd5b6121e785846000015461243c90919063ffffffff16565b836000018190555061220685856002015461243c90919063ffffffff16565b8460020181905550505b612245670de0b6b3a76400006122378560040154856000015461280a90919063ffffffff16565b61282090919063ffffffff16565b826001018190555060008111156122a4576122a33382600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166124e29092919063ffffffff16565b5b3373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c856040516122ea91906135d4565b60405180910390a25050505050565b600b5481565b6123076123a8565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612376576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236d906141d1565b60405180910390fd5b61237f81612836565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6123b0612568565b73ffffffffffffffffffffffffffffffffffffffff166123ce611768565b73ffffffffffffffffffffffffffffffffffffffff1614612424576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161241b9061423d565b60405180910390fd5b565b60008183612434919061389f565b905092915050565b6000818361244a919061425d565b905092915050565b600061247a836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6129a4565b905092915050565b60006124aa836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612ab8565b905092915050565b60006124da836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612adb565b905092915050565b6125638363a9059cbb60e01b8484604051602401612501929190614291565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612b4b565b505050565b600033905090565b6125786113e0565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016125d591906135fe565b602060405180830381865afa1580156125f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126169190613bc1565b905061266e612623612568565b3085600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661291b909392919063ffffffff16565b600061271e82600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016126cf91906135fe565b602060405180830381865afa1580156126ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127109190613bc1565b61242690919063ffffffff16565b9050600042600b5411612732576000612748565b61274742600b5461242690919063ffffffff16565b5b905060006127618260045461280a90919063ffffffff16565b9050612776828661243c90919063ffffffff16565b945061278b838261243c90919063ffffffff16565b90506127a0858261282090919063ffffffff16565b600481905550600a5442106127cd576127c2854261243c90919063ffffffff16565b600b819055506127e9565b6127e285600a5461243c90919063ffffffff16565b600b819055505b82600260008282546127fb919061425d565b92505081905550505050505050565b6000818361281891906142ba565b905092915050565b6000818361282e919061432b565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6060600061290a83600001612c12565b905060608190508092505050919050565b61299e846323b872dd60e01b85858560405160240161293c9392919061435c565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612b4b565b50505050565b60008083600101600084815260200190815260200160002054905060008114612aac5760006001826129d6919061389f565b90506000600186600001805490506129ee919061389f565b9050818114612a5d576000866000018281548110612a0f57612a0e613976565b5b9060005260206000200154905080876000018481548110612a3357612a32613976565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480612a7157612a70614393565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612ab2565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000612ae78383612ab8565b612b40578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612b45565b600090505b92915050565b6000612bad826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612c6e9092919063ffffffff16565b9050600081511115612c0d5780806020019051810190612bcd91906143ee565b612c0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c039061448d565b60405180910390fd5b5b505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015612c6257602002820191906000526020600020905b815481526020019060010190808311612c4e575b50505050509050919050565b6060612c7d8484600085612c86565b90509392505050565b606082471015612ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cc29061451f565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612cf49190614586565b60006040518083038185875af1925050503d8060008114612d31576040519150601f19603f3d011682016040523d82523d6000602084013e612d36565b606091505b5091509150612d4787838387612d53565b92505050949350505050565b60608315612db5576000835103612dad57612d6d85612dc8565b612dac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612da3906145e9565b60405180910390fd5b5b829050612dc0565b612dbf8383612deb565b5b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600082511115612dfe5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e329190614642565b60405180910390fd5b60405180606001604052806000815260200160008152602001600081525090565b604051806101a00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016060815260200160608152602001600060ff1681526020016000815260200160008152602001600081525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b612f0481612ef1565b8114612f0f57600080fd5b50565b600081359050612f2181612efb565b92915050565b600060208284031215612f3d57612f3c612ee7565b5b6000612f4b84828501612f12565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000612f99612f94612f8f84612f54565b612f74565b612f54565b9050919050565b6000612fab82612f7e565b9050919050565b6000612fbd82612fa0565b9050919050565b612fcd81612fb2565b82525050565b612fdc81612ef1565b82525050565b600060a082019050612ff76000830188612fc4565b6130046020830187612fd3565b6130116040830186612fd3565b61301e6060830185612fd3565b61302b6080830184612fd3565b9695505050505050565b6000806040838503121561304c5761304b612ee7565b5b600061305a85828601612f12565b925050602061306b85828601612f12565b9150509250929050565b600061308082612f54565b9050919050565b61309081613075565b811461309b57600080fd5b50565b6000813590506130ad81613087565b92915050565b6000602082840312156130c9576130c8612ee7565b5b60006130d78482850161309e565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61311581612ef1565b82525050565b606082016000820151613131600085018261310c565b506020820151613144602085018261310c565b506040820151613157604085018261310c565b50505050565b6000613169838361311b565b60608301905092915050565b6000602082019050919050565b600061318d826130e0565b61319781856130eb565b93506131a2836130fc565b8060005b838110156131d35781516131ba888261315d565b97506131c583613175565b9250506001810190506131a6565b5085935050505092915050565b600060208201905081810360008301526131fa8184613182565b905092915050565b60008115159050919050565b61321781613202565b82525050565b6000602082019050613232600083018461320e565b92915050565b6000806040838503121561324f5761324e612ee7565b5b600061325d85828601612f12565b925050602061326e8582860161309e565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6132ad81613075565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b838110156132ed5780820151818401526020810190506132d2565b60008484015250505050565b6000601f19601f8301169050919050565b6000613315826132b3565b61331f81856132be565b935061332f8185602086016132cf565b613338816132f9565b840191505092915050565b600060ff82169050919050565b61335981613343565b82525050565b60006101a083016000830151613378600086018261310c565b50602083015161338b602086018261310c565b50604083015161339e604086018261310c565b5060608301516133b1606086018261310c565b5060808301516133c4608086018261310c565b5060a08301516133d760a086018261310c565b5060c08301516133ea60c08601826132a4565b5060e083015184820360e0860152613402828261330a565b91505061010083015184820361010086015261341e828261330a565b915050610120830151613435610120860182613350565b5061014083015161344a61014086018261310c565b5061016083015161345f61016086018261310c565b5061018083015161347461018086018261310c565b508091505092915050565b600061348b838361335f565b905092915050565b6000602082019050919050565b60006134ab82613278565b6134b58185613283565b9350836020820285016134c785613294565b8060005b8581101561350357848403895281516134e4858261347f565b94506134ef83613493565b925060208a019950506001810190506134cb565b50829750879550505050505092915050565b6000602082019050818103600083015261352f81846134a0565b905092915050565b6000806040838503121561354e5761354d612ee7565b5b600061355c8582860161309e565b925050602061356d8582860161309e565b9150509250929050565b60608201600082015161358d600085018261310c565b5060208201516135a0602085018261310c565b5060408201516135b3604085018261310c565b50505050565b60006060820190506135ce6000830184613577565b92915050565b60006020820190506135e96000830184612fd3565b92915050565b6135f881613075565b82525050565b600060208201905061361360008301846135ef565b92915050565b600060408201905061362e6000830185612fd3565b61363b6020830184612fd3565b9392505050565b60006101a08301600083015161365b600086018261310c565b50602083015161366e602086018261310c565b506040830151613681604086018261310c565b506060830151613694606086018261310c565b5060808301516136a7608086018261310c565b5060a08301516136ba60a086018261310c565b5060c08301516136cd60c08601826132a4565b5060e083015184820360e08601526136e5828261330a565b915050610100830151848203610100860152613701828261330a565b915050610120830151613718610120860182613350565b5061014083015161372d61014086018261310c565b5061016083015161374261016086018261310c565b5061018083015161375761018086018261310c565b508091505092915050565b6000602082019050818103600083015261377c8184613642565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006137bc83836132a4565b60208301905092915050565b6000602082019050919050565b60006137e082613784565b6137ea818561378f565b93506137f5836137a0565b8060005b8381101561382657815161380d88826137b0565b9750613818836137c8565b9250506001810190506137f9565b5085935050505092915050565b6000602082019050818103600083015261384d81846137d5565b905092915050565b600060208201905061386a6000830184612fc4565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006138aa82612ef1565b91506138b583612ef1565b92508282039050818111156138cd576138cc613870565b5b92915050565b600082825260208201905092915050565b7f41495345414c6971756964697479506f6f6c3a2043616e206e6f742066696e6460008201527f207468697320706f6f6c00000000000000000000000000000000000000000000602082015250565b6000613940602a836138d3565b915061394b826138e4565b604082019050919050565b6000602082019050818103600083015261396f81613933565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006139df82612ef1565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613a1157613a10613870565b5b600182019050919050565b7f41495345414c6971756964697479506f6f6c3a2063616c6c657220697320746860008201527f65207a65726f2061646472657373000000000000000000000000000000000000602082015250565b6000613a78602e836138d3565b9150613a8382613a1c565b604082019050919050565b60006020820190508181036000830152613aa781613a6b565b9050919050565b7f5f746f6b656e20697320746865207a65726f2061646472657373000000000000600082015250565b6000613ae4601a836138d3565b9150613aef82613aae565b602082019050919050565b60006020820190508181036000830152613b1381613ad7565b9050919050565b7f5f746f6b656e20697320616c726561647920616464656420746f20746865207060008201527f6f6f6c0000000000000000000000000000000000000000000000000000000000602082015250565b6000613b766023836138d3565b9150613b8182613b1a565b604082019050919050565b60006020820190508181036000830152613ba581613b69565b9050919050565b600081519050613bbb81612efb565b92915050565b600060208284031215613bd757613bd6612ee7565b5b6000613be584828501613bac565b91505092915050565b7f41495345414c6971756964697479506f6f6c3a206e6f7420656e6f756768207460008201527f6f6b656e00000000000000000000000000000000000000000000000000000000602082015250565b6000613c4a6024836138d3565b9150613c5582613bee565b604082019050919050565b60006020820190508181036000830152613c7981613c3d565b9050919050565b7f6f6e6c7943616c6c657200000000000000000000000000000000000000000000600082015250565b6000613cb6600a836138d3565b9150613cc182613c80565b602082019050919050565b60006020820190508181036000830152613ce581613ca9565b9050919050565b7f41495345414c6971756964697479506f6f6c3a2057697468647261772077697460008201527f6820696e73756666696369656e742062616c616e636500000000000000000000602082015250565b6000613d486036836138d3565b9150613d5382613cec565b604082019050919050565b60006020820190508181036000830152613d7781613d3b565b9050919050565b7f41495345414c6971756964697479506f6f6c3a2076616c20697320746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b6000613dda602b836138d3565b9150613de582613d7e565b604082019050919050565b60006020820190508181036000830152613e0981613dcd565b9050919050565b7f41495345414c6971756964697479506f6f6c3a20696e74657276616c206d757360008201527f742062652067726561746572207468616e203000000000000000000000000000602082015250565b6000613e6c6033836138d3565b9150613e7782613e10565b604082019050919050565b60006020820190508181036000830152613e9b81613e5f565b9050919050565b7f41495345414c6971756964697479506f6f6c3a20706964206f7574206f66207260008201527f616e676500000000000000000000000000000000000000000000000000000000602082015250565b6000613efe6024836138d3565b9150613f0982613ea2565b604082019050919050565b60006020820190508181036000830152613f2d81613ef1565b9050919050565b600080fd5b600080fd5b613f47826132f9565b810181811067ffffffffffffffff82111715613f6657613f656139a5565b5b80604052505050565b6000613f79612edd565b9050613f858282613f3e565b919050565b600067ffffffffffffffff821115613fa557613fa46139a5565b5b613fae826132f9565b9050602081019050919050565b6000613fce613fc984613f8a565b613f6f565b905082815260208101848484011115613fea57613fe9613f39565b5b613ff58482856132cf565b509392505050565b600082601f83011261401257614011613f34565b5b8151614022848260208601613fbb565b91505092915050565b60006020828403121561404157614040612ee7565b5b600082015167ffffffffffffffff81111561405f5761405e612eec565b5b61406b84828501613ffd565b91505092915050565b61407d81613343565b811461408857600080fd5b50565b60008151905061409a81614074565b92915050565b6000602082840312156140b6576140b5612ee7565b5b60006140c48482850161408b565b91505092915050565b7f41495345414c6971756964697479506f6f6c3a20657863656564206d6178207360008201527f74616b6500000000000000000000000000000000000000000000000000000000602082015250565b60006141296024836138d3565b9150614134826140cd565b604082019050919050565b600060208201905081810360008301526141588161411c565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006141bb6026836138d3565b91506141c68261415f565b604082019050919050565b600060208201905081810360008301526141ea816141ae565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006142276020836138d3565b9150614232826141f1565b602082019050919050565b600060208201905081810360008301526142568161421a565b9050919050565b600061426882612ef1565b915061427383612ef1565b925082820190508082111561428b5761428a613870565b5b92915050565b60006040820190506142a660008301856135ef565b6142b36020830184612fd3565b9392505050565b60006142c582612ef1565b91506142d083612ef1565b92508282026142de81612ef1565b915082820484148315176142f5576142f4613870565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061433682612ef1565b915061434183612ef1565b925082614351576143506142fc565b5b828204905092915050565b600060608201905061437160008301866135ef565b61437e60208301856135ef565b61438b6040830184612fd3565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6143cb81613202565b81146143d657600080fd5b50565b6000815190506143e8816143c2565b92915050565b60006020828403121561440457614403612ee7565b5b6000614412848285016143d9565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000614477602a836138d3565b91506144828261441b565b604082019050919050565b600060208201905081810360008301526144a68161446a565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006145096026836138d3565b9150614514826144ad565b604082019050919050565b60006020820190508181036000830152614538816144fc565b9050919050565b600081519050919050565b600081905092915050565b60006145608261453f565b61456a818561454a565b935061457a8185602086016132cf565b80840191505092915050565b60006145928284614555565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006145d3601d836138d3565b91506145de8261459d565b602082019050919050565b60006020820190508181036000830152614602816145c6565b9050919050565b6000614614826132b3565b61461e81856138d3565b935061462e8185602086016132cf565b614637816132f9565b840191505092915050565b6000602082019050818103600083015261465c8184614609565b90509291505056fea264697066735822122056c63f0f5d983ab8070c83af96b2d54d52098b991c7f2ba94aa86d4a0e175c7964736f6c63430008130033000000000000000000000000912ce59144191c1204e64559fe8253a0e49e6548000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000645f276000000000000000000000000000000000000000000000000000000000645f2760ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102275760003560e01c8063750142e611610130578063a2ea0c10116100b8578063dd8d4c401161007c578063dd8d4c401461063f578063e2bbb1581461065d578063ee1a629514610679578063f2fde38b14610697578063f7c618c1146106b357610227565b8063a2ea0c1014610587578063aa50d351146105a5578063b0c7044b146105c1578063c372e312146105f1578063d0c9bb591461060f57610227565b80638da5cb5b116100ff5780638da5cb5b146104ba5780638dbb1e3a146104d85780638f10369a1461050857806393f1a40b1461052657806398969e821461055757610227565b8063750142e61461045657806378e979251461047457806380dc0672146104925780638aa285501461049c57610227565b806351eb05a6116101b3578063647573321161018257806364757332146103c65780636ccdf9ff146103e4578063715018a61461041457806373566f021461041e578063747293fb1461043a57610227565b806351eb05a6146103685780635312ea8e146103845780635ffe6146146103a0578063630b5ba1146103bc57610227565b8063231a418c116101fa578063231a418c146102c85780632b8bbbe8146102f85780633279beab146103145780633bdc8a1f14610330578063441a3e701461034c57610227565b8063122058391461022c5780631526fe27146102485780631ab06ee51461027c578063225b87c414610298575b600080fd5b61024660048036038101906102419190612f27565b6106d1565b005b610262600480360381019061025d9190612f27565b6106e3565b604051610273959493929190612fe2565b60405180910390f35b61029660048036038101906102919190613035565b610749565b005b6102b260048036038101906102ad91906130b3565b61082d565b6040516102bf91906131e0565b60405180910390f35b6102e260048036038101906102dd91906130b3565b61092b565b6040516102ef919061321d565b60405180910390f35b610312600480360381019061030d9190613238565b6109bf565b005b61032e60048036038101906103299190612f27565b610bfc565b005b61034a60048036038101906103459190612f27565b610d32565b005b61036660048036038101906103619190613035565b610dec565b005b610382600480360381019061037d9190612f27565b61113d565b005b61039e60048036038101906103999190612f27565b611246565b005b6103ba60048036038101906103b59190612f27565b6113c6565b005b6103c46113e0565b005b6103ce611413565b6040516103db9190613515565b60405180910390f35b6103fe60048036038101906103f99190613537565b6114c4565b60405161040b91906135b9565b60405180910390f35b61041c61163a565b005b61043860048036038101906104339190613035565b61164e565b005b610454600480360381019061044f91906130b3565b6116b6565b005b61045e611745565b60405161046b91906135d4565b60405180910390f35b61047c61174b565b60405161048991906135d4565b60405180910390f35b61049a611751565b005b6104a4611762565b6040516104b191906135d4565b60405180910390f35b6104c2611768565b6040516104cf91906135fe565b60405180910390f35b6104f260048036038101906104ed9190613035565b611791565b6040516104ff91906135d4565b60405180910390f35b61051061180e565b60405161051d91906135d4565b60405180910390f35b610540600480360381019061053b9190613238565b611814565b60405161054e929190613619565b60405180910390f35b610571600480360381019061056c9190613238565b611845565b60405161057e91906135d4565b60405180910390f35b61058f611a2c565b60405161059c91906135d4565b60405180910390f35b6105bf60048036038101906105ba9190612f27565b611a32565b005b6105db60048036038101906105d691906130b3565b611a87565b6040516105e891906135d4565b60405180910390f35b6105f9611a9f565b60405161060691906135d4565b60405180910390f35b61062960048036038101906106249190612f27565b611aa5565b6040516106369190613762565b60405180910390f35b610647611dc2565b6040516106549190613833565b60405180910390f35b61067760048036038101906106729190613035565b611dd3565b005b6106816122f9565b60405161068e91906135d4565b60405180910390f35b6106b160048036038101906106ac91906130b3565b6122ff565b005b6106bb612382565b6040516106c89190613855565b60405180910390f35b6106d96123a8565b8060038190555050565b600781815481106106f357600080fd5b90600052602060002090600502016000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154908060020154908060030154908060040154905085565b6107516123a8565b6001600780549050610763919061389f565b8211156107a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161079c90613956565b60405180910390fd5b6107ad6113e0565b6107f9816107eb600785815481106107c8576107c7613976565b5b90600052602060002090600502016001015460095461242690919063ffffffff16565b61243c90919063ffffffff16565b600981905550806007838154811061081457610813613976565b5b9060005260206000209060050201600101819055505050565b606060008060078054905067ffffffffffffffff811115610851576108506139a5565b5b60405190808252806020026020018201604052801561088a57816020015b610877612e3b565b81526020019060019003908161086f5790505b50905060005b60078054905081101561092057600781815481106108b1576108b0613976565b5b906000526020600020906005020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1692506108ef83866114c4565b82828151811061090257610901613976565b5b60200260200101819052508080610918906139d4565b915050610890565b508092505050919050565b60006109356123a8565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036109a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099b90613a8e565b60405180910390fd5b6109b882600f61245290919063ffffffff16565b9050919050565b6109c76123a8565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610a36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2d90613afa565b60405180910390fd5b610a41600c82612482565b15610a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7890613b8c565b60405180910390fd5b610a8c600c826124b2565b50610a956113e0565b6000600a544211610aa857600a54610aaa565b425b9050610ac18360095461243c90919063ffffffff16565b60098190555060076040518060a001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001858152602001600081526020018381526020016000815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015560408201518160020155606082015181600301556080820151816004015550506001600780549050610bb4919061389f565b600e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050565b610c046123a8565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610c5f91906135fe565b602060405180830381865afa158015610c7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca09190613bc1565b811115610ce2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cd990613c60565b60405180910390fd5b610d2f3382600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166124e29092919063ffffffff16565b50565b610d4d610d3d612568565b600f61248290919063ffffffff16565b610d8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d8390613ccc565b60405180910390fd5b600042600b5411610d9e576000610db4565b610db342600b5461242690919063ffffffff16565b5b90506000600554905080821015610dd8578181610dd1919061389f565b9050610ddd565b600090505b610de78382612570565b505050565b600060078381548110610e0257610e01613976565b5b9060005260206000209060050201905060006008600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508281600001541015610ead576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea490613d5e565b60405180910390fd5b610eb68461113d565b6000610f038260010154610ef5670de0b6b3a7640000610ee78760040154876000015461280a90919063ffffffff16565b61282090919063ffffffff16565b61242690919063ffffffff16565b90506000841115610f9c57610f2584836000015461242690919063ffffffff16565b8260000181905550610f4484846002015461242690919063ffffffff16565b8360020181905550610f9b33858560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166124e29092919063ffffffff16565b5b610fd1670de0b6b3a7640000610fc38560040154856000015461280a90919063ffffffff16565b61282090919063ffffffff16565b8260010181905550600080821115611098576000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161104091906135fe565b602060405180830381865afa15801561105d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110819190613bc1565b905082811061109257829150611096565b8091505b505b6110e53382600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166124e29092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568868360405161112d929190613619565b60405180910390a2505050505050565b60006007828154811061115357611152613976565b5b90600052602060002090600502019050806003015442116111745750611243565b60008160020154905060008103611195574282600301819055505050611243565b60006111a5836003015442611791565b905060006111e86009546111da86600101546111cc6004548761280a90919063ffffffff16565b61280a90919063ffffffff16565b61282090919063ffffffff16565b905061122d61121a8461120c670de0b6b3a76400008561280a90919063ffffffff16565b61282090919063ffffffff16565b856004015461243c90919063ffffffff16565b8460040181905550428460030181905550505050505b50565b60006007828154811061125c5761125b613976565b5b9060005260206000209060050201905060006008600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000816000015490508160000154836002015410611300576112f38260000154846002015461242690919063ffffffff16565b836002018190555061130b565b600083600201819055505b600082600001819055506000826001018190555061136e33828560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166124e29092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd969583600001546040516113b891906135d4565b60405180910390a250505050565b6113ce6123a8565b6113d66113e0565b8060068190555050565b6000600780549050905060005b8181101561140f576113fe8161113d565b80611408906139d4565b90506113ed565b5050565b6060600060078054905067ffffffffffffffff811115611436576114356139a5565b5b60405190808252806020026020018201604052801561146f57816020015b61145c612e5c565b8152602001906001900390816114545790505b50905060005b6007805490508110156114bc5761148b81611aa5565b82828151811061149e5761149d613976565b5b602002602001018190525080806114b4906139d4565b915050611475565b508091505090565b6114cc612e3b565b6000600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006008600083815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806040016040529081600082015481526020016001820154815250509050600061158f8386611845565b905060008673ffffffffffffffffffffffffffffffffffffffff166370a08231876040518263ffffffff1660e01b81526004016115cc91906135fe565b602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d9190613bc1565b90506040518060600160405280846000015181526020018381526020018281525094505050505092915050565b6116426123a8565b61164c6000612836565b565b611669611659612568565b600f61248290919063ffffffff16565b6116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169f90613ccc565b60405180910390fd5b6116b28282612570565b5050565b6116be6123a8565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361172d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172490613df0565b60405180910390fd5b61174181600f6124b290919063ffffffff16565b5050565b60025481565b600a5481565b6117596123a8565b42600b81905550565b60065481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600b5482116117ca576117c36006546117b5858561242690919063ffffffff16565b61280a90919063ffffffff16565b9050611808565b600b5483106117dc5760009050611808565b6118056006546117f785600b5461242690919063ffffffff16565b61280a90919063ffffffff16565b90505b92915050565b60045481565b6008602052816000526040600020602052806000526040600020600091509150508060000154908060010154905082565b60006001600780549050611859919061389f565b83111561189b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161189290613956565b60405180910390fd5b6000600784815481106118b1576118b0613976565b5b9060005260206000209060050201905060006008600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008260040154905060008360020154905083600301544211801561193b575060008114155b156119d9576000611950856003015442611791565b9050600061199360095461198588600101546119776004548761280a90919063ffffffff16565b61280a90919063ffffffff16565b61282090919063ffffffff16565b90506119d46119c5846119b7670de0b6b3a76400008561280a90919063ffffffff16565b61282090919063ffffffff16565b8561243c90919063ffffffff16565b935050505b611a208360010154611a12670de0b6b3a7640000611a0486886000015461280a90919063ffffffff16565b61282090919063ffffffff16565b61242690919063ffffffff16565b94505050505092915050565b60055481565b611a3a6123a8565b60008111611a7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a7490613e82565b60405180910390fd5b8060058190555050565b600e6020528060005260406000206000915090505481565b60035481565b611aad612e5c565b6007805490508210611af4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aeb90613f14565b60405180910390fd5b600060078381548110611b0a57611b09613976565b5b90600052602060002090600502016040518060a00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481526020016003820154815260200160048201548152505090506000816000015190506000611bdb600954611bcd600454866020015161280a90919063ffffffff16565b61282090919063ffffffff16565b9050604051806101a00160405280868152602001846020015181526020018460600151815260200182815260200184608001518152602001846040015181526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611c84573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611cad919061402b565b81526020018373ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015611cfd573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611d26919061402b565b81526020018373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9a91906140a0565b60ff168152602001600a548152602001600b5481526020016002548152509350505050919050565b6060611dce600f6128fa565b905090565b6001600780549050611de5919061389f565b821115611e27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1e90613956565b60405180910390fd5b600060078381548110611e3d57611e3c613976565b5b9060005260206000209060050201905060006008600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050611eaa8461113d565b60008082600001541115611fc7576000611f058360010154611ef7670de0b6b3a7640000611ee98860040154886000015461280a90919063ffffffff16565b61282090919063ffffffff16565b61242690919063ffffffff16565b90506000811115611fc5576000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611f6d91906135fe565b602060405180830381865afa158015611f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fae9190613bc1565b9050818110611fbf57819250611fc3565b8092505b505b505b60008411156122105760008360000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161202f91906135fe565b602060405180830381865afa15801561204c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120709190613bc1565b90506120c33330878760000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661291b909392919063ffffffff16565b612173818560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161212491906135fe565b602060405180830381865afa158015612141573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121659190613bc1565b61242690919063ffffffff16565b945060035461218f84600001548761243c90919063ffffffff16565b11156121d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121c79061413f565b60405180910390fd5b6121e785846000015461243c90919063ffffffff16565b836000018190555061220685856002015461243c90919063ffffffff16565b8460020181905550505b612245670de0b6b3a76400006122378560040154856000015461280a90919063ffffffff16565b61282090919063ffffffff16565b826001018190555060008111156122a4576122a33382600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166124e29092919063ffffffff16565b5b3373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c856040516122ea91906135d4565b60405180910390a25050505050565b600b5481565b6123076123a8565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612376576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236d906141d1565b60405180910390fd5b61237f81612836565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6123b0612568565b73ffffffffffffffffffffffffffffffffffffffff166123ce611768565b73ffffffffffffffffffffffffffffffffffffffff1614612424576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161241b9061423d565b60405180910390fd5b565b60008183612434919061389f565b905092915050565b6000818361244a919061425d565b905092915050565b600061247a836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6129a4565b905092915050565b60006124aa836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612ab8565b905092915050565b60006124da836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612adb565b905092915050565b6125638363a9059cbb60e01b8484604051602401612501929190614291565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612b4b565b505050565b600033905090565b6125786113e0565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016125d591906135fe565b602060405180830381865afa1580156125f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126169190613bc1565b905061266e612623612568565b3085600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661291b909392919063ffffffff16565b600061271e82600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016126cf91906135fe565b602060405180830381865afa1580156126ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127109190613bc1565b61242690919063ffffffff16565b9050600042600b5411612732576000612748565b61274742600b5461242690919063ffffffff16565b5b905060006127618260045461280a90919063ffffffff16565b9050612776828661243c90919063ffffffff16565b945061278b838261243c90919063ffffffff16565b90506127a0858261282090919063ffffffff16565b600481905550600a5442106127cd576127c2854261243c90919063ffffffff16565b600b819055506127e9565b6127e285600a5461243c90919063ffffffff16565b600b819055505b82600260008282546127fb919061425d565b92505081905550505050505050565b6000818361281891906142ba565b905092915050565b6000818361282e919061432b565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6060600061290a83600001612c12565b905060608190508092505050919050565b61299e846323b872dd60e01b85858560405160240161293c9392919061435c565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612b4b565b50505050565b60008083600101600084815260200190815260200160002054905060008114612aac5760006001826129d6919061389f565b90506000600186600001805490506129ee919061389f565b9050818114612a5d576000866000018281548110612a0f57612a0e613976565b5b9060005260206000200154905080876000018481548110612a3357612a32613976565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480612a7157612a70614393565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612ab2565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000612ae78383612ab8565b612b40578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612b45565b600090505b92915050565b6000612bad826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612c6e9092919063ffffffff16565b9050600081511115612c0d5780806020019051810190612bcd91906143ee565b612c0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c039061448d565b60405180910390fd5b5b505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015612c6257602002820191906000526020600020905b815481526020019060010190808311612c4e575b50505050509050919050565b6060612c7d8484600085612c86565b90509392505050565b606082471015612ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cc29061451f565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612cf49190614586565b60006040518083038185875af1925050503d8060008114612d31576040519150601f19603f3d011682016040523d82523d6000602084013e612d36565b606091505b5091509150612d4787838387612d53565b92505050949350505050565b60608315612db5576000835103612dad57612d6d85612dc8565b612dac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612da3906145e9565b60405180910390fd5b5b829050612dc0565b612dbf8383612deb565b5b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600082511115612dfe5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e329190614642565b60405180910390fd5b60405180606001604052806000815260200160008152602001600081525090565b604051806101a00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016060815260200160608152602001600060ff1681526020016000815260200160008152602001600081525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b612f0481612ef1565b8114612f0f57600080fd5b50565b600081359050612f2181612efb565b92915050565b600060208284031215612f3d57612f3c612ee7565b5b6000612f4b84828501612f12565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000612f99612f94612f8f84612f54565b612f74565b612f54565b9050919050565b6000612fab82612f7e565b9050919050565b6000612fbd82612fa0565b9050919050565b612fcd81612fb2565b82525050565b612fdc81612ef1565b82525050565b600060a082019050612ff76000830188612fc4565b6130046020830187612fd3565b6130116040830186612fd3565b61301e6060830185612fd3565b61302b6080830184612fd3565b9695505050505050565b6000806040838503121561304c5761304b612ee7565b5b600061305a85828601612f12565b925050602061306b85828601612f12565b9150509250929050565b600061308082612f54565b9050919050565b61309081613075565b811461309b57600080fd5b50565b6000813590506130ad81613087565b92915050565b6000602082840312156130c9576130c8612ee7565b5b60006130d78482850161309e565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61311581612ef1565b82525050565b606082016000820151613131600085018261310c565b506020820151613144602085018261310c565b506040820151613157604085018261310c565b50505050565b6000613169838361311b565b60608301905092915050565b6000602082019050919050565b600061318d826130e0565b61319781856130eb565b93506131a2836130fc565b8060005b838110156131d35781516131ba888261315d565b97506131c583613175565b9250506001810190506131a6565b5085935050505092915050565b600060208201905081810360008301526131fa8184613182565b905092915050565b60008115159050919050565b61321781613202565b82525050565b6000602082019050613232600083018461320e565b92915050565b6000806040838503121561324f5761324e612ee7565b5b600061325d85828601612f12565b925050602061326e8582860161309e565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6132ad81613075565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b838110156132ed5780820151818401526020810190506132d2565b60008484015250505050565b6000601f19601f8301169050919050565b6000613315826132b3565b61331f81856132be565b935061332f8185602086016132cf565b613338816132f9565b840191505092915050565b600060ff82169050919050565b61335981613343565b82525050565b60006101a083016000830151613378600086018261310c565b50602083015161338b602086018261310c565b50604083015161339e604086018261310c565b5060608301516133b1606086018261310c565b5060808301516133c4608086018261310c565b5060a08301516133d760a086018261310c565b5060c08301516133ea60c08601826132a4565b5060e083015184820360e0860152613402828261330a565b91505061010083015184820361010086015261341e828261330a565b915050610120830151613435610120860182613350565b5061014083015161344a61014086018261310c565b5061016083015161345f61016086018261310c565b5061018083015161347461018086018261310c565b508091505092915050565b600061348b838361335f565b905092915050565b6000602082019050919050565b60006134ab82613278565b6134b58185613283565b9350836020820285016134c785613294565b8060005b8581101561350357848403895281516134e4858261347f565b94506134ef83613493565b925060208a019950506001810190506134cb565b50829750879550505050505092915050565b6000602082019050818103600083015261352f81846134a0565b905092915050565b6000806040838503121561354e5761354d612ee7565b5b600061355c8582860161309e565b925050602061356d8582860161309e565b9150509250929050565b60608201600082015161358d600085018261310c565b5060208201516135a0602085018261310c565b5060408201516135b3604085018261310c565b50505050565b60006060820190506135ce6000830184613577565b92915050565b60006020820190506135e96000830184612fd3565b92915050565b6135f881613075565b82525050565b600060208201905061361360008301846135ef565b92915050565b600060408201905061362e6000830185612fd3565b61363b6020830184612fd3565b9392505050565b60006101a08301600083015161365b600086018261310c565b50602083015161366e602086018261310c565b506040830151613681604086018261310c565b506060830151613694606086018261310c565b5060808301516136a7608086018261310c565b5060a08301516136ba60a086018261310c565b5060c08301516136cd60c08601826132a4565b5060e083015184820360e08601526136e5828261330a565b915050610100830151848203610100860152613701828261330a565b915050610120830151613718610120860182613350565b5061014083015161372d61014086018261310c565b5061016083015161374261016086018261310c565b5061018083015161375761018086018261310c565b508091505092915050565b6000602082019050818103600083015261377c8184613642565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006137bc83836132a4565b60208301905092915050565b6000602082019050919050565b60006137e082613784565b6137ea818561378f565b93506137f5836137a0565b8060005b8381101561382657815161380d88826137b0565b9750613818836137c8565b9250506001810190506137f9565b5085935050505092915050565b6000602082019050818103600083015261384d81846137d5565b905092915050565b600060208201905061386a6000830184612fc4565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006138aa82612ef1565b91506138b583612ef1565b92508282039050818111156138cd576138cc613870565b5b92915050565b600082825260208201905092915050565b7f41495345414c6971756964697479506f6f6c3a2043616e206e6f742066696e6460008201527f207468697320706f6f6c00000000000000000000000000000000000000000000602082015250565b6000613940602a836138d3565b915061394b826138e4565b604082019050919050565b6000602082019050818103600083015261396f81613933565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006139df82612ef1565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613a1157613a10613870565b5b600182019050919050565b7f41495345414c6971756964697479506f6f6c3a2063616c6c657220697320746860008201527f65207a65726f2061646472657373000000000000000000000000000000000000602082015250565b6000613a78602e836138d3565b9150613a8382613a1c565b604082019050919050565b60006020820190508181036000830152613aa781613a6b565b9050919050565b7f5f746f6b656e20697320746865207a65726f2061646472657373000000000000600082015250565b6000613ae4601a836138d3565b9150613aef82613aae565b602082019050919050565b60006020820190508181036000830152613b1381613ad7565b9050919050565b7f5f746f6b656e20697320616c726561647920616464656420746f20746865207060008201527f6f6f6c0000000000000000000000000000000000000000000000000000000000602082015250565b6000613b766023836138d3565b9150613b8182613b1a565b604082019050919050565b60006020820190508181036000830152613ba581613b69565b9050919050565b600081519050613bbb81612efb565b92915050565b600060208284031215613bd757613bd6612ee7565b5b6000613be584828501613bac565b91505092915050565b7f41495345414c6971756964697479506f6f6c3a206e6f7420656e6f756768207460008201527f6f6b656e00000000000000000000000000000000000000000000000000000000602082015250565b6000613c4a6024836138d3565b9150613c5582613bee565b604082019050919050565b60006020820190508181036000830152613c7981613c3d565b9050919050565b7f6f6e6c7943616c6c657200000000000000000000000000000000000000000000600082015250565b6000613cb6600a836138d3565b9150613cc182613c80565b602082019050919050565b60006020820190508181036000830152613ce581613ca9565b9050919050565b7f41495345414c6971756964697479506f6f6c3a2057697468647261772077697460008201527f6820696e73756666696369656e742062616c616e636500000000000000000000602082015250565b6000613d486036836138d3565b9150613d5382613cec565b604082019050919050565b60006020820190508181036000830152613d7781613d3b565b9050919050565b7f41495345414c6971756964697479506f6f6c3a2076616c20697320746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b6000613dda602b836138d3565b9150613de582613d7e565b604082019050919050565b60006020820190508181036000830152613e0981613dcd565b9050919050565b7f41495345414c6971756964697479506f6f6c3a20696e74657276616c206d757360008201527f742062652067726561746572207468616e203000000000000000000000000000602082015250565b6000613e6c6033836138d3565b9150613e7782613e10565b604082019050919050565b60006020820190508181036000830152613e9b81613e5f565b9050919050565b7f41495345414c6971756964697479506f6f6c3a20706964206f7574206f66207260008201527f616e676500000000000000000000000000000000000000000000000000000000602082015250565b6000613efe6024836138d3565b9150613f0982613ea2565b604082019050919050565b60006020820190508181036000830152613f2d81613ef1565b9050919050565b600080fd5b600080fd5b613f47826132f9565b810181811067ffffffffffffffff82111715613f6657613f656139a5565b5b80604052505050565b6000613f79612edd565b9050613f858282613f3e565b919050565b600067ffffffffffffffff821115613fa557613fa46139a5565b5b613fae826132f9565b9050602081019050919050565b6000613fce613fc984613f8a565b613f6f565b905082815260208101848484011115613fea57613fe9613f39565b5b613ff58482856132cf565b509392505050565b600082601f83011261401257614011613f34565b5b8151614022848260208601613fbb565b91505092915050565b60006020828403121561404157614040612ee7565b5b600082015167ffffffffffffffff81111561405f5761405e612eec565b5b61406b84828501613ffd565b91505092915050565b61407d81613343565b811461408857600080fd5b50565b60008151905061409a81614074565b92915050565b6000602082840312156140b6576140b5612ee7565b5b60006140c48482850161408b565b91505092915050565b7f41495345414c6971756964697479506f6f6c3a20657863656564206d6178207360008201527f74616b6500000000000000000000000000000000000000000000000000000000602082015250565b60006141296024836138d3565b9150614134826140cd565b604082019050919050565b600060208201905081810360008301526141588161411c565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006141bb6026836138d3565b91506141c68261415f565b604082019050919050565b600060208201905081810360008301526141ea816141ae565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006142276020836138d3565b9150614232826141f1565b602082019050919050565b600060208201905081810360008301526142568161421a565b9050919050565b600061426882612ef1565b915061427383612ef1565b925082820190508082111561428b5761428a613870565b5b92915050565b60006040820190506142a660008301856135ef565b6142b36020830184612fd3565b9392505050565b60006142c582612ef1565b91506142d083612ef1565b92508282026142de81612ef1565b915082820484148315176142f5576142f4613870565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061433682612ef1565b915061434183612ef1565b925082614351576143506142fc565b5b828204905092915050565b600060608201905061437160008301866135ef565b61437e60208301856135ef565b61438b6040830184612fd3565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6143cb81613202565b81146143d657600080fd5b50565b6000815190506143e8816143c2565b92915050565b60006020828403121561440457614403612ee7565b5b6000614412848285016143d9565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000614477602a836138d3565b91506144828261441b565b604082019050919050565b600060208201905081810360008301526144a68161446a565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006145096026836138d3565b9150614514826144ad565b604082019050919050565b60006020820190508181036000830152614538816144fc565b9050919050565b600081519050919050565b600081905092915050565b60006145608261453f565b61456a818561454a565b935061457a8185602086016132cf565b80840191505092915050565b60006145928284614555565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006145d3601d836138d3565b91506145de8261459d565b602082019050919050565b60006020820190508181036000830152614602816145c6565b9050919050565b6000614614826132b3565b61461e81856138d3565b935061462e8185602086016132cf565b614637816132f9565b840191505092915050565b6000602082019050818103600083015261465c8184614609565b90509291505056fea264697066735822122056c63f0f5d983ab8070c83af96b2d54d52098b991c7f2ba94aa86d4a0e175c7964736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000912ce59144191c1204e64559fe8253a0e49e6548000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000645f276000000000000000000000000000000000000000000000000000000000645f2760ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-----Decoded View---------------
Arg [0] : _rewardToken (address): 0x912CE59144191C1204E64559FE8253a0e49E6548
Arg [1] : _rewardPerSecond (uint256): 0
Arg [2] : _startTime (uint256): 1683957600
Arg [3] : _bonusEndTime (uint256): 1683957600
Arg [4] : _maxStakingPerUser (uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000912ce59144191c1204e64559fe8253a0e49e6548
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [2] : 00000000000000000000000000000000000000000000000000000000645f2760
Arg [3] : 00000000000000000000000000000000000000000000000000000000645f2760
Arg [4] : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Deployed Bytecode Sourcemap
59529:14185:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63774:108;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;61041:26;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;63267:340;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72713:374;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73274:206;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62456:803;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70636:247;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67350:465;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68935:1107;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64973:684;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70050:578;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63615:151;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;65665:180;;;:::i;:::-;;71907:276;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72191:514;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44534:103;;;:::i;:::-;;67823:154;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73095:171;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60833:26;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61189:24;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62004:88;;;:::i;:::-;;60997:35;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43886:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62100:348;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60905:30;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61074:64;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;64107:858;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60942:46;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63890:209;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;61300:42;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60866:32;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70891:1008;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73488:108;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65853:1489;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;61220:27;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44792:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60801:25;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63774:108;43772:13;:11;:13::i;:::-;63868:6:::1;63848:17;:26;;;;63774:108:::0;:::o;61041:26::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;63267:340::-;43772:13;:11;:13::i;:::-;63377:1:::1;63359:8;:15;;;;:19;;;;:::i;:::-;63351:4;:27;;63343:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;63438:17;:15;:17::i;:::-;63486:63;63537:11;63486:46;63506:8;63515:4;63506:14;;;;;;;;:::i;:::-;;;;;;;;;;;;:25;;;63486:15;;:19;;:46;;;;:::i;:::-;:50;;:63;;;;:::i;:::-;63468:15;:81;;;;63588:11;63560:8;63569:4;63560:14;;;;;;;;:::i;:::-;;;;;;;;;;;;:25;;:39;;;;63267:340:::0;;:::o;72713:374::-;72775:17;72805:13;72829:23;72870:8;:15;;;;72855:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;72829:57;;72902:9;72897:160;72921:8;:15;;;;72917:1;:19;72897:160;;;72974:8;72983:1;72974:11;;;;;;;;:::i;:::-;;;;;;;;;;;;:17;;;;;;;;;;;;72958:34;;73018:27;73030:5;73037:7;73018:11;:27::i;:::-;73007:5;73013:1;73007:8;;;;;;;;:::i;:::-;;;;;;;:38;;;;72938:3;;;;;:::i;:::-;;;;72897:160;;;;73074:5;73067:12;;;;72713:374;;;:::o;73274:206::-;73335:4;43772:13;:11;:13::i;:::-;73378:1:::1;73360:20;;:6;:20;;::::0;73352:79:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;73449:23;73465:6;73449:8;:15;;:23;;;;:::i;:::-;73442:30;;73274:206:::0;;;:::o;62456:803::-;43772:13;:11;:13::i;:::-;62560:1:::1;62542:20;;:6;:20;;::::0;62534:59:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;62615:38;62638:6;62646;62615:22;:38::i;:::-;62614:39;62606:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;62704:33;62722:6;62730;62704:17;:33::i;:::-;;62750:17;:15;:17::i;:::-;62780:22;62823:9;;62805:15;:27;:57;;62853:9;;62805:57;;;62835:15;62805:57;62780:82;;62891:32;62911:11;62891:15;;:19;;:32;;;;:::i;:::-;62873:15;:50;;;;62934:8;62962:230;;;;;;;;63004:6;62962:230;;;;;;63042:11;62962:230;;;;63086:1;62962:230;;;;63122:14;62962:230;;;;63175:1;62962:230;;::::0;62934:269:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63250:1;63232:8;:15;;;;:19;;;;:::i;:::-;63214:7;:15;63222:6;63214:15;;;;;;;;;;;;;;;:37;;;;62523:736;62456:803:::0;;:::o;70636:247::-;43772:13;:11;:13::i;:::-;70733:11:::1;;;;;;;;;;;:21;;;70763:4;70733:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;70722:7;:47;;70714:96;;;;;;;;;;;;:::i;:::-;;;;;;;;;70821:54;70854:10;70867:7;70821:11;;;;;;;;;;;:24;;;;:54;;;;;:::i;:::-;70636:247:::0;:::o;67350:465::-;73645:31;73663:12;:10;:12::i;:::-;73645:8;:17;;:31;;;;:::i;:::-;73637:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;67418:24:::1;67460:15;67445:12;;:30;:70;;67514:1;67445:70;;;67478:33;67495:15;67478:12;;:16;;:33;;;;:::i;:::-;67445:70;67418:97;;67526:22;67551;;67526:47;;67607:14;67588:16;:33;67584:167;;;67672:16;67655:14;:33;;;;:::i;:::-;67638:50;;67584:167;;;67738:1;67721:18;;67584:167;67761:46;67784:6;67792:14;67761:22;:46::i;:::-;67407:408;;67350:465:::0;:::o;68935:1107::-;69002:21;69026:8;69035:4;69026:14;;;;;;;;:::i;:::-;;;;;;;;;;;;69002:38;;69051:21;69075:8;:14;69084:4;69075:14;;;;;;;;;;;:26;69090:10;69075:26;;;;;;;;;;;;;;;69051:50;;69135:7;69120:4;:11;;;:22;;69112:89;;;;;;;;;;;;:::i;:::-;;;;;;;;;69214:16;69225:4;69214:10;:16::i;:::-;69243:15;69261:71;69316:4;:15;;;69261:50;69306:4;69261:40;69277:4;:23;;;69261:4;:11;;;:15;;:40;;;;:::i;:::-;:44;;:50;;;;:::i;:::-;:54;;:71;;;;:::i;:::-;69243:89;;69366:1;69356:7;:11;69353:214;;;69398:24;69414:7;69398:4;:11;;;:15;;:24;;;;:::i;:::-;69384:4;:11;;:38;;;;69457:30;69479:7;69457:4;:17;;;:21;;:30;;;;:::i;:::-;69437:4;:17;;:50;;;;69502:53;69534:10;69547:7;69502:4;:10;;;;;;;;;;;;:23;;;;:53;;;;;:::i;:::-;69353:214;69595:50;69640:4;69595:40;69611:4;:23;;;69595:4;:11;;;:15;;:40;;;;:::i;:::-;:44;;:50;;;;:::i;:::-;69577:4;:15;;:68;;;;69658:15;69697:1;69687:7;:11;69684:232;;;69715:11;69729;;;;;;;;;;;:21;;;69759:4;69729:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;69715:50;;69790:7;69783:3;:14;69780:125;;69828:7;69818:17;;69780:125;;;69886:3;69876:13;;69780:125;69700:216;69684:232;69926:54;69959:10;69972:7;69926:11;;;;;;;;;;;:24;;;;:54;;;;;:::i;:::-;70005:10;69996:38;;;70017:7;70026;69996:38;;;;;;;:::i;:::-;;;;;;;;68991:1051;;;;68935:1107;;:::o;64973:684::-;65025:21;65049:8;65058:4;65049:14;;;;;;;;:::i;:::-;;;;;;;;;;;;65025:38;;65097:4;:19;;;65078:15;:38;65074:77;;65133:7;;;65074:77;65161:16;65180:4;:17;;;65161:36;;65224:1;65212:8;:13;65208:104;;65264:15;65242:4;:19;;:37;;;;65294:7;;;;65208:104;65322:18;65343:51;65357:4;:19;;;65378:15;65343:13;:51::i;:::-;65322:72;;65405:19;65427:73;65484:15;;65427:52;65463:4;:15;;;65427:31;65442:15;;65427:10;:14;;:31;;;;:::i;:::-;:35;;:52;;;;:::i;:::-;:56;;:73;;;;:::i;:::-;65405:95;;65537:64;65565:35;65591:8;65565:21;65581:4;65565:11;:15;;:21;;;;:::i;:::-;:25;;:35;;;;:::i;:::-;65537:4;:23;;;:27;;:64;;;;:::i;:::-;65511:4;:23;;:90;;;;65634:15;65612:4;:19;;:37;;;;65014:643;;;;64973:684;;:::o;70050:578::-;70109:21;70133:8;70142:4;70133:14;;;;;;;;:::i;:::-;;;;;;;;;;;;70109:38;;70158:21;70182:8;:14;70191:4;70182:14;;;;;;;;;;;:26;70197:10;70182:26;;;;;;;;;;;;;;;70158:50;;70221:14;70238:4;:11;;;70221:28;;70294:4;:11;;;70273:4;:17;;;:32;70270:172;;70342:34;70364:4;:11;;;70342:4;:17;;;:21;;:34;;;;:::i;:::-;70322:4;:17;;:54;;;;70270:172;;;70429:1;70409:4;:17;;:21;;;;70270:172;70466:1;70452:4;:11;;:15;;;;70496:1;70478:4;:15;;:19;;;;70510:52;70542:10;70555:6;70510:4;:10;;;;;;;;;;;;:23;;;;:52;;;;;:::i;:::-;70596:10;70578:42;;;70608:4;:11;;;70578:42;;;;;;:::i;:::-;;;;;;;;70098:530;;;70050:578;:::o;63615:151::-;43772:13;:11;:13::i;:::-;63695:17:::1;:15;:17::i;:::-;63742:16;63723;:35;;;;63615:151:::0;:::o;65665:180::-;65710:14;65727:8;:15;;;;65710:32;;65758:11;65753:85;65781:6;65775:3;:12;65753:85;;;65811:15;65822:3;65811:10;:15::i;:::-;65789:5;;;;:::i;:::-;;;65753:85;;;;65699:146;65665:180::o;71907:276::-;71957:17;71987:23;72028:8;:15;;;;72013:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;71987:57;;72060:9;72055:98;72079:8;:15;;;;72075:1;:19;72055:98;;;72127:14;72139:1;72127:11;:14::i;:::-;72116:5;72122:1;72116:8;;;;;;;;:::i;:::-;;;;;;;:25;;;;72096:3;;;;;:::i;:::-;;;;72055:98;;;;72170:5;72163:12;;;71907:276;:::o;72191:514::-;72265:15;;:::i;:::-;72293:11;72307:7;:14;72315:5;72307:14;;;;;;;;;;;;;;;;72293:28;;72332:20;72355:8;:13;72364:3;72355:13;;;;;;;;;;;:22;72369:7;72355:22;;;;;;;;;;;;;;;72332:45;;;;;;;;;;;;;;;;;;;;;;;;;;;72388:24;72415:27;72429:3;72434:7;72415:13;:27::i;:::-;72388:54;;72453:17;72480:5;72473:23;;;72497:7;72473:32;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72453:52;;72536:161;;;;;;;;72578:4;:11;;;72536:161;;;;72626:16;72536:161;;;;72672:9;72536:161;;;72516:181;;;;;;72191:514;;;;:::o;44534:103::-;43772:13;:11;:13::i;:::-;44599:30:::1;44626:1;44599:18;:30::i;:::-;44534:103::o:0;67823:154::-;73645:31;73663:12;:10;:12::i;:::-;73645:8;:17;;:31;;;;:::i;:::-;73637:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;67923:46:::1;67946:6;67954:14;67923:22;:46::i;:::-;67823:154:::0;;:::o;73095:171::-;43772:13;:11;:13::i;:::-;73180:1:::1;73165:17;;:3;:17;;::::0;73157:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;73241:17;73254:3;73241:8;:12;;:17;;;;:::i;:::-;;73095:171:::0;:::o;60833:26::-;;;;:::o;61189:24::-;;;;:::o;62004:88::-;43772:13;:11;:13::i;:::-;62069:15:::1;62054:12;:30;;;;62004:88::o:0;60997:35::-;;;;:::o;43886:87::-;43932:7;43959:6;;;;;;;;;;;43952:13;;43886:87;:::o;62100:348::-;62172:7;62203:12;;62196:3;:19;62192:249;;62240:36;62259:16;;62240:14;62248:5;62240:3;:7;;:14;;;;:::i;:::-;:18;;:36;;;;:::i;:::-;62233:43;;;;62192:249;62307:12;;62298:5;:21;62294:147;;62343:1;62336:8;;;;62294:147;62384:45;62412:16;;62384:23;62401:5;62384:12;;:16;;:23;;;;:::i;:::-;:27;;:45;;;;:::i;:::-;62377:52;;62100:348;;;;;:::o;60905:30::-;;;;:::o;61074:64::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;64107:858::-;64180:7;64234:1;64216:8;:15;;;;:19;;;;:::i;:::-;64208:4;:27;;64200:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;64295:21;64319:8;64328:4;64319:14;;;;;;;;:::i;:::-;;;;;;;;;;;;64295:38;;64344:21;64368:8;:14;64377:4;64368:14;;;;;;;;;;;:21;64383:5;64368:21;;;;;;;;;;;;;;;64344:45;;64400:26;64429:4;:23;;;64400:52;;64463:16;64482:4;:17;;;64463:36;;64532:4;:19;;;64514:15;:37;:54;;;;;64567:1;64555:8;:13;;64514:54;64510:364;;;64585:18;64606:51;64620:4;:19;;;64641:15;64606:13;:51::i;:::-;64585:72;;64672:19;64694:73;64751:15;;64694:52;64730:4;:15;;;64694:31;64709:15;;64694:10;:14;;:31;;;;:::i;:::-;:35;;:52;;;;:::i;:::-;:56;;:73;;;;:::i;:::-;64672:95;;64803:59;64826:35;64852:8;64826:21;64842:4;64826:11;:15;;:21;;;;:::i;:::-;:25;;:35;;;;:::i;:::-;64803:18;:22;;:59;;;;:::i;:::-;64782:80;;64570:304;;64510:364;64891:66;64941:4;:15;;;64891:45;64931:4;64891:35;64907:18;64891:4;:11;;;:15;;:35;;;;:::i;:::-;:39;;:45;;;;:::i;:::-;:49;;:66;;;;:::i;:::-;64884:73;;;;;;64107:858;;;;:::o;60942:46::-;;;;:::o;63890:209::-;43772:13;:11;:13::i;:::-;63990:1:::1;63979:8;:12;63971:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;64083:8;64058:22;:33;;;;63890:209:::0;:::o;61300:42::-;;;;;;;;;;;;;;;;;:::o;60866:32::-;;;;:::o;70891:1008::-;70946:15;;:::i;:::-;70988:8;:15;;;;70982:3;:21;70974:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;71055:20;71078:8;71087:3;71078:13;;;;;;;;:::i;:::-;;;;;;;;;;;;71055:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71102:20;71148:4;:10;;;71102:58;;71171:24;71198:57;71239:15;;71198:36;71218:15;;71198:4;:15;;;:19;;:36;;;;:::i;:::-;:40;;:57;;;;:::i;:::-;71171:84;;71286:605;;;;;;;;71319:3;71286:605;;;;71353:4;:15;;;71286:605;;;;71403:4;:19;;;71286:605;;;;71520:16;71286:605;;;;71460:4;:23;;;71286:605;;;;71568:4;:17;;;71286:605;;;;71619:5;71286:605;;;;;;71652:5;:12;;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71286:605;;;;71691:5;:10;;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71286:605;;;;71732:5;:14;;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71286:605;;;;;;71778:9;;71286:605;;;;71820:12;;71286:605;;;;71864:11;;71286:605;;;71266:625;;;;;70891:1008;;;:::o;73488:108::-;73531:20;73571:17;:8;:15;:17::i;:::-;73564:24;;73488:108;:::o;65853:1489::-;65953:1;65935:8;:15;;;;:19;;;;:::i;:::-;65927:4;:27;;65919:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;66014:21;66038:8;66047:4;66038:14;;;;;;;;:::i;:::-;;;;;;;;;;;;66014:38;;66063:21;66087:8;:14;66096:4;66087:14;;;;;;;;;;;:26;66102:10;66087:26;;;;;;;;;;;;;;;66063:50;;66126:16;66137:4;66126:10;:16::i;:::-;66163:14;66206:1;66192:4;:11;;;:15;66188:409;;;66224:15;66242:71;66297:4;:15;;;66242:50;66287:4;66242:40;66258:4;:23;;;66242:4;:11;;;:15;;:40;;;;:::i;:::-;:44;;:50;;;;:::i;:::-;:54;;:71;;;;:::i;:::-;66224:89;;66341:1;66331:7;:11;66328:258;;;66363:11;66377;;;;;;;;;;;:21;;;66407:4;66377:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66363:50;;66442:7;66435:3;:14;66432:139;;66483:7;66474:16;;66432:139;;;66548:3;66539:12;;66432:139;66344:242;66328:258;66209:388;66188:409;66622:1;66612:7;:11;66609:485;;;66640:14;66657:4;:10;;;;;;;;;;;;:20;;;66686:4;66657:35;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66640:52;;66707:72;66743:10;66764:4;66771:7;66707:4;:10;;;;;;;;;;;;:27;;;;:72;;;;;;:::i;:::-;66804:47;66844:6;66804:4;:10;;;;;;;;;;;;:20;;;66833:4;66804:35;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:39;;:47;;;;:::i;:::-;66794:57;;66904:17;;66876:24;66888:4;:11;;;66876:7;:11;;:24;;;;:::i;:::-;:45;;66868:94;;;;;;;;;;;;:::i;:::-;;;;;;;;;66993:24;67009:7;66993:4;:11;;;:15;;:24;;;;:::i;:::-;66979:4;:11;;:38;;;;67052:30;67074:7;67052:4;:17;;;:21;;:30;;;;:::i;:::-;67032:4;:17;;:50;;;;66625:469;66609:485;67122:50;67167:4;67122:40;67138:4;:23;;;67122:4;:11;;;:15;;:40;;;;:::i;:::-;:44;;:50;;;;:::i;:::-;67104:4;:15;;:68;;;;67198:1;67189:6;:10;67185:96;;;67216:53;67249:10;67262:6;67216:11;;;;;;;;;;;:24;;;;:53;;;;;:::i;:::-;67185:96;67314:10;67306:28;;;67326:7;67306:28;;;;;;:::i;:::-;;;;;;;;65908:1434;;;65853:1489;;:::o;61220:27::-;;;;:::o;44792:201::-;43772:13;:11;:13::i;:::-;44901:1:::1;44881:22;;:8;:22;;::::0;44873:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;44957:28;44976:8;44957:18;:28::i;:::-;44792:201:::0;:::o;60801:25::-;;;;;;;;;;;;;:::o;44051:132::-;44126:12;:10;:12::i;:::-;44115:23;;:7;:5;:7::i;:::-;:23;;;44107:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;44051:132::o;3288:98::-;3346:7;3377:1;3373;:5;;;;:::i;:::-;3366:12;;3288:98;;;;:::o;2907:::-;2965:7;2996:1;2992;:5;;;;:::i;:::-;2985:12;;2907:98;;;;:::o;54253:158::-;54326:4;54350:53;54358:3;:10;;54394:5;54378:23;;54370:32;;54350:7;:53::i;:::-;54343:60;;54253:158;;;;:::o;54497:167::-;54577:4;54601:55;54611:3;:10;;54647:5;54631:23;;54623:32;;54601:9;:55::i;:::-;54594:62;;54497:167;;;;:::o;53925:152::-;53995:4;54019:50;54024:3;:10;;54060:5;54044:23;;54036:32;;54019:4;:50::i;:::-;54012:57;;53925:152;;;;:::o;38865:211::-;38982:86;39002:5;39032:23;;;39057:2;39061:5;39009:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38982:19;:86::i;:::-;38865:211;;;:::o;20624:98::-;20677:7;20704:10;20697:17;;20624:98;:::o;67985:942::-;68079:17;:15;:17::i;:::-;68109:14;68126:11;;;;;;;;;;;:21;;;68156:4;68126:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68109:53;;68173:65;68202:12;:10;:12::i;:::-;68224:4;68231:6;68173:11;;;;;;;;;;;:28;;;;:65;;;;;;:::i;:::-;68249:18;68270:48;68311:6;68270:11;;;;;;;;;;;:21;;;68300:4;68270:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:40;;:48;;;;:::i;:::-;68249:69;;68331:24;68373:15;68358:12;;:30;:70;;68427:1;68358:70;;;68391:33;68408:15;68391:12;;:16;;:33;;;;:::i;:::-;68358:70;68331:97;;68439:20;68462:37;68482:16;68462:15;;:19;;:37;;;;:::i;:::-;68439:60;;68529:36;68548:16;68529:14;:18;;:36;;;;:::i;:::-;68512:53;;68591:28;68608:10;68591:12;:16;;:28;;;;:::i;:::-;68576:43;;68650:32;68667:14;68650:12;:16;;:32;;;;:::i;:::-;68632:15;:50;;;;68717:9;;68698:15;:28;68695:187;;68758:35;68778:14;68758:15;:19;;:35;;;;:::i;:::-;68743:12;:50;;;;68695:187;;;68841:29;68855:14;68841:9;;:13;;:29;;;;:::i;:::-;68826:12;:44;;;;68695:187;68909:10;68894:11;;:25;;;;;;;:::i;:::-;;;;;;;;68066:861;;;;67985:942;;:::o;3645:98::-;3703:7;3734:1;3730;:5;;;;:::i;:::-;3723:12;;3645:98;;;;:::o;4044:::-;4102:7;4133:1;4129;:5;;;;:::i;:::-;4122:12;;4044:98;;;;:::o;45153:191::-;45227:16;45246:6;;;;;;;;;;;45227:25;;45272:8;45263:6;;:17;;;;;;;;;;;;;;;;;;45327:8;45296:40;;45317:8;45296:40;;;;;;;;;;;;45216:128;45153:191;:::o;55929:310::-;55992:16;56021:22;56046:19;56054:3;:10;;56046:7;:19::i;:::-;56021:44;;56076:23;56190:5;56180:15;;56225:6;56218:13;;;;55929:310;;;:::o;39084:248::-;39228:96;39248:5;39278:27;;;39307:4;39313:2;39317:5;39255:68;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39228:19;:96::i;:::-;39084:248;;;;:::o;48246:1420::-;48312:4;48430:18;48451:3;:12;;:19;48464:5;48451:19;;;;;;;;;;;;48430:40;;48501:1;48487:10;:15;48483:1176;;48862:21;48899:1;48886:10;:14;;;;:::i;:::-;48862:38;;48915:17;48956:1;48935:3;:11;;:18;;;;:22;;;;:::i;:::-;48915:42;;48991:13;48978:9;:26;48974:405;;49025:17;49045:3;:11;;49057:9;49045:22;;;;;;;;:::i;:::-;;;;;;;;;;49025:42;;49199:9;49170:3;:11;;49182:13;49170:26;;;;;;;;:::i;:::-;;;;;;;;;:38;;;;49310:10;49284:3;:12;;:23;49297:9;49284:23;;;;;;;;;;;:36;;;;49006:373;48974:405;49460:3;:11;;:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;49555:3;:12;;:19;49568:5;49555:19;;;;;;;;;;;49548:26;;;49598:4;49591:11;;;;;;;48483:1176;49642:5;49635:12;;;48246:1420;;;;;:::o;49752:129::-;49825:4;49872:1;49849:3;:12;;:19;49862:5;49849:19;;;;;;;;;;;;:24;;49842:31;;49752:129;;;;:::o;47656:414::-;47719:4;47741:21;47751:3;47756:5;47741:9;:21::i;:::-;47736:327;;47779:3;:11;;47796:5;47779:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47962:3;:11;;:18;;;;47940:3;:12;;:19;47953:5;47940:19;;;;;;;;;;;:40;;;;48002:4;47995:11;;;;47736:327;48046:5;48039:12;;47656:414;;;;;:::o;41932:716::-;42356:23;42382:69;42410:4;42382:69;;;;;;;;;;;;;;;;;42390:5;42382:27;;;;:69;;;;;:::i;:::-;42356:95;;42486:1;42466:10;:17;:21;42462:179;;;42563:10;42552:30;;;;;;;;;;;;:::i;:::-;42544:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;42462:179;42002:646;41932:716;;:::o;51100:111::-;51156:16;51192:3;:11;;51185:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51100:111;;;:::o;32717:229::-;32854:12;32886:52;32908:6;32916:4;32922:1;32925:12;32886:21;:52::i;:::-;32879:59;;32717:229;;;;;:::o;33837:455::-;34007:12;34065:5;34040:21;:30;;34032:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;34125:12;34139:23;34166:6;:11;;34185:5;34192:4;34166:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34124:73;;;;34215:69;34242:6;34250:7;34259:10;34271:12;34215:26;:69::i;:::-;34208:76;;;;33837:455;;;;;;:::o;36410:644::-;36595:12;36624:7;36620:427;;;36673:1;36652:10;:17;:22;36648:290;;36870:18;36881:6;36870:10;:18::i;:::-;36862:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;36648:290;36959:10;36952:17;;;;36620:427;37002:33;37010:10;37022:12;37002:7;:33::i;:::-;36410:644;;;;;;;:::o;29960:326::-;30020:4;30277:1;30255:7;:19;;;:23;30248:30;;29960:326;;;:::o;37596:552::-;37777:1;37757:10;:17;:21;37753:388;;;37989:10;37983:17;38046:15;38033:10;38029:2;38025:19;38018:44;37753:388;38116:12;38109:20;;;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:126::-;1062:7;1102:42;1095:5;1091:54;1080:65;;1025:126;;;:::o;1157:60::-;1185:3;1206:5;1199:12;;1157:60;;;:::o;1223:142::-;1273:9;1306:53;1324:34;1333:24;1351:5;1333:24;:::i;:::-;1324:34;:::i;:::-;1306:53;:::i;:::-;1293:66;;1223:142;;;:::o;1371:126::-;1421:9;1454:37;1485:5;1454:37;:::i;:::-;1441:50;;1371:126;;;:::o;1503:141::-;1568:9;1601:37;1632:5;1601:37;:::i;:::-;1588:50;;1503:141;;;:::o;1650:161::-;1752:52;1798:5;1752:52;:::i;:::-;1747:3;1740:65;1650:161;;:::o;1817:118::-;1904:24;1922:5;1904:24;:::i;:::-;1899:3;1892:37;1817:118;;:::o;1941:694::-;2161:4;2199:3;2188:9;2184:19;2176:27;;2213:86;2296:1;2285:9;2281:17;2272:6;2213:86;:::i;:::-;2309:72;2377:2;2366:9;2362:18;2353:6;2309:72;:::i;:::-;2391;2459:2;2448:9;2444:18;2435:6;2391:72;:::i;:::-;2473;2541:2;2530:9;2526:18;2517:6;2473:72;:::i;:::-;2555:73;2623:3;2612:9;2608:19;2599:6;2555:73;:::i;:::-;1941:694;;;;;;;;:::o;2641:474::-;2709:6;2717;2766:2;2754:9;2745:7;2741:23;2737:32;2734:119;;;2772:79;;:::i;:::-;2734:119;2892:1;2917:53;2962:7;2953:6;2942:9;2938:22;2917:53;:::i;:::-;2907:63;;2863:117;3019:2;3045:53;3090:7;3081:6;3070:9;3066:22;3045:53;:::i;:::-;3035:63;;2990:118;2641:474;;;;;:::o;3121:96::-;3158:7;3187:24;3205:5;3187:24;:::i;:::-;3176:35;;3121:96;;;:::o;3223:122::-;3296:24;3314:5;3296:24;:::i;:::-;3289:5;3286:35;3276:63;;3335:1;3332;3325:12;3276:63;3223:122;:::o;3351:139::-;3397:5;3435:6;3422:20;3413:29;;3451:33;3478:5;3451:33;:::i;:::-;3351:139;;;;:::o;3496:329::-;3555:6;3604:2;3592:9;3583:7;3579:23;3575:32;3572:119;;;3610:79;;:::i;:::-;3572:119;3730:1;3755:53;3800:7;3791:6;3780:9;3776:22;3755:53;:::i;:::-;3745:63;;3701:117;3496:329;;;;:::o;3831:140::-;3924:6;3958:5;3952:12;3942:22;;3831:140;;;:::o;3977:210::-;4102:11;4136:6;4131:3;4124:19;4176:4;4171:3;4167:14;4152:29;;3977:210;;;;:::o;4193:158::-;4286:4;4309:3;4301:11;;4339:4;4334:3;4330:14;4322:22;;4193:158;;;:::o;4357:108::-;4434:24;4452:5;4434:24;:::i;:::-;4429:3;4422:37;4357:108;;:::o;4551:698::-;4690:4;4685:3;4681:14;4785:4;4778:5;4774:16;4768:23;4804:63;4861:4;4856:3;4852:14;4838:12;4804:63;:::i;:::-;4705:172;4971:4;4964:5;4960:16;4954:23;4990:63;5047:4;5042:3;5038:14;5024:12;4990:63;:::i;:::-;4887:176;5150:4;5143:5;5139:16;5133:23;5169:63;5226:4;5221:3;5217:14;5203:12;5169:63;:::i;:::-;5073:169;4659:590;4551:698;;:::o;5255:283::-;5376:10;5397:98;5491:3;5483:6;5397:98;:::i;:::-;5527:4;5522:3;5518:14;5504:28;;5255:283;;;;:::o;5544:139::-;5640:4;5672;5667:3;5663:14;5655:22;;5544:139;;;:::o;5773:940::-;5944:3;5973:80;6047:5;5973:80;:::i;:::-;6069:112;6174:6;6169:3;6069:112;:::i;:::-;6062:119;;6205:82;6281:5;6205:82;:::i;:::-;6310:7;6341:1;6326:362;6351:6;6348:1;6345:13;6326:362;;;6427:6;6421:13;6454:115;6565:3;6550:13;6454:115;:::i;:::-;6447:122;;6592:86;6671:6;6592:86;:::i;:::-;6582:96;;6386:302;6373:1;6370;6366:9;6361:14;;6326:362;;;6330:14;6704:3;6697:10;;5949:764;;;5773:940;;;;:::o;6719:477::-;6914:4;6952:2;6941:9;6937:18;6929:26;;7001:9;6995:4;6991:20;6987:1;6976:9;6972:17;6965:47;7029:160;7184:4;7175:6;7029:160;:::i;:::-;7021:168;;6719:477;;;;:::o;7202:90::-;7236:7;7279:5;7272:13;7265:21;7254:32;;7202:90;;;:::o;7298:109::-;7379:21;7394:5;7379:21;:::i;:::-;7374:3;7367:34;7298:109;;:::o;7413:210::-;7500:4;7538:2;7527:9;7523:18;7515:26;;7551:65;7613:1;7602:9;7598:17;7589:6;7551:65;:::i;:::-;7413:210;;;;:::o;7629:474::-;7697:6;7705;7754:2;7742:9;7733:7;7729:23;7725:32;7722:119;;;7760:79;;:::i;:::-;7722:119;7880:1;7905:53;7950:7;7941:6;7930:9;7926:22;7905:53;:::i;:::-;7895:63;;7851:117;8007:2;8033:53;8078:7;8069:6;8058:9;8054:22;8033:53;:::i;:::-;8023:63;;7978:118;7629:474;;;;;:::o;8109:140::-;8202:6;8236:5;8230:12;8220:22;;8109:140;;;:::o;8255:210::-;8380:11;8414:6;8409:3;8402:19;8454:4;8449:3;8445:14;8430:29;;8255:210;;;;:::o;8471:158::-;8564:4;8587:3;8579:11;;8617:4;8612:3;8608:14;8600:22;;8471:158;;;:::o;8635:108::-;8712:24;8730:5;8712:24;:::i;:::-;8707:3;8700:37;8635:108;;:::o;8749:99::-;8801:6;8835:5;8829:12;8819:22;;8749:99;;;:::o;8854:159::-;8928:11;8962:6;8957:3;8950:19;9002:4;8997:3;8993:14;8978:29;;8854:159;;;;:::o;9019:246::-;9100:1;9110:113;9124:6;9121:1;9118:13;9110:113;;;9209:1;9204:3;9200:11;9194:18;9190:1;9185:3;9181:11;9174:39;9146:2;9143:1;9139:10;9134:15;;9110:113;;;9257:1;9248:6;9243:3;9239:16;9232:27;9081:184;9019:246;;;:::o;9271:102::-;9312:6;9363:2;9359:7;9354:2;9347:5;9343:14;9339:28;9329:38;;9271:102;;;:::o;9379:357::-;9457:3;9485:39;9518:5;9485:39;:::i;:::-;9540:61;9594:6;9589:3;9540:61;:::i;:::-;9533:68;;9610:65;9668:6;9663:3;9656:4;9649:5;9645:16;9610:65;:::i;:::-;9700:29;9722:6;9700:29;:::i;:::-;9695:3;9691:39;9684:46;;9461:275;9379:357;;;;:::o;9742:86::-;9777:7;9817:4;9810:5;9806:16;9795:27;;9742:86;;;:::o;9834:102::-;9907:22;9923:5;9907:22;:::i;:::-;9902:3;9895:35;9834:102;;:::o;10022:2675::-;10133:3;10169:6;10164:3;10160:16;10257:4;10250:5;10246:16;10240:23;10276:63;10333:4;10328:3;10324:14;10310:12;10276:63;:::i;:::-;10186:163;10437:4;10430:5;10426:16;10420:23;10456:63;10513:4;10508:3;10504:14;10490:12;10456:63;:::i;:::-;10359:170;10621:4;10614:5;10610:16;10604:23;10640:63;10697:4;10692:3;10688:14;10674:12;10640:63;:::i;:::-;10539:174;10807:4;10800:5;10796:16;10790:23;10826:63;10883:4;10878:3;10874:14;10860:12;10826:63;:::i;:::-;10723:176;10994:4;10987:5;10983:16;10977:23;11013:63;11070:4;11065:3;11061:14;11047:12;11013:63;:::i;:::-;10909:177;11175:4;11168:5;11164:16;11158:23;11194:63;11251:4;11246:3;11242:14;11228:12;11194:63;:::i;:::-;11096:171;11350:4;11343:5;11339:16;11333:23;11369:63;11426:4;11421:3;11417:14;11403:12;11369:63;:::i;:::-;11277:165;11526:4;11519:5;11515:16;11509:23;11579:3;11573:4;11569:14;11562:4;11557:3;11553:14;11546:38;11605:73;11673:4;11659:12;11605:73;:::i;:::-;11597:81;;11452:237;11771:6;11764:5;11760:18;11754:25;11828:3;11822:4;11818:14;11809:6;11804:3;11800:16;11793:40;11854:73;11922:4;11908:12;11854:73;:::i;:::-;11846:81;;11699:239;12024:6;12017:5;12013:18;12007:25;12045:61;12098:6;12093:3;12089:16;12075:12;12045:61;:::i;:::-;11948:168;12203:6;12196:5;12192:18;12186:25;12224:65;12281:6;12276:3;12272:16;12258:12;12224:65;:::i;:::-;12126:173;12389:6;12382:5;12378:18;12372:25;12410:65;12467:6;12462:3;12458:16;12444:12;12410:65;:::i;:::-;12309:176;12574:6;12567:5;12563:18;12557:25;12595:65;12652:6;12647:3;12643:16;12629:12;12595:65;:::i;:::-;12495:175;12687:4;12680:11;;10138:2559;10022:2675;;;;:::o;12703:260::-;12824:10;12859:98;12953:3;12945:6;12859:98;:::i;:::-;12845:112;;12703:260;;;;:::o;12969:139::-;13065:4;13097;13092:3;13088:14;13080:22;;12969:139;;;:::o;13198:1119::-;13369:3;13398:80;13472:5;13398:80;:::i;:::-;13494:112;13599:6;13594:3;13494:112;:::i;:::-;13487:119;;13632:3;13677:4;13669:6;13665:17;13660:3;13656:27;13707:82;13783:5;13707:82;:::i;:::-;13812:7;13843:1;13828:444;13853:6;13850:1;13847:13;13828:444;;;13924:9;13918:4;13914:20;13909:3;13902:33;13975:6;13969:13;14003:116;14114:4;14099:13;14003:116;:::i;:::-;13995:124;;14142:86;14221:6;14142:86;:::i;:::-;14132:96;;14257:4;14252:3;14248:14;14241:21;;13888:384;13875:1;13872;13868:9;13863:14;;13828:444;;;13832:14;14288:4;14281:11;;14308:3;14301:10;;13374:943;;;;;13198:1119;;;;:::o;14323:477::-;14518:4;14556:2;14545:9;14541:18;14533:26;;14605:9;14599:4;14595:20;14591:1;14580:9;14576:17;14569:47;14633:160;14788:4;14779:6;14633:160;:::i;:::-;14625:168;;14323:477;;;;:::o;14806:474::-;14874:6;14882;14931:2;14919:9;14910:7;14906:23;14902:32;14899:119;;;14937:79;;:::i;:::-;14899:119;15057:1;15082:53;15127:7;15118:6;15107:9;15103:22;15082:53;:::i;:::-;15072:63;;15028:117;15184:2;15210:53;15255:7;15246:6;15235:9;15231:22;15210:53;:::i;:::-;15200:63;;15155:118;14806:474;;;;;:::o;15366:708::-;15515:4;15510:3;15506:14;15610:4;15603:5;15599:16;15593:23;15629:63;15686:4;15681:3;15677:14;15663:12;15629:63;:::i;:::-;15530:172;15796:4;15789:5;15785:16;15779:23;15815:63;15872:4;15867:3;15863:14;15849:12;15815:63;:::i;:::-;15712:176;15975:4;15968:5;15964:16;15958:23;15994:63;16051:4;16046:3;16042:14;16028:12;15994:63;:::i;:::-;15898:169;15484:590;15366:708;;:::o;16080:326::-;16225:4;16263:2;16252:9;16248:18;16240:26;;16276:123;16396:1;16385:9;16381:17;16372:6;16276:123;:::i;:::-;16080:326;;;;:::o;16412:222::-;16505:4;16543:2;16532:9;16528:18;16520:26;;16556:71;16624:1;16613:9;16609:17;16600:6;16556:71;:::i;:::-;16412:222;;;;:::o;16640:118::-;16727:24;16745:5;16727:24;:::i;:::-;16722:3;16715:37;16640:118;;:::o;16764:222::-;16857:4;16895:2;16884:9;16880:18;16872:26;;16908:71;16976:1;16965:9;16961:17;16952:6;16908:71;:::i;:::-;16764:222;;;;:::o;16992:332::-;17113:4;17151:2;17140:9;17136:18;17128:26;;17164:71;17232:1;17221:9;17217:17;17208:6;17164:71;:::i;:::-;17245:72;17313:2;17302:9;17298:18;17289:6;17245:72;:::i;:::-;16992:332;;;;;:::o;17410:2685::-;17531:3;17567:6;17562:3;17558:16;17655:4;17648:5;17644:16;17638:23;17674:63;17731:4;17726:3;17722:14;17708:12;17674:63;:::i;:::-;17584:163;17835:4;17828:5;17824:16;17818:23;17854:63;17911:4;17906:3;17902:14;17888:12;17854:63;:::i;:::-;17757:170;18019:4;18012:5;18008:16;18002:23;18038:63;18095:4;18090:3;18086:14;18072:12;18038:63;:::i;:::-;17937:174;18205:4;18198:5;18194:16;18188:23;18224:63;18281:4;18276:3;18272:14;18258:12;18224:63;:::i;:::-;18121:176;18392:4;18385:5;18381:16;18375:23;18411:63;18468:4;18463:3;18459:14;18445:12;18411:63;:::i;:::-;18307:177;18573:4;18566:5;18562:16;18556:23;18592:63;18649:4;18644:3;18640:14;18626:12;18592:63;:::i;:::-;18494:171;18748:4;18741:5;18737:16;18731:23;18767:63;18824:4;18819:3;18815:14;18801:12;18767:63;:::i;:::-;18675:165;18924:4;18917:5;18913:16;18907:23;18977:3;18971:4;18967:14;18960:4;18955:3;18951:14;18944:38;19003:73;19071:4;19057:12;19003:73;:::i;:::-;18995:81;;18850:237;19169:6;19162:5;19158:18;19152:25;19226:3;19220:4;19216:14;19207:6;19202:3;19198:16;19191:40;19252:73;19320:4;19306:12;19252:73;:::i;:::-;19244:81;;19097:239;19422:6;19415:5;19411:18;19405:25;19443:61;19496:6;19491:3;19487:16;19473:12;19443:61;:::i;:::-;19346:168;19601:6;19594:5;19590:18;19584:25;19622:65;19679:6;19674:3;19670:16;19656:12;19622:65;:::i;:::-;19524:173;19787:6;19780:5;19776:18;19770:25;19808:65;19865:6;19860:3;19856:16;19842:12;19808:65;:::i;:::-;19707:176;19972:6;19965:5;19961:18;19955:25;19993:65;20050:6;20045:3;20041:16;20027:12;19993:65;:::i;:::-;19893:175;20085:4;20078:11;;17536:2559;17410:2685;;;;:::o;20101:377::-;20246:4;20284:2;20273:9;20269:18;20261:26;;20333:9;20327:4;20323:20;20319:1;20308:9;20304:17;20297:47;20361:110;20466:4;20457:6;20361:110;:::i;:::-;20353:118;;20101:377;;;;:::o;20484:114::-;20551:6;20585:5;20579:12;20569:22;;20484:114;;;:::o;20604:184::-;20703:11;20737:6;20732:3;20725:19;20777:4;20772:3;20768:14;20753:29;;20604:184;;;;:::o;20794:132::-;20861:4;20884:3;20876:11;;20914:4;20909:3;20905:14;20897:22;;20794:132;;;:::o;20932:179::-;21001:10;21022:46;21064:3;21056:6;21022:46;:::i;:::-;21100:4;21095:3;21091:14;21077:28;;20932:179;;;;:::o;21117:113::-;21187:4;21219;21214:3;21210:14;21202:22;;21117:113;;;:::o;21266:732::-;21385:3;21414:54;21462:5;21414:54;:::i;:::-;21484:86;21563:6;21558:3;21484:86;:::i;:::-;21477:93;;21594:56;21644:5;21594:56;:::i;:::-;21673:7;21704:1;21689:284;21714:6;21711:1;21708:13;21689:284;;;21790:6;21784:13;21817:63;21876:3;21861:13;21817:63;:::i;:::-;21810:70;;21903:60;21956:6;21903:60;:::i;:::-;21893:70;;21749:224;21736:1;21733;21729:9;21724:14;;21689:284;;;21693:14;21989:3;21982:10;;21390:608;;;21266:732;;;;:::o;22004:373::-;22147:4;22185:2;22174:9;22170:18;22162:26;;22234:9;22228:4;22224:20;22220:1;22209:9;22205:17;22198:47;22262:108;22365:4;22356:6;22262:108;:::i;:::-;22254:116;;22004:373;;;;:::o;22383:252::-;22491:4;22529:2;22518:9;22514:18;22506:26;;22542:86;22625:1;22614:9;22610:17;22601:6;22542:86;:::i;:::-;22383:252;;;;:::o;22641:180::-;22689:77;22686:1;22679:88;22786:4;22783:1;22776:15;22810:4;22807:1;22800:15;22827:194;22867:4;22887:20;22905:1;22887:20;:::i;:::-;22882:25;;22921:20;22939:1;22921:20;:::i;:::-;22916:25;;22965:1;22962;22958:9;22950:17;;22989:1;22983:4;22980:11;22977:37;;;22994:18;;:::i;:::-;22977:37;22827:194;;;;:::o;23027:169::-;23111:11;23145:6;23140:3;23133:19;23185:4;23180:3;23176:14;23161:29;;23027:169;;;;:::o;23202:229::-;23342:34;23338:1;23330:6;23326:14;23319:58;23411:12;23406:2;23398:6;23394:15;23387:37;23202:229;:::o;23437:366::-;23579:3;23600:67;23664:2;23659:3;23600:67;:::i;:::-;23593:74;;23676:93;23765:3;23676:93;:::i;:::-;23794:2;23789:3;23785:12;23778:19;;23437:366;;;:::o;23809:419::-;23975:4;24013:2;24002:9;23998:18;23990:26;;24062:9;24056:4;24052:20;24048:1;24037:9;24033:17;24026:47;24090:131;24216:4;24090:131;:::i;:::-;24082:139;;23809:419;;;:::o;24234:180::-;24282:77;24279:1;24272:88;24379:4;24376:1;24369:15;24403:4;24400:1;24393:15;24420:180;24468:77;24465:1;24458:88;24565:4;24562:1;24555:15;24589:4;24586:1;24579:15;24606:233;24645:3;24668:24;24686:5;24668:24;:::i;:::-;24659:33;;24714:66;24707:5;24704:77;24701:103;;24784:18;;:::i;:::-;24701:103;24831:1;24824:5;24820:13;24813:20;;24606:233;;;:::o;24845:::-;24985:34;24981:1;24973:6;24969:14;24962:58;25054:16;25049:2;25041:6;25037:15;25030:41;24845:233;:::o;25084:366::-;25226:3;25247:67;25311:2;25306:3;25247:67;:::i;:::-;25240:74;;25323:93;25412:3;25323:93;:::i;:::-;25441:2;25436:3;25432:12;25425:19;;25084:366;;;:::o;25456:419::-;25622:4;25660:2;25649:9;25645:18;25637:26;;25709:9;25703:4;25699:20;25695:1;25684:9;25680:17;25673:47;25737:131;25863:4;25737:131;:::i;:::-;25729:139;;25456:419;;;:::o;25881:176::-;26021:28;26017:1;26009:6;26005:14;25998:52;25881:176;:::o;26063:366::-;26205:3;26226:67;26290:2;26285:3;26226:67;:::i;:::-;26219:74;;26302:93;26391:3;26302:93;:::i;:::-;26420:2;26415:3;26411:12;26404:19;;26063:366;;;:::o;26435:419::-;26601:4;26639:2;26628:9;26624:18;26616:26;;26688:9;26682:4;26678:20;26674:1;26663:9;26659:17;26652:47;26716:131;26842:4;26716:131;:::i;:::-;26708:139;;26435:419;;;:::o;26860:222::-;27000:34;26996:1;26988:6;26984:14;26977:58;27069:5;27064:2;27056:6;27052:15;27045:30;26860:222;:::o;27088:366::-;27230:3;27251:67;27315:2;27310:3;27251:67;:::i;:::-;27244:74;;27327:93;27416:3;27327:93;:::i;:::-;27445:2;27440:3;27436:12;27429:19;;27088:366;;;:::o;27460:419::-;27626:4;27664:2;27653:9;27649:18;27641:26;;27713:9;27707:4;27703:20;27699:1;27688:9;27684:17;27677:47;27741:131;27867:4;27741:131;:::i;:::-;27733:139;;27460:419;;;:::o;27885:143::-;27942:5;27973:6;27967:13;27958:22;;27989:33;28016:5;27989:33;:::i;:::-;27885:143;;;;:::o;28034:351::-;28104:6;28153:2;28141:9;28132:7;28128:23;28124:32;28121:119;;;28159:79;;:::i;:::-;28121:119;28279:1;28304:64;28360:7;28351:6;28340:9;28336:22;28304:64;:::i;:::-;28294:74;;28250:128;28034:351;;;;:::o;28391:223::-;28531:34;28527:1;28519:6;28515:14;28508:58;28600:6;28595:2;28587:6;28583:15;28576:31;28391:223;:::o;28620:366::-;28762:3;28783:67;28847:2;28842:3;28783:67;:::i;:::-;28776:74;;28859:93;28948:3;28859:93;:::i;:::-;28977:2;28972:3;28968:12;28961:19;;28620:366;;;:::o;28992:419::-;29158:4;29196:2;29185:9;29181:18;29173:26;;29245:9;29239:4;29235:20;29231:1;29220:9;29216:17;29209:47;29273:131;29399:4;29273:131;:::i;:::-;29265:139;;28992:419;;;:::o;29417:160::-;29557:12;29553:1;29545:6;29541:14;29534:36;29417:160;:::o;29583:366::-;29725:3;29746:67;29810:2;29805:3;29746:67;:::i;:::-;29739:74;;29822:93;29911:3;29822:93;:::i;:::-;29940:2;29935:3;29931:12;29924:19;;29583:366;;;:::o;29955:419::-;30121:4;30159:2;30148:9;30144:18;30136:26;;30208:9;30202:4;30198:20;30194:1;30183:9;30179:17;30172:47;30236:131;30362:4;30236:131;:::i;:::-;30228:139;;29955:419;;;:::o;30380:241::-;30520:34;30516:1;30508:6;30504:14;30497:58;30589:24;30584:2;30576:6;30572:15;30565:49;30380:241;:::o;30627:366::-;30769:3;30790:67;30854:2;30849:3;30790:67;:::i;:::-;30783:74;;30866:93;30955:3;30866:93;:::i;:::-;30984:2;30979:3;30975:12;30968:19;;30627:366;;;:::o;30999:419::-;31165:4;31203:2;31192:9;31188:18;31180:26;;31252:9;31246:4;31242:20;31238:1;31227:9;31223:17;31216:47;31280:131;31406:4;31280:131;:::i;:::-;31272:139;;30999:419;;;:::o;31424:230::-;31564:34;31560:1;31552:6;31548:14;31541:58;31633:13;31628:2;31620:6;31616:15;31609:38;31424:230;:::o;31660:366::-;31802:3;31823:67;31887:2;31882:3;31823:67;:::i;:::-;31816:74;;31899:93;31988:3;31899:93;:::i;:::-;32017:2;32012:3;32008:12;32001:19;;31660:366;;;:::o;32032:419::-;32198:4;32236:2;32225:9;32221:18;32213:26;;32285:9;32279:4;32275:20;32271:1;32260:9;32256:17;32249:47;32313:131;32439:4;32313:131;:::i;:::-;32305:139;;32032:419;;;:::o;32457:238::-;32597:34;32593:1;32585:6;32581:14;32574:58;32666:21;32661:2;32653:6;32649:15;32642:46;32457:238;:::o;32701:366::-;32843:3;32864:67;32928:2;32923:3;32864:67;:::i;:::-;32857:74;;32940:93;33029:3;32940:93;:::i;:::-;33058:2;33053:3;33049:12;33042:19;;32701:366;;;:::o;33073:419::-;33239:4;33277:2;33266:9;33262:18;33254:26;;33326:9;33320:4;33316:20;33312:1;33301:9;33297:17;33290:47;33354:131;33480:4;33354:131;:::i;:::-;33346:139;;33073:419;;;:::o;33498:223::-;33638:34;33634:1;33626:6;33622:14;33615:58;33707:6;33702:2;33694:6;33690:15;33683:31;33498:223;:::o;33727:366::-;33869:3;33890:67;33954:2;33949:3;33890:67;:::i;:::-;33883:74;;33966:93;34055:3;33966:93;:::i;:::-;34084:2;34079:3;34075:12;34068:19;;33727:366;;;:::o;34099:419::-;34265:4;34303:2;34292:9;34288:18;34280:26;;34352:9;34346:4;34342:20;34338:1;34327:9;34323:17;34316:47;34380:131;34506:4;34380:131;:::i;:::-;34372:139;;34099:419;;;:::o;34524:117::-;34633:1;34630;34623:12;34647:117;34756:1;34753;34746:12;34770:281;34853:27;34875:4;34853:27;:::i;:::-;34845:6;34841:40;34983:6;34971:10;34968:22;34947:18;34935:10;34932:34;34929:62;34926:88;;;34994:18;;:::i;:::-;34926:88;35034:10;35030:2;35023:22;34813:238;34770:281;;:::o;35057:129::-;35091:6;35118:20;;:::i;:::-;35108:30;;35147:33;35175:4;35167:6;35147:33;:::i;:::-;35057:129;;;:::o;35192:308::-;35254:4;35344:18;35336:6;35333:30;35330:56;;;35366:18;;:::i;:::-;35330:56;35404:29;35426:6;35404:29;:::i;:::-;35396:37;;35488:4;35482;35478:15;35470:23;;35192:308;;;:::o;35506:434::-;35595:5;35620:66;35636:49;35678:6;35636:49;:::i;:::-;35620:66;:::i;:::-;35611:75;;35709:6;35702:5;35695:21;35747:4;35740:5;35736:16;35785:3;35776:6;35771:3;35767:16;35764:25;35761:112;;;35792:79;;:::i;:::-;35761:112;35882:52;35927:6;35922:3;35917;35882:52;:::i;:::-;35601:339;35506:434;;;;;:::o;35960:355::-;36027:5;36076:3;36069:4;36061:6;36057:17;36053:27;36043:122;;36084:79;;:::i;:::-;36043:122;36194:6;36188:13;36219:90;36305:3;36297:6;36290:4;36282:6;36278:17;36219:90;:::i;:::-;36210:99;;36033:282;35960:355;;;;:::o;36321:524::-;36401:6;36450:2;36438:9;36429:7;36425:23;36421:32;36418:119;;;36456:79;;:::i;:::-;36418:119;36597:1;36586:9;36582:17;36576:24;36627:18;36619:6;36616:30;36613:117;;;36649:79;;:::i;:::-;36613:117;36754:74;36820:7;36811:6;36800:9;36796:22;36754:74;:::i;:::-;36744:84;;36547:291;36321:524;;;;:::o;36851:118::-;36922:22;36938:5;36922:22;:::i;:::-;36915:5;36912:33;36902:61;;36959:1;36956;36949:12;36902:61;36851:118;:::o;36975:139::-;37030:5;37061:6;37055:13;37046:22;;37077:31;37102:5;37077:31;:::i;:::-;36975:139;;;;:::o;37120:347::-;37188:6;37237:2;37225:9;37216:7;37212:23;37208:32;37205:119;;;37243:79;;:::i;:::-;37205:119;37363:1;37388:62;37442:7;37433:6;37422:9;37418:22;37388:62;:::i;:::-;37378:72;;37334:126;37120:347;;;;:::o;37473:223::-;37613:34;37609:1;37601:6;37597:14;37590:58;37682:6;37677:2;37669:6;37665:15;37658:31;37473:223;:::o;37702:366::-;37844:3;37865:67;37929:2;37924:3;37865:67;:::i;:::-;37858:74;;37941:93;38030:3;37941:93;:::i;:::-;38059:2;38054:3;38050:12;38043:19;;37702:366;;;:::o;38074:419::-;38240:4;38278:2;38267:9;38263:18;38255:26;;38327:9;38321:4;38317:20;38313:1;38302:9;38298:17;38291:47;38355:131;38481:4;38355:131;:::i;:::-;38347:139;;38074:419;;;:::o;38499:225::-;38639:34;38635:1;38627:6;38623:14;38616:58;38708:8;38703:2;38695:6;38691:15;38684:33;38499:225;:::o;38730:366::-;38872:3;38893:67;38957:2;38952:3;38893:67;:::i;:::-;38886:74;;38969:93;39058:3;38969:93;:::i;:::-;39087:2;39082:3;39078:12;39071:19;;38730:366;;;:::o;39102:419::-;39268:4;39306:2;39295:9;39291:18;39283:26;;39355:9;39349:4;39345:20;39341:1;39330:9;39326:17;39319:47;39383:131;39509:4;39383:131;:::i;:::-;39375:139;;39102:419;;;:::o;39527:182::-;39667:34;39663:1;39655:6;39651:14;39644:58;39527:182;:::o;39715:366::-;39857:3;39878:67;39942:2;39937:3;39878:67;:::i;:::-;39871:74;;39954:93;40043:3;39954:93;:::i;:::-;40072:2;40067:3;40063:12;40056:19;;39715:366;;;:::o;40087:419::-;40253:4;40291:2;40280:9;40276:18;40268:26;;40340:9;40334:4;40330:20;40326:1;40315:9;40311:17;40304:47;40368:131;40494:4;40368:131;:::i;:::-;40360:139;;40087:419;;;:::o;40512:191::-;40552:3;40571:20;40589:1;40571:20;:::i;:::-;40566:25;;40605:20;40623:1;40605:20;:::i;:::-;40600:25;;40648:1;40645;40641:9;40634:16;;40669:3;40666:1;40663:10;40660:36;;;40676:18;;:::i;:::-;40660:36;40512:191;;;;:::o;40709:332::-;40830:4;40868:2;40857:9;40853:18;40845:26;;40881:71;40949:1;40938:9;40934:17;40925:6;40881:71;:::i;:::-;40962:72;41030:2;41019:9;41015:18;41006:6;40962:72;:::i;:::-;40709:332;;;;;:::o;41047:410::-;41087:7;41110:20;41128:1;41110:20;:::i;:::-;41105:25;;41144:20;41162:1;41144:20;:::i;:::-;41139:25;;41199:1;41196;41192:9;41221:30;41239:11;41221:30;:::i;:::-;41210:41;;41400:1;41391:7;41387:15;41384:1;41381:22;41361:1;41354:9;41334:83;41311:139;;41430:18;;:::i;:::-;41311:139;41095:362;41047:410;;;;:::o;41463:180::-;41511:77;41508:1;41501:88;41608:4;41605:1;41598:15;41632:4;41629:1;41622:15;41649:185;41689:1;41706:20;41724:1;41706:20;:::i;:::-;41701:25;;41740:20;41758:1;41740:20;:::i;:::-;41735:25;;41779:1;41769:35;;41784:18;;:::i;:::-;41769:35;41826:1;41823;41819:9;41814:14;;41649:185;;;;:::o;41840:442::-;41989:4;42027:2;42016:9;42012:18;42004:26;;42040:71;42108:1;42097:9;42093:17;42084:6;42040:71;:::i;:::-;42121:72;42189:2;42178:9;42174:18;42165:6;42121:72;:::i;:::-;42203;42271:2;42260:9;42256:18;42247:6;42203:72;:::i;:::-;41840:442;;;;;;:::o;42288:180::-;42336:77;42333:1;42326:88;42433:4;42430:1;42423:15;42457:4;42454:1;42447:15;42474:116;42544:21;42559:5;42544:21;:::i;:::-;42537:5;42534:32;42524:60;;42580:1;42577;42570:12;42524:60;42474:116;:::o;42596:137::-;42650:5;42681:6;42675:13;42666:22;;42697:30;42721:5;42697:30;:::i;:::-;42596:137;;;;:::o;42739:345::-;42806:6;42855:2;42843:9;42834:7;42830:23;42826:32;42823:119;;;42861:79;;:::i;:::-;42823:119;42981:1;43006:61;43059:7;43050:6;43039:9;43035:22;43006:61;:::i;:::-;42996:71;;42952:125;42739:345;;;;:::o;43090:229::-;43230:34;43226:1;43218:6;43214:14;43207:58;43299:12;43294:2;43286:6;43282:15;43275:37;43090:229;:::o;43325:366::-;43467:3;43488:67;43552:2;43547:3;43488:67;:::i;:::-;43481:74;;43564:93;43653:3;43564:93;:::i;:::-;43682:2;43677:3;43673:12;43666:19;;43325:366;;;:::o;43697:419::-;43863:4;43901:2;43890:9;43886:18;43878:26;;43950:9;43944:4;43940:20;43936:1;43925:9;43921:17;43914:47;43978:131;44104:4;43978:131;:::i;:::-;43970:139;;43697:419;;;:::o;44122:225::-;44262:34;44258:1;44250:6;44246:14;44239:58;44331:8;44326:2;44318:6;44314:15;44307:33;44122:225;:::o;44353:366::-;44495:3;44516:67;44580:2;44575:3;44516:67;:::i;:::-;44509:74;;44592:93;44681:3;44592:93;:::i;:::-;44710:2;44705:3;44701:12;44694:19;;44353:366;;;:::o;44725:419::-;44891:4;44929:2;44918:9;44914:18;44906:26;;44978:9;44972:4;44968:20;44964:1;44953:9;44949:17;44942:47;45006:131;45132:4;45006:131;:::i;:::-;44998:139;;44725:419;;;:::o;45150:98::-;45201:6;45235:5;45229:12;45219:22;;45150:98;;;:::o;45254:147::-;45355:11;45392:3;45377:18;;45254:147;;;;:::o;45407:386::-;45511:3;45539:38;45571:5;45539:38;:::i;:::-;45593:88;45674:6;45669:3;45593:88;:::i;:::-;45586:95;;45690:65;45748:6;45743:3;45736:4;45729:5;45725:16;45690:65;:::i;:::-;45780:6;45775:3;45771:16;45764:23;;45515:278;45407:386;;;;:::o;45799:271::-;45929:3;45951:93;46040:3;46031:6;45951:93;:::i;:::-;45944:100;;46061:3;46054:10;;45799:271;;;;:::o;46076:179::-;46216:31;46212:1;46204:6;46200:14;46193:55;46076:179;:::o;46261:366::-;46403:3;46424:67;46488:2;46483:3;46424:67;:::i;:::-;46417:74;;46500:93;46589:3;46500:93;:::i;:::-;46618:2;46613:3;46609:12;46602:19;;46261:366;;;:::o;46633:419::-;46799:4;46837:2;46826:9;46822:18;46814:26;;46886:9;46880:4;46876:20;46872:1;46861:9;46857:17;46850:47;46914:131;47040:4;46914:131;:::i;:::-;46906:139;;46633:419;;;:::o;47058:377::-;47146:3;47174:39;47207:5;47174:39;:::i;:::-;47229:71;47293:6;47288:3;47229:71;:::i;:::-;47222:78;;47309:65;47367:6;47362:3;47355:4;47348:5;47344:16;47309:65;:::i;:::-;47399:29;47421:6;47399:29;:::i;:::-;47394:3;47390:39;47383:46;;47150:285;47058:377;;;;:::o;47441:313::-;47554:4;47592:2;47581:9;47577:18;47569:26;;47641:9;47635:4;47631:20;47627:1;47616:9;47612:17;47605:47;47669:78;47742:4;47733:6;47669:78;:::i;:::-;47661:86;;47441:313;;;;:::o
Swarm Source
ipfs://56c63f0f5d983ab8070c83af96b2d54d52098b991c7f2ba94aa86d4a0e175c79
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$4.79
Net Worth in ETH
0.001623
Token Allocations
ARB
100.00%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ARB | 100.00% | $0.176198 | 27.1628 | $4.79 |
Loading...
Loading
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.