Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 511 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Mint | 20117220 | 25 mins ago | IN | 0 S | 0.01334549 | ||||
Mint | 20007482 | 12 hrs ago | IN | 0 S | 0.00970445 | ||||
Mint | 20007397 | 12 hrs ago | IN | 0 S | 0.00914945 | ||||
Mint | 20007315 | 12 hrs ago | IN | 0 S | 0.00938945 | ||||
Mint | 20007241 | 12 hrs ago | IN | 0 S | 0.0125582 | ||||
Mint | 20006979 | 12 hrs ago | IN | 0 S | 0.0106012 | ||||
Approve | 20006234 | 13 hrs ago | IN | 0 S | 0.0024413 | ||||
Remove From Whit... | 20000969 | 13 hrs ago | IN | 0 S | 0.002029 | ||||
Mint | 19991948 | 14 hrs ago | IN | 0 S | 0.0105902 | ||||
Mint | 19988674 | 15 hrs ago | IN | 0 S | 0.01710745 | ||||
Approve | 19986911 | 15 hrs ago | IN | 0 S | 0.0024413 | ||||
Mint | 19983431 | 15 hrs ago | IN | 0 S | 0.01169075 | ||||
Add To Sos White... | 19983232 | 15 hrs ago | IN | 0 S | 0.0025112 | ||||
Mint | 19980363 | 16 hrs ago | IN | 0 S | 0.0106012 | ||||
Mint | 19980281 | 16 hrs ago | IN | 0 S | 0.01231442 | ||||
Approve | 19980159 | 16 hrs ago | IN | 0 S | 0.00284788 | ||||
Mint | 19979644 | 16 hrs ago | IN | 0 S | 0.01292779 | ||||
Mint | 19965333 | 18 hrs ago | IN | 0 S | 0.01110877 | ||||
Mint | 19965316 | 18 hrs ago | IN | 0 S | 0.01137282 | ||||
Mint | 19965301 | 18 hrs ago | IN | 0 S | 0.01137282 | ||||
Mint | 19965284 | 18 hrs ago | IN | 0 S | 0.01059586 | ||||
Mint | 19965266 | 18 hrs ago | IN | 0 S | 0.01837598 | ||||
Mint | 19965248 | 18 hrs ago | IN | 0 S | 0.01452043 | ||||
Approve | 19964488 | 18 hrs ago | IN | 0 S | 0.0014463 | ||||
Approve | 19964473 | 18 hrs ago | IN | 0 S | 0.0024413 |
Loading...
Loading
Contract Name:
Tales_of_Sparta
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at SonicScan.org on 2025-04-10 */ // SPDX-License-Identifier: No license // File: @openzeppelin/contracts/security/ReentrancyGuard.sol // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } } // File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/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/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.9.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: abdk-libraries-solidity/ABDKMath64x64.sol /* * ABDK Math 64.64 Smart Contract Library. Copyright © 2019 by ABDK Consulting. * Author: Mikhail Vladimirov <[email protected]> */ pragma solidity ^0.8.0; /** * Smart contract library of mathematical functions operating with signed * 64.64-bit fixed point numbers. Signed 64.64-bit fixed point number is * basically a simple fraction whose numerator is signed 128-bit integer and * denominator is 2^64. As long as denominator is always the same, there is no * need to store it, thus in Solidity signed 64.64-bit fixed point numbers are * represented by int128 type holding only the numerator. */ library ABDKMath64x64 { /* * Minimum value signed 64.64-bit fixed point number may have. */ int128 private constant MIN_64x64 = -0x80000000000000000000000000000000; /* * Maximum value signed 64.64-bit fixed point number may have. */ int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; /** * Convert signed 256-bit integer number into signed 64.64-bit fixed point * number. Revert on overflow. * * @param x signed 256-bit integer number * @return signed 64.64-bit fixed point number */ function fromInt (int256 x) internal pure returns (int128) { unchecked { require (x >= -0x8000000000000000 && x <= 0x7FFFFFFFFFFFFFFF); return int128 (x << 64); } } /** * Convert signed 64.64 fixed point number into signed 64-bit integer number * rounding down. * * @param x signed 64.64-bit fixed point number * @return signed 64-bit integer number */ function toInt (int128 x) internal pure returns (int64) { unchecked { return int64 (x >> 64); } } /** * Convert unsigned 256-bit integer number into signed 64.64-bit fixed point * number. Revert on overflow. * * @param x unsigned 256-bit integer number * @return signed 64.64-bit fixed point number */ function fromUInt (uint256 x) internal pure returns (int128) { unchecked { require (x <= 0x7FFFFFFFFFFFFFFF); return int128 (int256 (x << 64)); } } /** * Convert signed 64.64 fixed point number into unsigned 64-bit integer * number rounding down. Revert on underflow. * * @param x signed 64.64-bit fixed point number * @return unsigned 64-bit integer number */ function toUInt (int128 x) internal pure returns (uint64) { unchecked { require (x >= 0); return uint64 (uint128 (x >> 64)); } } /** * Convert signed 128.128 fixed point number into signed 64.64-bit fixed point * number rounding down. Revert on overflow. * * @param x signed 128.128-bin fixed point number * @return signed 64.64-bit fixed point number */ function from128x128 (int256 x) internal pure returns (int128) { unchecked { int256 result = x >> 64; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } } /** * Convert signed 64.64 fixed point number into signed 128.128 fixed point * number. * * @param x signed 64.64-bit fixed point number * @return signed 128.128 fixed point number */ function to128x128 (int128 x) internal pure returns (int256) { unchecked { return int256 (x) << 64; } } /** * Calculate x + y. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function add (int128 x, int128 y) internal pure returns (int128) { unchecked { int256 result = int256(x) + y; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } } /** * Calculate x - y. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function sub (int128 x, int128 y) internal pure returns (int128) { unchecked { int256 result = int256(x) - y; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } } /** * Calculate x * y rounding down. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function mul (int128 x, int128 y) internal pure returns (int128) { unchecked { int256 result = int256(x) * y >> 64; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } } /** * Calculate x * y rounding towards zero, where x is signed 64.64 fixed point * number and y is signed 256-bit integer number. Revert on overflow. * * @param x signed 64.64 fixed point number * @param y signed 256-bit integer number * @return signed 256-bit integer number */ function muli (int128 x, int256 y) internal pure returns (int256) { unchecked { if (x == MIN_64x64) { require (y >= -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF && y <= 0x1000000000000000000000000000000000000000000000000); return -y << 63; } else { bool negativeResult = false; if (x < 0) { x = -x; negativeResult = true; } if (y < 0) { y = -y; // We rely on overflow behavior here negativeResult = !negativeResult; } uint256 absoluteResult = mulu (x, uint256 (y)); if (negativeResult) { require (absoluteResult <= 0x8000000000000000000000000000000000000000000000000000000000000000); return -int256 (absoluteResult); // We rely on overflow behavior here } else { require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int256 (absoluteResult); } } } } /** * Calculate x * y rounding down, where x is signed 64.64 fixed point number * and y is unsigned 256-bit integer number. Revert on overflow. * * @param x signed 64.64 fixed point number * @param y unsigned 256-bit integer number * @return unsigned 256-bit integer number */ function mulu (int128 x, uint256 y) internal pure returns (uint256) { unchecked { if (y == 0) return 0; require (x >= 0); uint256 lo = (uint256 (int256 (x)) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64; uint256 hi = uint256 (int256 (x)) * (y >> 128); require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); hi <<= 64; require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - lo); return hi + lo; } } /** * Calculate x / y rounding towards zero. Revert on overflow or when y is * zero. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function div (int128 x, int128 y) internal pure returns (int128) { unchecked { require (y != 0); int256 result = (int256 (x) << 64) / y; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } } /** * Calculate x / y rounding towards zero, where x and y are signed 256-bit * integer numbers. Revert on overflow or when y is zero. * * @param x signed 256-bit integer number * @param y signed 256-bit integer number * @return signed 64.64-bit fixed point number */ function divi (int256 x, int256 y) internal pure returns (int128) { unchecked { require (y != 0); bool negativeResult = false; if (x < 0) { x = -x; // We rely on overflow behavior here negativeResult = true; } if (y < 0) { y = -y; // We rely on overflow behavior here negativeResult = !negativeResult; } uint128 absoluteResult = divuu (uint256 (x), uint256 (y)); if (negativeResult) { require (absoluteResult <= 0x80000000000000000000000000000000); return -int128 (absoluteResult); // We rely on overflow behavior here } else { require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int128 (absoluteResult); // We rely on overflow behavior here } } } /** * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit * integer numbers. Revert on overflow or when y is zero. * * @param x unsigned 256-bit integer number * @param y unsigned 256-bit integer number * @return signed 64.64-bit fixed point number */ function divu (uint256 x, uint256 y) internal pure returns (int128) { unchecked { require (y != 0); uint128 result = divuu (x, y); require (result <= uint128 (MAX_64x64)); return int128 (result); } } /** * Calculate -x. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function neg (int128 x) internal pure returns (int128) { unchecked { require (x != MIN_64x64); return -x; } } /** * Calculate |x|. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function abs (int128 x) internal pure returns (int128) { unchecked { require (x != MIN_64x64); return x < 0 ? -x : x; } } /** * Calculate 1 / x rounding towards zero. Revert on overflow or when x is * zero. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function inv (int128 x) internal pure returns (int128) { unchecked { require (x != 0); int256 result = int256 (0x100000000000000000000000000000000) / x; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } } /** * Calculate arithmetics average of x and y, i.e. (x + y) / 2 rounding down. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function avg (int128 x, int128 y) internal pure returns (int128) { unchecked { return int128 ((int256 (x) + int256 (y)) >> 1); } } /** * Calculate geometric average of x and y, i.e. sqrt (x * y) rounding down. * Revert on overflow or in case x * y is negative. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function gavg (int128 x, int128 y) internal pure returns (int128) { unchecked { int256 m = int256 (x) * int256 (y); require (m >= 0); require (m < 0x4000000000000000000000000000000000000000000000000000000000000000); return int128 (sqrtu (uint256 (m))); } } /** * Calculate x^y assuming 0^0 is 1, where x is signed 64.64 fixed point number * and y is unsigned 256-bit integer number. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y uint256 value * @return signed 64.64-bit fixed point number */ function pow (int128 x, uint256 y) internal pure returns (int128) { unchecked { bool negative = x < 0 && y & 1 == 1; uint256 absX = uint128 (x < 0 ? -x : x); uint256 absResult; absResult = 0x100000000000000000000000000000000; if (absX <= 0x10000000000000000) { absX <<= 63; while (y != 0) { if (y & 0x1 != 0) { absResult = absResult * absX >> 127; } absX = absX * absX >> 127; if (y & 0x2 != 0) { absResult = absResult * absX >> 127; } absX = absX * absX >> 127; if (y & 0x4 != 0) { absResult = absResult * absX >> 127; } absX = absX * absX >> 127; if (y & 0x8 != 0) { absResult = absResult * absX >> 127; } absX = absX * absX >> 127; y >>= 4; } absResult >>= 64; } else { uint256 absXShift = 63; if (absX < 0x1000000000000000000000000) { absX <<= 32; absXShift -= 32; } if (absX < 0x10000000000000000000000000000) { absX <<= 16; absXShift -= 16; } if (absX < 0x1000000000000000000000000000000) { absX <<= 8; absXShift -= 8; } if (absX < 0x10000000000000000000000000000000) { absX <<= 4; absXShift -= 4; } if (absX < 0x40000000000000000000000000000000) { absX <<= 2; absXShift -= 2; } if (absX < 0x80000000000000000000000000000000) { absX <<= 1; absXShift -= 1; } uint256 resultShift = 0; while (y != 0) { require (absXShift < 64); if (y & 0x1 != 0) { absResult = absResult * absX >> 127; resultShift += absXShift; if (absResult > 0x100000000000000000000000000000000) { absResult >>= 1; resultShift += 1; } } absX = absX * absX >> 127; absXShift <<= 1; if (absX >= 0x100000000000000000000000000000000) { absX >>= 1; absXShift += 1; } y >>= 1; } require (resultShift < 64); absResult >>= 64 - resultShift; } int256 result = negative ? -int256 (absResult) : int256 (absResult); require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } } /** * Calculate sqrt (x) rounding down. Revert if x < 0. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function sqrt (int128 x) internal pure returns (int128) { unchecked { require (x >= 0); return int128 (sqrtu (uint256 (int256 (x)) << 64)); } } /** * Calculate binary logarithm of x. Revert if x <= 0. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function log_2 (int128 x) internal pure returns (int128) { unchecked { require (x > 0); int256 msb = 0; int256 xc = x; if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; } if (xc >= 0x100000000) { xc >>= 32; msb += 32; } if (xc >= 0x10000) { xc >>= 16; msb += 16; } if (xc >= 0x100) { xc >>= 8; msb += 8; } if (xc >= 0x10) { xc >>= 4; msb += 4; } if (xc >= 0x4) { xc >>= 2; msb += 2; } if (xc >= 0x2) msb += 1; // No need to shift xc anymore int256 result = msb - 64 << 64; uint256 ux = uint256 (int256 (x)) << uint256 (127 - msb); for (int256 bit = 0x8000000000000000; bit > 0; bit >>= 1) { ux *= ux; uint256 b = ux >> 255; ux >>= 127 + b; result += bit * int256 (b); } return int128 (result); } } /** * Calculate natural logarithm of x. Revert if x <= 0. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function ln (int128 x) internal pure returns (int128) { unchecked { require (x > 0); return int128 (int256 ( uint256 (int256 (log_2 (x))) * 0xB17217F7D1CF79ABC9E3B39803F2F6AF >> 128)); } } /** * Calculate binary exponent of x. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function exp_2 (int128 x) internal pure returns (int128) { unchecked { require (x < 0x400000000000000000); // Overflow if (x < -0x400000000000000000) return 0; // Underflow uint256 result = 0x80000000000000000000000000000000; if (x & 0x8000000000000000 > 0) result = result * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128; if (x & 0x4000000000000000 > 0) result = result * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128; if (x & 0x2000000000000000 > 0) result = result * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128; if (x & 0x1000000000000000 > 0) result = result * 0x10B5586CF9890F6298B92B71842A98363 >> 128; if (x & 0x800000000000000 > 0) result = result * 0x1059B0D31585743AE7C548EB68CA417FD >> 128; if (x & 0x400000000000000 > 0) result = result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128; if (x & 0x200000000000000 > 0) result = result * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128; if (x & 0x100000000000000 > 0) result = result * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128; if (x & 0x80000000000000 > 0) result = result * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128; if (x & 0x40000000000000 > 0) result = result * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128; if (x & 0x20000000000000 > 0) result = result * 0x100162F3904051FA128BCA9C55C31E5DF >> 128; if (x & 0x10000000000000 > 0) result = result * 0x1000B175EFFDC76BA38E31671CA939725 >> 128; if (x & 0x8000000000000 > 0) result = result * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128; if (x & 0x4000000000000 > 0) result = result * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128; if (x & 0x2000000000000 > 0) result = result * 0x1000162E525EE054754457D5995292026 >> 128; if (x & 0x1000000000000 > 0) result = result * 0x10000B17255775C040618BF4A4ADE83FC >> 128; if (x & 0x800000000000 > 0) result = result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128; if (x & 0x400000000000 > 0) result = result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128; if (x & 0x200000000000 > 0) result = result * 0x10000162E43F4F831060E02D839A9D16D >> 128; if (x & 0x100000000000 > 0) result = result * 0x100000B1721BCFC99D9F890EA06911763 >> 128; if (x & 0x80000000000 > 0) result = result * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128; if (x & 0x40000000000 > 0) result = result * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128; if (x & 0x20000000000 > 0) result = result * 0x100000162E430E5A18F6119E3C02282A5 >> 128; if (x & 0x10000000000 > 0) result = result * 0x1000000B1721835514B86E6D96EFD1BFE >> 128; if (x & 0x8000000000 > 0) result = result * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128; if (x & 0x4000000000 > 0) result = result * 0x10000002C5C8601CC6B9E94213C72737A >> 128; if (x & 0x2000000000 > 0) result = result * 0x1000000162E42FFF037DF38AA2B219F06 >> 128; if (x & 0x1000000000 > 0) result = result * 0x10000000B17217FBA9C739AA5819F44F9 >> 128; if (x & 0x800000000 > 0) result = result * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128; if (x & 0x400000000 > 0) result = result * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128; if (x & 0x200000000 > 0) result = result * 0x10000000162E42FF0999CE3541B9FFFCF >> 128; if (x & 0x100000000 > 0) result = result * 0x100000000B17217F80F4EF5AADDA45554 >> 128; if (x & 0x80000000 > 0) result = result * 0x10000000058B90BFBF8479BD5A81B51AD >> 128; if (x & 0x40000000 > 0) result = result * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128; if (x & 0x20000000 > 0) result = result * 0x100000000162E42FEFB2FED257559BDAA >> 128; if (x & 0x10000000 > 0) result = result * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128; if (x & 0x8000000 > 0) result = result * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128; if (x & 0x4000000 > 0) result = result * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128; if (x & 0x2000000 > 0) result = result * 0x1000000000162E42FEFA494F1478FDE05 >> 128; if (x & 0x1000000 > 0) result = result * 0x10000000000B17217F7D20CF927C8E94C >> 128; if (x & 0x800000 > 0) result = result * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128; if (x & 0x400000 > 0) result = result * 0x100000000002C5C85FDF477B662B26945 >> 128; if (x & 0x200000 > 0) result = result * 0x10000000000162E42FEFA3AE53369388C >> 128; if (x & 0x100000 > 0) result = result * 0x100000000000B17217F7D1D351A389D40 >> 128; if (x & 0x80000 > 0) result = result * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128; if (x & 0x40000 > 0) result = result * 0x1000000000002C5C85FDF4741BEA6E77E >> 128; if (x & 0x20000 > 0) result = result * 0x100000000000162E42FEFA39FE95583C2 >> 128; if (x & 0x10000 > 0) result = result * 0x1000000000000B17217F7D1CFB72B45E1 >> 128; if (x & 0x8000 > 0) result = result * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128; if (x & 0x4000 > 0) result = result * 0x10000000000002C5C85FDF473E242EA38 >> 128; if (x & 0x2000 > 0) result = result * 0x1000000000000162E42FEFA39F02B772C >> 128; if (x & 0x1000 > 0) result = result * 0x10000000000000B17217F7D1CF7D83C1A >> 128; if (x & 0x800 > 0) result = result * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128; if (x & 0x400 > 0) result = result * 0x100000000000002C5C85FDF473DEA871F >> 128; if (x & 0x200 > 0) result = result * 0x10000000000000162E42FEFA39EF44D91 >> 128; if (x & 0x100 > 0) result = result * 0x100000000000000B17217F7D1CF79E949 >> 128; if (x & 0x80 > 0) result = result * 0x10000000000000058B90BFBE8E7BCE544 >> 128; if (x & 0x40 > 0) result = result * 0x1000000000000002C5C85FDF473DE6ECA >> 128; if (x & 0x20 > 0) result = result * 0x100000000000000162E42FEFA39EF366F >> 128; if (x & 0x10 > 0) result = result * 0x1000000000000000B17217F7D1CF79AFA >> 128; if (x & 0x8 > 0) result = result * 0x100000000000000058B90BFBE8E7BCD6D >> 128; if (x & 0x4 > 0) result = result * 0x10000000000000002C5C85FDF473DE6B2 >> 128; if (x & 0x2 > 0) result = result * 0x1000000000000000162E42FEFA39EF358 >> 128; if (x & 0x1 > 0) result = result * 0x10000000000000000B17217F7D1CF79AB >> 128; result >>= uint256 (int256 (63 - (x >> 64))); require (result <= uint256 (int256 (MAX_64x64))); return int128 (int256 (result)); } } /** * Calculate natural exponent of x. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function exp (int128 x) internal pure returns (int128) { unchecked { require (x < 0x400000000000000000); // Overflow if (x < -0x400000000000000000) return 0; // Underflow return exp_2 ( int128 (int256 (x) * 0x171547652B82FE1777D0FFDA0D23A7D12 >> 128)); } } /** * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit * integer numbers. Revert on overflow or when y is zero. * * @param x unsigned 256-bit integer number * @param y unsigned 256-bit integer number * @return unsigned 64.64-bit fixed point number */ function divuu (uint256 x, uint256 y) private pure returns (uint128) { unchecked { require (y != 0); uint256 result; if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) result = (x << 64) / y; else { uint256 msb = 192; uint256 xc = x >> 192; if (xc >= 0x100000000) { xc >>= 32; msb += 32; } if (xc >= 0x10000) { xc >>= 16; msb += 16; } if (xc >= 0x100) { xc >>= 8; msb += 8; } if (xc >= 0x10) { xc >>= 4; msb += 4; } if (xc >= 0x4) { xc >>= 2; msb += 2; } if (xc >= 0x2) msb += 1; // No need to shift xc anymore result = (x << 255 - msb) / ((y - 1 >> msb - 191) + 1); require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); uint256 hi = result * (y >> 128); uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); uint256 xh = x >> 192; uint256 xl = x << 64; if (xl < lo) xh -= 1; xl -= lo; // We rely on overflow behavior here lo = hi << 128; if (xl < lo) xh -= 1; xl -= lo; // We rely on overflow behavior here result += xh == hi >> 128 ? xl / y : 1; } require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return uint128 (result); } } /** * Calculate sqrt (x) rounding down, where x is unsigned 256-bit integer * number. * * @param x unsigned 256-bit integer number * @return unsigned 128-bit integer number */ function sqrtu (uint256 x) private pure returns (uint128) { unchecked { if (x == 0) return 0; else { uint256 xx = x; uint256 r = 1; if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; } if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; } if (xx >= 0x100000000) { xx >>= 32; r <<= 16; } if (xx >= 0x10000) { xx >>= 16; r <<= 8; } if (xx >= 0x100) { xx >>= 8; r <<= 4; } if (xx >= 0x10) { xx >>= 4; r <<= 2; } if (xx >= 0x4) { r <<= 1; } r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; // Seven iterations should be enough uint256 r1 = x / r; return uint128 (r < r1 ? r : r1); } } } } // File: @openzeppelin/contracts/utils/math/SafeMath.sol // OpenZeppelin Contracts (last updated v4.9.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/SignedMath.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } } // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v4.9.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) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 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 256, 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 << 3) < value ? 1 : 0); } } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } } // 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/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.9.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. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling 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/Address.sol // OpenZeppelin Contracts (last updated v4.9.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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [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://consensys.net/diligence/blog/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.8.0/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.9.3) (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; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ 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)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ 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"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ 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"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation 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). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // 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 cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } } // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } // File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } // File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // File: @openzeppelin/contracts/token/ERC721/ERC721.sol // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such * that `ownerOf(tokenId)` is `a`. */ // solhint-disable-next-line func-name-mixedcase function __unsafe_increaseBalance(address account, uint256 amount) internal { _balances[account] += amount; } } // File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev See {ERC721-_beforeTokenTransfer}. */ function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual override { super._beforeTokenTransfer(from, to, firstTokenId, batchSize); if (batchSize > 1) { // Will only trigger during construction. Batch transferring (minting) is not available afterwards. revert("ERC721Enumerable: consecutive transfers not supported"); } uint256 tokenId = firstTokenId; if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } } // File: contracts/TalesOfSparta.sol // Custom contract // @title Tales of Sparta // Original Storyboard Comic book Tales of Sparta on Sonic // website: https://sparta.my | telegram: https://t.me/spartaonsonic | twitter: https://x.com/spartaonsonic pragma solidity ^0.8.18; contract Tales_of_Sparta is ERC721Enumerable, Ownable, ReentrancyGuard { constructor(string memory _name, string memory _symbol, address _spartanDAO) ERC721(_name, _symbol) { spartanDAO = _spartanDAO; } using SafeERC20 for IERC20; using Strings for uint256; address public spartanDAO; address private developmentAddress; address public burnAddress; string public baseURI; uint256 public fee = 100 ether; uint256 public sosFee = 0 ether; uint256 public payId = 0; uint256 public immutable supplyCap = 3333; uint256 private startTime = block.timestamp + 1 weeks; uint256 private wlDuration = 60 minutes; uint256 public toll = 100; uint256 public deadtax = 0; uint256 public devtax = 0; uint256 public TotalBurns = 0; uint256 public derpLimit = 100; uint256 public lazybearLimit = 100; uint256 public brainLimit = 100; uint256 public sosLimit = 100; uint256 public pythLimit = 70; uint256 public contributorLimit = 30; string public Author = "undoxxed"; bool public baseURItype = false; bool public paused = false; modifier onlySpartanDAO() { require(msg.sender == spartanDAO, "Not authorized."); _; } struct TokenInfo { IERC20 paytoken; } struct WhiteList { bool whitelist; uint256 brainNFTowner; uint256 lazybearNFTowner; uint256 derpNFTowner; uint256 pythCommunity; uint256 sosContributor; uint256 earlyContributor; } struct BlackList { bool blacklist; } struct TalesMinted { uint256 talesmint; uint256 brainNFTmints; uint256 lazybearNFTmints; uint256 derpNFTmints; uint256 pythMints; uint256 sosMints; uint256 contributorMints; } //Array TokenInfo[] public AllowedCrypto; //Maps mapping (address => WhiteList) public whitelisted; mapping (uint256 => BlackList) public blacklisted; mapping (address => TalesMinted) public talesminted; function addCurrency(IERC20 _paytoken) external onlySpartanDAO { AllowedCrypto.push( TokenInfo({ paytoken: _paytoken }) ); } function whitelistState() internal returns (bool) { if (!whitelisted[msg.sender].whitelist) return false; uint256 talesUnminted = totalMintable(); if (talesUnminted > 0 && limitCompliance()) { return true; } return false; } function totalMintable() internal view returns (uint256) { uint256 talesOwned = talesminted[msg.sender].talesmint; uint256 talesMintable = whitelisted[msg.sender].brainNFTowner + whitelisted[msg.sender].lazybearNFTowner + whitelisted[msg.sender].derpNFTowner + whitelisted[msg.sender].pythCommunity + whitelisted[msg.sender].sosContributor + whitelisted[msg.sender].earlyContributor; uint256 talesUnminted = talesMintable - talesOwned; require(talesOwned <= talesMintable, "failsafe"); return talesUnminted; } function limitCompliance() internal returns (bool) { if (talesminted[msg.sender].talesmint < 1) { // initialize snapshot record of talesMint talesminted[msg.sender].brainNFTmints = whitelisted[msg.sender].brainNFTowner; talesminted[msg.sender].lazybearNFTmints = whitelisted[msg.sender].lazybearNFTowner; talesminted[msg.sender].derpNFTmints = whitelisted[msg.sender].derpNFTowner; talesminted[msg.sender].pythMints = whitelisted[msg.sender].pythCommunity; talesminted[msg.sender].sosMints = whitelisted[msg.sender].sosContributor; talesminted[msg.sender].contributorMints = whitelisted[msg.sender].earlyContributor; } //Objectively subtract mint from associated whitelist limit if (talesminted[msg.sender].brainNFTmints > 0 && brainLimit > 0) { talesminted[msg.sender].brainNFTmints--; // subtract mint from brain eligibilty whitelist brainLimit--; return true; } else if (talesminted[msg.sender].lazybearNFTmints > 0 && lazybearLimit > 0) { talesminted[msg.sender].lazybearNFTmints--; // subtract mint from lazybear eligibility whitelist lazybearLimit--; return true; } else if (talesminted[msg.sender].derpNFTmints > 0 && derpLimit > 0) { talesminted[msg.sender].derpNFTmints--; //subtract mint from derp eligibility whitelist derpLimit--; return true; } else if (talesminted[msg.sender].pythMints > 0 && pythLimit > 0) { talesminted[msg.sender].pythMints--; // subtract mint from pyth eligibility whitelist pythLimit--; return true; } else if (talesminted[msg.sender].sosMints > 0 && sosLimit > 0) { talesminted[msg.sender].sosMints--; // subtract mint from sos eligibility whitelist sosLimit--; return true; } else if (talesminted[msg.sender].contributorMints > 0 && contributorLimit > 0) { talesminted[msg.sender].contributorMints--; // subtract mint from contributor eligibility whitelist contributorLimit--; return true; } return false; } event proofOfTale(uint256 indexed tokenId); function SpinAWhiteTale() internal { uint256 currentSupply = totalSupply(); require(currentSupply < supplyCap, "Max Exceeded"); uint256 tokenId = currentSupply + 1; // Conditional Mint to the Spartan Reserve for the Sparta of Sonic GambleFi app if (currentSupply > 0 && currentSupply % 10 == 0) { _mint(spartanDAO, tokenId); //Map it blacklisted[tokenId] = BlackList({ blacklist: false }); talesminted[spartanDAO].talesmint++; emit proofOfTale(tokenId); tokenId++; // Increment for the next mint } // Regular Mint _mint(msg.sender, tokenId); //record mint talesminted[msg.sender].talesmint++; //Map it blacklisted[tokenId] = BlackList({ blacklist: false }); emit proofOfTale(tokenId); } function SpinATale() internal { uint256 currentSupply = totalSupply(); require(currentSupply < supplyCap, "Max Exceeded"); uint256 tokenId = currentSupply + 1; // Conditional Mint to the Spartan Reserve for the Sparta of Sonic GambleFi app if (currentSupply > 0 && currentSupply % 10 == 0) { _mint(spartanDAO, tokenId); //Map it blacklisted[tokenId] = BlackList({ blacklist: false }); talesminted[spartanDAO].talesmint++; emit proofOfTale(tokenId); tokenId++; // Increment for the next mint } // Regular Mint _mint(msg.sender, tokenId); //record mint talesminted[msg.sender].talesmint++; //Map it blacklisted[tokenId] = BlackList({ blacklist: false }); emit proofOfTale(tokenId); } function mint() public payable nonReentrant { require(!paused, "Paused Contract"); uint256 supply = totalSupply(); require( supply < supplyCap, "Max Exceeded."); require (startTime < block.timestamp, "Mint Not Live!"); if (whitelistState()) { //Mint a Tale SpinAWhiteTale(); } else { require((startTime + wlDuration) < block.timestamp, "Public Phase Has Not Yet Begun"); require(msg.value == fee, "Insufficient fee"); // Transfer required brain tokens to mint a brain transferTokens(sosFee); // Initiate permaburn from the contract burn(sosFee, toll); //Mint a Tale SpinATale(); } } function burn(uint256 _burnAmount, uint256 _num) internal { uint256 taxed = (_burnAmount * _num)/100 ; uint256 dead = (taxed * deadtax)/100; uint256 dev = (taxed * devtax)/100; TokenInfo storage tokens = AllowedCrypto[payId]; IERC20 paytoken; paytoken = tokens.paytoken; paytoken.transfer(burnAddress, dead); paytoken.transfer(developmentAddress, dev); TotalBurns += dead; } function transferTokens(uint256 _cost) internal { TokenInfo storage tokens = AllowedCrypto[payId]; IERC20 paytoken; paytoken = tokens.paytoken; paytoken.transferFrom(msg.sender,address(this), _cost); } function setValues (uint256 _feeEther, uint256 _sosFeeEther, uint256 _payId, uint256[] calldata _taxes, uint256 _startTime, uint256 _wlDuration, uint256[] calldata _mintLimits) external onlySpartanDAO() { fee = _feeEther * 1 ether; sosFee = _sosFeeEther * 1 ether; payId = _payId; toll = _taxes[0]; deadtax = _taxes[1]; devtax = _taxes[2]; startTime = block.timestamp + (_startTime * 1 days); wlDuration = _wlDuration * 1 minutes; brainLimit = _mintLimits[0]; derpLimit = _mintLimits[1]; lazybearLimit = _mintLimits[2]; pythLimit = _mintLimits[3]; sosLimit = _mintLimits[4]; contributorLimit = _mintLimits[5]; } function changeOwner(address newOwner) external onlySpartanDAO { // Update the owner to the new owner transferOwnership(newOwner); } function withdraw(uint256 _amount) external payable onlySpartanDAO nonReentrant { address payable _owner = payable(owner()); _owner.transfer(_amount); } function withdrawERC20(uint256 _payId, uint256 _amount) external payable onlySpartanDAO nonReentrant { TokenInfo storage tokens = AllowedCrypto[_payId]; IERC20 paytoken; paytoken = tokens.paytoken; paytoken.transfer(msg.sender, _amount); } function _baseURI() internal view virtual override returns (string memory) { return baseURI; } function updateBaseURI(string memory _newLink) external onlySpartanDAO() { baseURI = _newLink; } function setBaseURItype() external onlySpartanDAO() { if (!baseURItype) { baseURItype = true; } else { baseURItype = false; } } function tokenURI(uint256 _tokenId) public view override returns (string memory) { require(_tokenId <= totalSupply(), "Not Found"); string memory uriBase = baseURI; if (blacklisted[_tokenId].blacklist) { return bytes(uriBase).length > 0 ? string(abi.encodePacked(uriBase, "blacklisted", ".json")) : ""; } if (baseURItype) { return bytes(uriBase).length > 0 ? string(abi.encodePacked(uriBase, _tokenId.toString(), ".json")) : ""; } return bytes(uriBase).length > 0 ? string(abi.encodePacked(uriBase, "alpha", ".json")) : ""; } event Pause(); function pause() public onlySpartanDAO { require(!paused, "Already paused."); paused = true; emit Pause(); } event Unpause(); function unpause() public onlySpartanDAO { require(paused, "Not paused."); paused = false; emit Unpause(); } // Helpers function addToBrainWhitelist(address[] calldata _address, uint256[] calldata _amount) external onlySpartanDAO { for (uint256 i = 0; i < _address.length; i++) { whitelisted[_address[i]].whitelist = true; whitelisted[_address[i]].brainNFTowner = _amount[i]; } } function addToLazyBearWhitelist(address[] calldata _address, uint256[] calldata _amount) external onlySpartanDAO { for (uint256 i = 0; i < _address.length; i++) { whitelisted[_address[i]].whitelist = true; whitelisted[_address[i]].lazybearNFTowner = _amount[i]; } } function addToDerpWhitelist(address[] calldata _address, uint256[] calldata _amount) external onlySpartanDAO { for (uint256 i = 0; i < _address.length; i++) { whitelisted[_address[i]].whitelist = true; whitelisted[_address[i]].derpNFTowner = _amount[i]; } } function addToPythWhitelist(address[] calldata _address, uint256[] calldata _amount) external onlySpartanDAO { for (uint256 i = 0; i < _address.length; i++) { whitelisted[_address[i]].whitelist = true; whitelisted[_address[i]].pythCommunity = _amount[i]; } } function addToSosWhitelist(address[] calldata _address, uint256[] calldata _amount) external onlySpartanDAO { for (uint256 i = 0; i < _address.length; i++) { whitelisted[_address[i]].whitelist = true; whitelisted[_address[i]].sosContributor = _amount[i]; } } function addToEarlyWhitelist(address[] calldata _address, uint256[] calldata _amount) external onlySpartanDAO { for (uint256 i = 0; i < _address.length; i++) { whitelisted[_address[i]].whitelist = true; whitelisted[_address[i]].earlyContributor = _amount[i]; } } function addToBlacklist(uint256[] calldata _nfts) external onlySpartanDAO { for (uint256 i = 0; i < _nfts.length; i++) { blacklisted[_nfts[i]].blacklist = true; } } function removeFromWhitelist(address[] calldata _address) external onlySpartanDAO { for (uint256 i = 0; i < _address.length; i++) { whitelisted[_address[i]].whitelist = false; whitelisted[_address[i]].brainNFTowner = 0; whitelisted[_address[i]].lazybearNFTowner = 0; whitelisted[_address[i]].derpNFTowner = 0; whitelisted[_address[i]].pythCommunity = 0; whitelisted[_address[i]].sosContributor = 0; whitelisted[_address[i]].earlyContributor = 0; } } function removeFromBlacklist(uint256[] calldata _nfts) external onlySpartanDAO { for (uint256 i = 0; i < _nfts.length; i++) { blacklisted[_nfts[i]].blacklist = false; } } function setDAO (address _spartanDAO) external onlySpartanDAO { spartanDAO = _spartanDAO; } function setAddresses (address _address1, address _address2) external onlySpartanDAO { burnAddress = _address1; developmentAddress = _address2; } function setAuthor (string memory _reveal) external onlySpartanDAO { Author = _reveal; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_spartanDAO","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","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":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"proofOfTale","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"AllowedCrypto","outputs":[{"internalType":"contract IERC20","name":"paytoken","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Author","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TotalBurns","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_paytoken","type":"address"}],"name":"addCurrency","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_nfts","type":"uint256[]"}],"name":"addToBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_address","type":"address[]"},{"internalType":"uint256[]","name":"_amount","type":"uint256[]"}],"name":"addToBrainWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_address","type":"address[]"},{"internalType":"uint256[]","name":"_amount","type":"uint256[]"}],"name":"addToDerpWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_address","type":"address[]"},{"internalType":"uint256[]","name":"_amount","type":"uint256[]"}],"name":"addToEarlyWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_address","type":"address[]"},{"internalType":"uint256[]","name":"_amount","type":"uint256[]"}],"name":"addToLazyBearWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_address","type":"address[]"},{"internalType":"uint256[]","name":"_amount","type":"uint256[]"}],"name":"addToPythWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_address","type":"address[]"},{"internalType":"uint256[]","name":"_amount","type":"uint256[]"}],"name":"addToSosWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURItype","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"blacklisted","outputs":[{"internalType":"bool","name":"blacklist","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"brainLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"changeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contributorLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deadtax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"derpLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"devtax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lazybearLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"payId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pythLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_nfts","type":"uint256[]"}],"name":"removeFromBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_address","type":"address[]"}],"name":"removeFromWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address1","type":"address"},{"internalType":"address","name":"_address2","type":"address"}],"name":"setAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_reveal","type":"string"}],"name":"setAuthor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setBaseURItype","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_spartanDAO","type":"address"}],"name":"setDAO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feeEther","type":"uint256"},{"internalType":"uint256","name":"_sosFeeEther","type":"uint256"},{"internalType":"uint256","name":"_payId","type":"uint256"},{"internalType":"uint256[]","name":"_taxes","type":"uint256[]"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_wlDuration","type":"uint256"},{"internalType":"uint256[]","name":"_mintLimits","type":"uint256[]"}],"name":"setValues","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sosFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sosLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"spartanDAO","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supplyCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"talesminted","outputs":[{"internalType":"uint256","name":"talesmint","type":"uint256"},{"internalType":"uint256","name":"brainNFTmints","type":"uint256"},{"internalType":"uint256","name":"lazybearNFTmints","type":"uint256"},{"internalType":"uint256","name":"derpNFTmints","type":"uint256"},{"internalType":"uint256","name":"pythMints","type":"uint256"},{"internalType":"uint256","name":"sosMints","type":"uint256"},{"internalType":"uint256","name":"contributorMints","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toll","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newLink","type":"string"}],"name":"updateBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelisted","outputs":[{"internalType":"bool","name":"whitelist","type":"bool"},{"internalType":"uint256","name":"brainNFTowner","type":"uint256"},{"internalType":"uint256","name":"lazybearNFTowner","type":"uint256"},{"internalType":"uint256","name":"derpNFTowner","type":"uint256"},{"internalType":"uint256","name":"pythCommunity","type":"uint256"},{"internalType":"uint256","name":"sosContributor","type":"uint256"},{"internalType":"uint256","name":"earlyContributor","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_payId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawERC20","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
60a060405268056bc75e2d6310000060105560006011819055601255610d05608052620000304262093a8062000197565b601355610e10601455606460155560006016556000601755600060185560646019556064601a556064601b556064601c556046601d55601e8055604051806040016040528060088152602001671d5b991bde1e195960c21b815250601f90816200009b919062000264565b506020805461ffff19169055348015620000b457600080fd5b506040516200474538038062004745833981016040819052620000d791620003df565b82826000620000e7838262000264565b506001620000f6828262000264565b505050620001136200010d6200014160201b60201c565b62000145565b6001600b55600c80546001600160a01b0319166001600160a01b0392909216919091179055506200046c9050565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80820180821115620001b957634e487b7160e01b600052601160045260246000fd5b92915050565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620001ea57607f821691505b6020821081036200020b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200025f57600081815260208120601f850160051c810160208610156200023a5750805b601f850160051c820191505b818110156200025b5782815560010162000246565b5050505b505050565b81516001600160401b03811115620002805762000280620001bf565b6200029881620002918454620001d5565b8462000211565b602080601f831160018114620002d05760008415620002b75750858301515b600019600386901b1c1916600185901b1785556200025b565b600085815260208120601f198616915b828110156200030157888601518255948401946001909101908401620002e0565b5085821015620003205787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600082601f8301126200034257600080fd5b81516001600160401b03808211156200035f576200035f620001bf565b604051601f8301601f19908116603f011681019082821181831017156200038a576200038a620001bf565b81604052838152602092508683858801011115620003a757600080fd5b600091505b83821015620003cb5785820183015181830184015290820190620003ac565b600093810190920192909252949350505050565b600080600060608486031215620003f557600080fd5b83516001600160401b03808211156200040d57600080fd5b6200041b8783880162000330565b945060208601519150808211156200043257600080fd5b50620004418682870162000330565b604086015190935090506001600160a01b03811681146200046157600080fd5b809150509250925092565b6080516142af620004966000396000818161086f0152818161104401526127aa01526142af6000f3fe6080604052600436106103ce5760003560e01c8063717ceba2116101fd578063a6f9dae111610118578063d936547e116100ab578063e985e9c51161007a578063e985e9c514610b91578063f0c1e5ee14610bda578063f2fde38b14610bfa578063f41dfb1b14610c1a578063f49ae8be14610c3057600080fd5b8063d936547e14610ab5578063ddca3f4314610b48578063e00e8bf314610b5e578063e73a914c14610b7157600080fd5b8063c84200bf116100e7578063c84200bf14610a49578063c87b56dd14610a69578063c8c1f3f514610a89578063cc2129bf14610a9f57600080fd5b8063a6f9dae11461095c578063b5c455ec1461097c578063b88d4fde14610a09578063c5461d5014610a2957600080fd5b80638f770ad01161019057806395d89b411161015f57806395d89b41146108f157806398f4c9ed146109065780639f8175bd1461091c578063a22cb4651461093c57600080fd5b80638f770ad01461085d57806390107afe1461089157806392201a4a146108b1578063931688cb146108d157600080fd5b80638456cb59116101cc5780638456cb59146107f45780638ab234b6146108095780638c82ce3f146108295780638da5cb5b1461083f57600080fd5b8063717ceba21461077e5780637202a13a1461079457806377d140dc146107b45780637ecbaeb1146107d457600080fd5b80633d40bfb4116102ed5780635c983aec116102805780637017b8ed1161024f5780637017b8ed1461071357806370a082311461072957806370d5ae0514610749578063715018a61461076957600080fd5b80635c983aec146106a85780635f637025146106c85780636352211e146106de5780636c0360eb146106fe57600080fd5b80634f6ccce7116102bc5780634f6ccce714610634578063548db1741461065457806355aeba64146106745780635c975abb1461068957600080fd5b80633d40bfb4146105c95780633f4ba83a146105df5780633fe14e03146105f457806342842e0e1461061457600080fd5b806320b2af5211610365578063285aaa2011610334578063285aaa201461056a5780632e1a7d4d146105805780632f745c59146105935780633bff053f146105b357600080fd5b806320b2af52146104e557806323b872dd146104fa57806323db4c911461051a57806326c91cad1461054a57600080fd5b806311452462116103a157806311452462146104845780631249c58b146104a4578063146a775c146104ac57806318160ddd146104c657600080fd5b806301ffc9a7146103d357806306fdde0314610408578063081812fc1461042a578063095ea7b314610462575b600080fd5b3480156103df57600080fd5b506103f36103ee36600461394d565b610c46565b60405190151581526020015b60405180910390f35b34801561041457600080fd5b5061041d610c71565b6040516103ff91906139ba565b34801561043657600080fd5b5061044a6104453660046139cd565b610d03565b6040516001600160a01b0390911681526020016103ff565b34801561046e57600080fd5b5061048261047d3660046139fb565b610d2a565b005b34801561049057600080fd5b5061048261049f366004613a73565b610e44565b610482610fe3565b3480156104b857600080fd5b506020546103f39060ff1681565b3480156104d257600080fd5b506008545b6040519081526020016103ff565b3480156104f157600080fd5b5061041d6111cd565b34801561050657600080fd5b50610482610515366004613b15565b61125b565b34801561052657600080fd5b506103f36105353660046139cd565b60236020526000908152604090205460ff1681565b34801561055657600080fd5b5061044a6105653660046139cd565b61128c565b34801561057657600080fd5b506104d760155481565b61048261058e3660046139cd565b6112b6565b34801561059f57600080fd5b506104d76105ae3660046139fb565b611344565b3480156105bf57600080fd5b506104d760195481565b3480156105d557600080fd5b506104d7601a5481565b3480156105eb57600080fd5b506104826113da565b34801561060057600080fd5b5061048261060f366004613be2565b61147f565b34801561062057600080fd5b5061048261062f366004613b15565b6114b9565b34801561064057600080fd5b506104d761064f3660046139cd565b6114d4565b34801561066057600080fd5b5061048261066f366004613c2b565b611567565b34801561068057600080fd5b506104826117f1565b34801561069557600080fd5b506020546103f390610100900460ff1681565b3480156106b457600080fd5b506104826106c3366004613c2b565b611840565b3480156106d457600080fd5b506104d760165481565b3480156106ea57600080fd5b5061044a6106f93660046139cd565b6118c7565b34801561070a57600080fd5b5061041d611927565b34801561071f57600080fd5b506104d760125481565b34801561073557600080fd5b506104d7610744366004613c6d565b611934565b34801561075557600080fd5b50600e5461044a906001600160a01b031681565b34801561077557600080fd5b506104826119ba565b34801561078a57600080fd5b506104d760115481565b3480156107a057600080fd5b506104826107af366004613c8a565b6119cc565b3480156107c057600080fd5b50600c5461044a906001600160a01b031681565b3480156107e057600080fd5b506104826107ef366004613c8a565b611ad0565b34801561080057600080fd5b50610482611bcd565b34801561081557600080fd5b50610482610824366004613c6d565b611c7b565b34801561083557600080fd5b506104d760175481565b34801561084b57600080fd5b50600a546001600160a01b031661044a565b34801561086957600080fd5b506104d77f000000000000000000000000000000000000000000000000000000000000000081565b34801561089d57600080fd5b506104826108ac366004613cf6565b611d08565b3480156108bd57600080fd5b506104826108cc366004613c2b565b611d60565b3480156108dd57600080fd5b506104826108ec366004613be2565b611de7565b3480156108fd57600080fd5b5061041d611e1d565b34801561091257600080fd5b506104d7601e5481565b34801561092857600080fd5b50610482610937366004613c8a565b611e2c565b34801561094857600080fd5b50610482610957366004613d3d565b611f29565b34801561096857600080fd5b50610482610977366004613c6d565b611f34565b34801561098857600080fd5b506109d4610997366004613c6d565b6024602052600090815260409020805460018201546002830154600384015460048501546005860154600690960154949593949293919290919087565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016103ff565b348015610a1557600080fd5b50610482610a24366004613d6b565b611f67565b348015610a3557600080fd5b50610482610a44366004613c8a565b611f9f565b348015610a5557600080fd5b50610482610a64366004613c8a565b61209c565b348015610a7557600080fd5b5061041d610a843660046139cd565b612199565b348015610a9557600080fd5b506104d7601d5481565b348015610aab57600080fd5b506104d7601c5481565b348015610ac157600080fd5b50610b11610ad0366004613c6d565b602260205260009081526040902080546001820154600283015460038401546004850154600586015460069096015460ff9095169593949293919290919087565b6040805197151588526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016103ff565b348015610b5457600080fd5b506104d760105481565b610482610b6c366004613deb565b61233f565b348015610b7d57600080fd5b50610482610b8c366004613c6d565b612415565b348015610b9d57600080fd5b506103f3610bac366004613cf6565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610be657600080fd5b50610482610bf5366004613c8a565b612461565b348015610c0657600080fd5b50610482610c15366004613c6d565b61255e565b348015610c2657600080fd5b506104d7601b5481565b348015610c3c57600080fd5b506104d760185481565b60006001600160e01b0319821663780e9d6360e01b1480610c6b5750610c6b826125d4565b92915050565b606060008054610c8090613e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610cac90613e0d565b8015610cf95780601f10610cce57610100808354040283529160200191610cf9565b820191906000526020600020905b815481529060010190602001808311610cdc57829003601f168201915b5050505050905090565b6000610d0e82612624565b506000908152600460205260409020546001600160a01b031690565b6000610d35826118c7565b9050806001600160a01b0316836001600160a01b031603610da75760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b0382161480610dc35750610dc38133610bac565b610e355760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610d9e565b610e3f8383612683565b505050565b600c546001600160a01b03163314610e6e5760405162461bcd60e51b8152600401610d9e90613e47565b610e8089670de0b6b3a7640000613e86565b601055610e9588670de0b6b3a7640000613e86565b60115560128790558585600081610eae57610eae613e9d565b60200291909101356015555085856001818110610ecd57610ecd613e9d565b60200291909101356016555085856002818110610eec57610eec613e9d565b602002919091013560175550610f058462015180613e86565b610f0f9042613eb3565b601355610f1d83603c613e86565b6014558181600081610f3157610f31613e9d565b6020029190910135601b555081816001818110610f5057610f50613e9d565b60200291909101356019555081816002818110610f6f57610f6f613e9d565b6020029190910135601a555081816003818110610f8e57610f8e613e9d565b6020029190910135601d555081816004818110610fad57610fad613e9d565b6020029190910135601c555081816005818110610fcc57610fcc613e9d565b6020029190910135601e5550505050505050505050565b610feb6126f1565b602054610100900460ff16156110355760405162461bcd60e51b815260206004820152600f60248201526e14185d5cd9590810dbdb9d1c9858dd608a1b6044820152606401610d9e565b600061104060085490565b90507f000000000000000000000000000000000000000000000000000000000000000081106110a15760405162461bcd60e51b815260206004820152600d60248201526c26b0bc1022bc31b2b2b232b21760991b6044820152606401610d9e565b42601354106110e35760405162461bcd60e51b815260206004820152600e60248201526d4d696e74204e6f74204c6976652160901b6044820152606401610d9e565b6110eb61274a565b156110fd576110f861279b565b6111c0565b4260145460135461110e9190613eb3565b1061115b5760405162461bcd60e51b815260206004820152601e60248201527f5075626c696320506861736520486173204e6f742059657420426567756e00006044820152606401610d9e565b601054341461119f5760405162461bcd60e51b815260206004820152601060248201526f496e73756666696369656e742066656560801b6044820152606401610d9e565b6111aa60115461294f565b6111b86011546015546129ee565b6111c061279b565b506111cb6001600b55565b565b601f80546111da90613e0d565b80601f016020809104026020016040519081016040528092919081815260200182805461120690613e0d565b80156112535780601f1061122857610100808354040283529160200191611253565b820191906000526020600020905b81548152906001019060200180831161123657829003601f168201915b505050505081565b6112653382612b7b565b6112815760405162461bcd60e51b8152600401610d9e90613ec6565b610e3f838383612bfa565b6021818154811061129c57600080fd5b6000918252602090912001546001600160a01b0316905081565b600c546001600160a01b031633146112e05760405162461bcd60e51b8152600401610d9e90613e47565b6112e86126f1565b60006112fc600a546001600160a01b031690565b6040519091506001600160a01b0382169083156108fc029084906000818181858888f19350505050158015611335573d6000803e3d6000fd5b50506113416001600b55565b50565b600061134f83611934565b82106113b15760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610d9e565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600c546001600160a01b031633146114045760405162461bcd60e51b8152600401610d9e90613e47565b602054610100900460ff166114495760405162461bcd60e51b815260206004820152600b60248201526a2737ba103830bab9b2b21760a91b6044820152606401610d9e565b6020805461ff00191690556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3390600090a1565b600c546001600160a01b031633146114a95760405162461bcd60e51b8152600401610d9e90613e47565b601f6114b58282613f61565b5050565b610e3f83838360405180602001604052806000815250611f67565b60006114df60085490565b82106115425760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610d9e565b6008828154811061155557611555613e9d565b90600052602060002001549050919050565b600c546001600160a01b031633146115915760405162461bcd60e51b8152600401610d9e90613e47565b60005b81811015610e3f576000602260008585858181106115b4576115b4613e9d565b90506020020160208101906115c99190613c6d565b6001600160a01b0316815260208101919091526040016000908120805460ff19169215159290921790915560228185858581811061160957611609613e9d565b905060200201602081019061161e9190613c6d565b6001600160a01b03166001600160a01b031681526020019081526020016000206001018190555060006022600085858581811061165d5761165d613e9d565b90506020020160208101906116729190613c6d565b6001600160a01b03166001600160a01b03168152602001908152602001600020600201819055506000602260008585858181106116b1576116b1613e9d565b90506020020160208101906116c69190613c6d565b6001600160a01b03166001600160a01b031681526020019081526020016000206003018190555060006022600085858581811061170557611705613e9d565b905060200201602081019061171a9190613c6d565b6001600160a01b03166001600160a01b031681526020019081526020016000206004018190555060006022600085858581811061175957611759613e9d565b905060200201602081019061176e9190613c6d565b6001600160a01b03166001600160a01b03168152602001908152602001600020600501819055506000602260008585858181106117ad576117ad613e9d565b90506020020160208101906117c29190613c6d565b6001600160a01b03168152602081019190915260400160002060060155806117e981614021565b915050611594565b600c546001600160a01b0316331461181b5760405162461bcd60e51b8152600401610d9e90613e47565b60205460ff16611834576020805460ff19166001179055565b6020805460ff19169055565b600c546001600160a01b0316331461186a5760405162461bcd60e51b8152600401610d9e90613e47565b60005b81811015610e3f5760016023600085858581811061188d5761188d613e9d565b60209081029290920135835250810191909152604001600020805460ff1916911515919091179055806118bf81614021565b91505061186d565b6000818152600260205260408120546001600160a01b031680610c6b5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610d9e565b600f80546111da90613e0d565b60006001600160a01b03821661199e5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610d9e565b506001600160a01b031660009081526003602052604090205490565b6119c2612d6b565b6111cb6000612dc5565b600c546001600160a01b031633146119f65760405162461bcd60e51b8152600401610d9e90613e47565b60005b83811015611ac957600160226000878785818110611a1957611a19613e9d565b9050602002016020810190611a2e9190613c6d565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055828282818110611a6857611a68613e9d565b9050602002013560226000878785818110611a8557611a85613e9d565b9050602002016020810190611a9a9190613c6d565b6001600160a01b0316815260208101919091526040016000206004015580611ac181614021565b9150506119f9565b5050505050565b600c546001600160a01b03163314611afa5760405162461bcd60e51b8152600401610d9e90613e47565b60005b83811015611ac957600160226000878785818110611b1d57611b1d613e9d565b9050602002016020810190611b329190613c6d565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055828282818110611b6c57611b6c613e9d565b9050602002013560226000878785818110611b8957611b89613e9d565b9050602002016020810190611b9e9190613c6d565b6001600160a01b0316815260208101919091526040016000206003015580611bc581614021565b915050611afd565b600c546001600160a01b03163314611bf75760405162461bcd60e51b8152600401610d9e90613e47565b602054610100900460ff1615611c415760405162461bcd60e51b815260206004820152600f60248201526e20b63932b0b23c903830bab9b2b21760891b6044820152606401610d9e565b6020805461ff0019166101001790556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62590600090a1565b600c546001600160a01b03163314611ca55760405162461bcd60e51b8152600401610d9e90613e47565b60408051602081019091526001600160a01b0391821681526021805460018101825560009190915290517f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57090910180546001600160a01b03191691909216179055565b600c546001600160a01b03163314611d325760405162461bcd60e51b8152600401610d9e90613e47565b600e80546001600160a01b039384166001600160a01b031991821617909155600d8054929093169116179055565b600c546001600160a01b03163314611d8a5760405162461bcd60e51b8152600401610d9e90613e47565b60005b81811015610e3f57600060236000858585818110611dad57611dad613e9d565b60209081029290920135835250810191909152604001600020805460ff191691151591909117905580611ddf81614021565b915050611d8d565b600c546001600160a01b03163314611e115760405162461bcd60e51b8152600401610d9e90613e47565b600f6114b58282613f61565b606060018054610c8090613e0d565b600c546001600160a01b03163314611e565760405162461bcd60e51b8152600401610d9e90613e47565b60005b83811015611ac957600160226000878785818110611e7957611e79613e9d565b9050602002016020810190611e8e9190613c6d565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055828282818110611ec857611ec8613e9d565b9050602002013560226000878785818110611ee557611ee5613e9d565b9050602002016020810190611efa9190613c6d565b6001600160a01b0316815260208101919091526040016000206001015580611f2181614021565b915050611e59565b6114b5338383612e17565b600c546001600160a01b03163314611f5e5760405162461bcd60e51b8152600401610d9e90613e47565b6113418161255e565b611f713383612b7b565b611f8d5760405162461bcd60e51b8152600401610d9e90613ec6565b611f9984848484612ee5565b50505050565b600c546001600160a01b03163314611fc95760405162461bcd60e51b8152600401610d9e90613e47565b60005b83811015611ac957600160226000878785818110611fec57611fec613e9d565b90506020020160208101906120019190613c6d565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905582828281811061203b5761203b613e9d565b905060200201356022600087878581811061205857612058613e9d565b905060200201602081019061206d9190613c6d565b6001600160a01b031681526020810191909152604001600020600601558061209481614021565b915050611fcc565b600c546001600160a01b031633146120c65760405162461bcd60e51b8152600401610d9e90613e47565b60005b83811015611ac9576001602260008787858181106120e9576120e9613e9d565b90506020020160208101906120fe9190613c6d565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905582828281811061213857612138613e9d565b905060200201356022600087878581811061215557612155613e9d565b905060200201602081019061216a9190613c6d565b6001600160a01b031681526020810191909152604001600020600201558061219181614021565b9150506120c9565b60606121a460085490565b8211156121df5760405162461bcd60e51b8152602060048201526009602482015268139bdd08119bdd5b9960ba1b6044820152606401610d9e565b6000600f80546121ee90613e0d565b80601f016020809104026020016040519081016040528092919081815260200182805461221a90613e0d565b80156122675780601f1061223c57610100808354040283529160200191612267565b820191906000526020600020905b81548152906001019060200180831161224a57829003601f168201915b505050600086815260236020526040902054929350505060ff16156122cc5760008151116122a457604051806020016040528060008152506122c5565b806040516020016122b5919061403a565b6040516020818303038152906040525b9392505050565b60205460ff16156123105760008151116122f557604051806020016040528060008152506122c5565b806122ff84612f18565b6040516020016122b5929190614077565b600081511161232e57604051806020016040528060008152506122c5565b806040516020016122b591906140b6565b600c546001600160a01b031633146123695760405162461bcd60e51b8152600401610d9e90613e47565b6123716126f1565b60006021838154811061238657612386613e9d565b6000918252602090912001805460405163a9059cbb60e01b8152336004820152602481018590529192506001600160a01b031690819063a9059cbb906044016020604051808303816000875af11580156123e4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240891906140ed565b5050506114b56001600b55565b600c546001600160a01b0316331461243f5760405162461bcd60e51b8152600401610d9e90613e47565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b600c546001600160a01b0316331461248b5760405162461bcd60e51b8152600401610d9e90613e47565b60005b83811015611ac9576001602260008787858181106124ae576124ae613e9d565b90506020020160208101906124c39190613c6d565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558282828181106124fd576124fd613e9d565b905060200201356022600087878581811061251a5761251a613e9d565b905060200201602081019061252f9190613c6d565b6001600160a01b031681526020810191909152604001600020600501558061255681614021565b91505061248e565b612566612d6b565b6001600160a01b0381166125cb5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d9e565b61134181612dc5565b60006001600160e01b031982166380ac58cd60e01b148061260557506001600160e01b03198216635b5e139f60e01b145b80610c6b57506301ffc9a760e01b6001600160e01b0319831614610c6b565b6000818152600260205260409020546001600160a01b03166113415760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610d9e565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906126b8826118c7565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6002600b54036127435760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610d9e565b6002600b55565b3360009081526022602052604081205460ff166127675750600090565b6000612771612fab565b90506000811180156127865750612786613062565b1561279357600191505090565b600091505090565b60006127a660085490565b90507f000000000000000000000000000000000000000000000000000000000000000081106128065760405162461bcd60e51b815260206004820152600c60248201526b13585e08115e18d95959195960a21b6044820152606401610d9e565b6000612813826001613eb3565b905060008211801561282d575061282b600a83614120565b155b156128d057600c54612848906001600160a01b031682613308565b60408051602080820183526000808352848152602382528381209251835460ff191690151517909255600c546001600160a01b031682526024905290812080549161289283614021565b909155505060405181907facb55af3158df90a7759d626bd07a674a61a33c821bfd3816649a8757df0233290600090a2806128cc81614021565b9150505b6128da3382613308565b3360009081526024602052604081208054916128f583614021565b90915550506040805160208082018352600080835284815260239091528281209151825460ff191690151517909155905182917facb55af3158df90a7759d626bd07a674a61a33c821bfd3816649a8757df0233291a25050565b600060216012548154811061296657612966613e9d565b600091825260209091200180546040516323b872dd60e01b8152336004820152306024820152604481018590529192506001600160a01b03169081906323b872dd906064016020604051808303816000875af11580156129ca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9991906140ed565b600060646129fc8385613e86565b612a069190614134565b90506000606460165483612a1a9190613e86565b612a249190614134565b90506000606460175484612a389190613e86565b612a429190614134565b90506000602160125481548110612a5b57612a5b613e9d565b60009182526020909120018054600e5460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018790529293501690819063a9059cbb906044016020604051808303816000875af1158015612abe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ae291906140ed565b50600d5460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018590529082169063a9059cbb906044016020604051808303816000875af1158015612b36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b5a91906140ed565b508360186000828254612b6d9190613eb3565b909155505050505050505050565b600080612b87836118c7565b9050806001600160a01b0316846001600160a01b03161480612bce57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80612bf25750836001600160a01b0316612be784610d03565b6001600160a01b0316145b949350505050565b826001600160a01b0316612c0d826118c7565b6001600160a01b031614612c335760405162461bcd60e51b8152600401610d9e90614148565b6001600160a01b038216612c955760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610d9e565b612ca283838360016134a1565b826001600160a01b0316612cb5826118c7565b6001600160a01b031614612cdb5760405162461bcd60e51b8152600401610d9e90614148565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a546001600160a01b031633146111cb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d9e565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b031603612e785760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610d9e565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612ef0848484612bfa565b612efc848484846135ce565b611f995760405162461bcd60e51b8152600401610d9e9061418d565b60606000612f25836136cf565b600101905060008167ffffffffffffffff811115612f4557612f45613b56565b6040519080825280601f01601f191660200182016040528015612f6f576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084612f7957509392505050565b3360009081526024602090815260408083205460229092528220600681015460058201546004830154600384015460028501546001909501548795612fef91613eb3565b612ff99190613eb3565b6130039190613eb3565b61300d9190613eb3565b6130179190613eb3565b9050600061302583836141df565b9050818311156122c55760405162461bcd60e51b81526020600482015260086024820152676661696c7361666560c01b6044820152606401610d9e565b33600090815260246020526040812054600111156130d45733600090815260226020908152604080832060018082015460249094529190932090810191909155600280830154908201556003808301549082015560048083015490820155600580830154908201556006918201549101555b33600090815260246020526040902060010154158015906130f757506000601b54115b1561313b5733600090815260246020526040812060010180549161311a836141f2565b9091555050601b805490600061312f836141f2565b91905055506001905090565b336000908152602460205260409020600201541580159061315e57506000601a54115b1561319657336000908152602460205260408120600201805491613181836141f2565b9091555050601a805490600061312f836141f2565b33600090815260246020526040902060030154158015906131b957506000601954115b156131f1573360009081526024602052604081206003018054916131dc836141f2565b90915550506019805490600061312f836141f2565b336000908152602460205260409020600401541580159061321457506000601d54115b1561324c57336000908152602460205260408120600401805491613237836141f2565b9091555050601d805490600061312f836141f2565b336000908152602460205260409020600501541580159061326f57506000601c54115b156132a757336000908152602460205260408120600501805491613292836141f2565b9091555050601c805490600061312f836141f2565b33600090815260246020526040902060060154158015906132ca57506000601e54115b15613302573360009081526024602052604081206006018054916132ed836141f2565b9091555050601e805490600061312f836141f2565b50600090565b6001600160a01b03821661335e5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610d9e565b6000818152600260205260409020546001600160a01b0316156133c35760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610d9e565b6133d16000838360016134a1565b6000818152600260205260409020546001600160a01b0316156134365760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610d9e565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60018111156135105760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610d9e565b816001600160a01b03851661356c5761356781600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b61358f565b836001600160a01b0316856001600160a01b03161461358f5761358f85826137a7565b6001600160a01b0384166135ab576135a681613844565b611ac9565b846001600160a01b0316846001600160a01b031614611ac957611ac984826138f3565b60006001600160a01b0384163b156136c457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613612903390899088908890600401614209565b6020604051808303816000875af192505050801561364d575060408051601f3d908101601f1916820190925261364a91810190614246565b60015b6136aa573d80801561367b576040519150601f19603f3d011682016040523d82523d6000602084013e613680565b606091505b5080516000036136a25760405162461bcd60e51b8152600401610d9e9061418d565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612bf2565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b831061370e5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061373a576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061375857662386f26fc10000830492506010015b6305f5e1008310613770576305f5e100830492506008015b612710831061378457612710830492506004015b60648310613796576064830492506002015b600a8310610c6b5760010192915050565b600060016137b484611934565b6137be91906141df565b600083815260076020526040902054909150808214613811576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090613856906001906141df565b6000838152600960205260408120546008805493945090928490811061387e5761387e613e9d565b90600052602060002001549050806008838154811061389f5761389f613e9d565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806138d7576138d7614263565b6001900381819060005260206000200160009055905550505050565b60006138fe83611934565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160e01b03198116811461134157600080fd5b60006020828403121561395f57600080fd5b81356122c581613937565b60005b8381101561398557818101518382015260200161396d565b50506000910152565b600081518084526139a681602086016020860161396a565b601f01601f19169290920160200192915050565b6020815260006122c5602083018461398e565b6000602082840312156139df57600080fd5b5035919050565b6001600160a01b038116811461134157600080fd5b60008060408385031215613a0e57600080fd5b8235613a19816139e6565b946020939093013593505050565b60008083601f840112613a3957600080fd5b50813567ffffffffffffffff811115613a5157600080fd5b6020830191508360208260051b8501011115613a6c57600080fd5b9250929050565b600080600080600080600080600060e08a8c031215613a9157600080fd5b8935985060208a0135975060408a0135965060608a013567ffffffffffffffff80821115613abe57600080fd5b613aca8d838e01613a27565b909850965060808c0135955060a08c0135945060c08c0135915080821115613af157600080fd5b50613afe8c828d01613a27565b915080935050809150509295985092959850929598565b600080600060608486031215613b2a57600080fd5b8335613b35816139e6565b92506020840135613b45816139e6565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115613b8757613b87613b56565b604051601f8501601f19908116603f01168101908282118183101715613baf57613baf613b56565b81604052809350858152868686011115613bc857600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215613bf457600080fd5b813567ffffffffffffffff811115613c0b57600080fd5b8201601f81018413613c1c57600080fd5b612bf284823560208401613b6c565b60008060208385031215613c3e57600080fd5b823567ffffffffffffffff811115613c5557600080fd5b613c6185828601613a27565b90969095509350505050565b600060208284031215613c7f57600080fd5b81356122c5816139e6565b60008060008060408587031215613ca057600080fd5b843567ffffffffffffffff80821115613cb857600080fd5b613cc488838901613a27565b90965094506020870135915080821115613cdd57600080fd5b50613cea87828801613a27565b95989497509550505050565b60008060408385031215613d0957600080fd5b8235613d14816139e6565b91506020830135613d24816139e6565b809150509250929050565b801515811461134157600080fd5b60008060408385031215613d5057600080fd5b8235613d5b816139e6565b91506020830135613d2481613d2f565b60008060008060808587031215613d8157600080fd5b8435613d8c816139e6565b93506020850135613d9c816139e6565b925060408501359150606085013567ffffffffffffffff811115613dbf57600080fd5b8501601f81018713613dd057600080fd5b613ddf87823560208401613b6c565b91505092959194509250565b60008060408385031215613dfe57600080fd5b50508035926020909101359150565b600181811c90821680613e2157607f821691505b602082108103613e4157634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600f908201526e2737ba1030baba3437b934bd32b21760891b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610c6b57610c6b613e70565b634e487b7160e01b600052603260045260246000fd5b80820180821115610c6b57610c6b613e70565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b601f821115610e3f57600081815260208120601f850160051c81016020861015613f3a5750805b601f850160051c820191505b81811015613f5957828155600101613f46565b505050505050565b815167ffffffffffffffff811115613f7b57613f7b613b56565b613f8f81613f898454613e0d565b84613f13565b602080601f831160018114613fc45760008415613fac5750858301515b600019600386901b1c1916600185901b178555613f59565b600085815260208120601f198616915b82811015613ff357888601518255948401946001909101908401613fd4565b50858210156140115787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006001820161403357614033613e70565b5060010190565b6000825161404c81846020870161396a565b6a189b1858dadb1a5cdd195960aa1b92019182525064173539b7b760d91b600b820152601001919050565b6000835161408981846020880161396a565b83519083019061409d81836020880161396a565b64173539b7b760d91b9101908152600501949350505050565b600082516140c881846020870161396a565b64616c70686160d81b92019182525064173539b7b760d91b6005820152600a01919050565b6000602082840312156140ff57600080fd5b81516122c581613d2f565b634e487b7160e01b600052601260045260246000fd5b60008261412f5761412f61410a565b500690565b6000826141435761414361410a565b500490565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b81810381811115610c6b57610c6b613e70565b60008161420157614201613e70565b506000190190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061423c9083018461398e565b9695505050505050565b60006020828403121561425857600080fd5b81516122c581613937565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220686af8cc5eee68810ddf412555cbfae667e4370cf09432729a1b0fc1911532cd64736f6c63430008120033000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000008b40fc00d483b8a6a31539bbb399b14e1d36e454000000000000000000000000000000000000000000000000000000000000000f54616c6573206f662053706172746100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003544f530000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106103ce5760003560e01c8063717ceba2116101fd578063a6f9dae111610118578063d936547e116100ab578063e985e9c51161007a578063e985e9c514610b91578063f0c1e5ee14610bda578063f2fde38b14610bfa578063f41dfb1b14610c1a578063f49ae8be14610c3057600080fd5b8063d936547e14610ab5578063ddca3f4314610b48578063e00e8bf314610b5e578063e73a914c14610b7157600080fd5b8063c84200bf116100e7578063c84200bf14610a49578063c87b56dd14610a69578063c8c1f3f514610a89578063cc2129bf14610a9f57600080fd5b8063a6f9dae11461095c578063b5c455ec1461097c578063b88d4fde14610a09578063c5461d5014610a2957600080fd5b80638f770ad01161019057806395d89b411161015f57806395d89b41146108f157806398f4c9ed146109065780639f8175bd1461091c578063a22cb4651461093c57600080fd5b80638f770ad01461085d57806390107afe1461089157806392201a4a146108b1578063931688cb146108d157600080fd5b80638456cb59116101cc5780638456cb59146107f45780638ab234b6146108095780638c82ce3f146108295780638da5cb5b1461083f57600080fd5b8063717ceba21461077e5780637202a13a1461079457806377d140dc146107b45780637ecbaeb1146107d457600080fd5b80633d40bfb4116102ed5780635c983aec116102805780637017b8ed1161024f5780637017b8ed1461071357806370a082311461072957806370d5ae0514610749578063715018a61461076957600080fd5b80635c983aec146106a85780635f637025146106c85780636352211e146106de5780636c0360eb146106fe57600080fd5b80634f6ccce7116102bc5780634f6ccce714610634578063548db1741461065457806355aeba64146106745780635c975abb1461068957600080fd5b80633d40bfb4146105c95780633f4ba83a146105df5780633fe14e03146105f457806342842e0e1461061457600080fd5b806320b2af5211610365578063285aaa2011610334578063285aaa201461056a5780632e1a7d4d146105805780632f745c59146105935780633bff053f146105b357600080fd5b806320b2af52146104e557806323b872dd146104fa57806323db4c911461051a57806326c91cad1461054a57600080fd5b806311452462116103a157806311452462146104845780631249c58b146104a4578063146a775c146104ac57806318160ddd146104c657600080fd5b806301ffc9a7146103d357806306fdde0314610408578063081812fc1461042a578063095ea7b314610462575b600080fd5b3480156103df57600080fd5b506103f36103ee36600461394d565b610c46565b60405190151581526020015b60405180910390f35b34801561041457600080fd5b5061041d610c71565b6040516103ff91906139ba565b34801561043657600080fd5b5061044a6104453660046139cd565b610d03565b6040516001600160a01b0390911681526020016103ff565b34801561046e57600080fd5b5061048261047d3660046139fb565b610d2a565b005b34801561049057600080fd5b5061048261049f366004613a73565b610e44565b610482610fe3565b3480156104b857600080fd5b506020546103f39060ff1681565b3480156104d257600080fd5b506008545b6040519081526020016103ff565b3480156104f157600080fd5b5061041d6111cd565b34801561050657600080fd5b50610482610515366004613b15565b61125b565b34801561052657600080fd5b506103f36105353660046139cd565b60236020526000908152604090205460ff1681565b34801561055657600080fd5b5061044a6105653660046139cd565b61128c565b34801561057657600080fd5b506104d760155481565b61048261058e3660046139cd565b6112b6565b34801561059f57600080fd5b506104d76105ae3660046139fb565b611344565b3480156105bf57600080fd5b506104d760195481565b3480156105d557600080fd5b506104d7601a5481565b3480156105eb57600080fd5b506104826113da565b34801561060057600080fd5b5061048261060f366004613be2565b61147f565b34801561062057600080fd5b5061048261062f366004613b15565b6114b9565b34801561064057600080fd5b506104d761064f3660046139cd565b6114d4565b34801561066057600080fd5b5061048261066f366004613c2b565b611567565b34801561068057600080fd5b506104826117f1565b34801561069557600080fd5b506020546103f390610100900460ff1681565b3480156106b457600080fd5b506104826106c3366004613c2b565b611840565b3480156106d457600080fd5b506104d760165481565b3480156106ea57600080fd5b5061044a6106f93660046139cd565b6118c7565b34801561070a57600080fd5b5061041d611927565b34801561071f57600080fd5b506104d760125481565b34801561073557600080fd5b506104d7610744366004613c6d565b611934565b34801561075557600080fd5b50600e5461044a906001600160a01b031681565b34801561077557600080fd5b506104826119ba565b34801561078a57600080fd5b506104d760115481565b3480156107a057600080fd5b506104826107af366004613c8a565b6119cc565b3480156107c057600080fd5b50600c5461044a906001600160a01b031681565b3480156107e057600080fd5b506104826107ef366004613c8a565b611ad0565b34801561080057600080fd5b50610482611bcd565b34801561081557600080fd5b50610482610824366004613c6d565b611c7b565b34801561083557600080fd5b506104d760175481565b34801561084b57600080fd5b50600a546001600160a01b031661044a565b34801561086957600080fd5b506104d77f0000000000000000000000000000000000000000000000000000000000000d0581565b34801561089d57600080fd5b506104826108ac366004613cf6565b611d08565b3480156108bd57600080fd5b506104826108cc366004613c2b565b611d60565b3480156108dd57600080fd5b506104826108ec366004613be2565b611de7565b3480156108fd57600080fd5b5061041d611e1d565b34801561091257600080fd5b506104d7601e5481565b34801561092857600080fd5b50610482610937366004613c8a565b611e2c565b34801561094857600080fd5b50610482610957366004613d3d565b611f29565b34801561096857600080fd5b50610482610977366004613c6d565b611f34565b34801561098857600080fd5b506109d4610997366004613c6d565b6024602052600090815260409020805460018201546002830154600384015460048501546005860154600690960154949593949293919290919087565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016103ff565b348015610a1557600080fd5b50610482610a24366004613d6b565b611f67565b348015610a3557600080fd5b50610482610a44366004613c8a565b611f9f565b348015610a5557600080fd5b50610482610a64366004613c8a565b61209c565b348015610a7557600080fd5b5061041d610a843660046139cd565b612199565b348015610a9557600080fd5b506104d7601d5481565b348015610aab57600080fd5b506104d7601c5481565b348015610ac157600080fd5b50610b11610ad0366004613c6d565b602260205260009081526040902080546001820154600283015460038401546004850154600586015460069096015460ff9095169593949293919290919087565b6040805197151588526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016103ff565b348015610b5457600080fd5b506104d760105481565b610482610b6c366004613deb565b61233f565b348015610b7d57600080fd5b50610482610b8c366004613c6d565b612415565b348015610b9d57600080fd5b506103f3610bac366004613cf6565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610be657600080fd5b50610482610bf5366004613c8a565b612461565b348015610c0657600080fd5b50610482610c15366004613c6d565b61255e565b348015610c2657600080fd5b506104d7601b5481565b348015610c3c57600080fd5b506104d760185481565b60006001600160e01b0319821663780e9d6360e01b1480610c6b5750610c6b826125d4565b92915050565b606060008054610c8090613e0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610cac90613e0d565b8015610cf95780601f10610cce57610100808354040283529160200191610cf9565b820191906000526020600020905b815481529060010190602001808311610cdc57829003601f168201915b5050505050905090565b6000610d0e82612624565b506000908152600460205260409020546001600160a01b031690565b6000610d35826118c7565b9050806001600160a01b0316836001600160a01b031603610da75760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b0382161480610dc35750610dc38133610bac565b610e355760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610d9e565b610e3f8383612683565b505050565b600c546001600160a01b03163314610e6e5760405162461bcd60e51b8152600401610d9e90613e47565b610e8089670de0b6b3a7640000613e86565b601055610e9588670de0b6b3a7640000613e86565b60115560128790558585600081610eae57610eae613e9d565b60200291909101356015555085856001818110610ecd57610ecd613e9d565b60200291909101356016555085856002818110610eec57610eec613e9d565b602002919091013560175550610f058462015180613e86565b610f0f9042613eb3565b601355610f1d83603c613e86565b6014558181600081610f3157610f31613e9d565b6020029190910135601b555081816001818110610f5057610f50613e9d565b60200291909101356019555081816002818110610f6f57610f6f613e9d565b6020029190910135601a555081816003818110610f8e57610f8e613e9d565b6020029190910135601d555081816004818110610fad57610fad613e9d565b6020029190910135601c555081816005818110610fcc57610fcc613e9d565b6020029190910135601e5550505050505050505050565b610feb6126f1565b602054610100900460ff16156110355760405162461bcd60e51b815260206004820152600f60248201526e14185d5cd9590810dbdb9d1c9858dd608a1b6044820152606401610d9e565b600061104060085490565b90507f0000000000000000000000000000000000000000000000000000000000000d0581106110a15760405162461bcd60e51b815260206004820152600d60248201526c26b0bc1022bc31b2b2b232b21760991b6044820152606401610d9e565b42601354106110e35760405162461bcd60e51b815260206004820152600e60248201526d4d696e74204e6f74204c6976652160901b6044820152606401610d9e565b6110eb61274a565b156110fd576110f861279b565b6111c0565b4260145460135461110e9190613eb3565b1061115b5760405162461bcd60e51b815260206004820152601e60248201527f5075626c696320506861736520486173204e6f742059657420426567756e00006044820152606401610d9e565b601054341461119f5760405162461bcd60e51b815260206004820152601060248201526f496e73756666696369656e742066656560801b6044820152606401610d9e565b6111aa60115461294f565b6111b86011546015546129ee565b6111c061279b565b506111cb6001600b55565b565b601f80546111da90613e0d565b80601f016020809104026020016040519081016040528092919081815260200182805461120690613e0d565b80156112535780601f1061122857610100808354040283529160200191611253565b820191906000526020600020905b81548152906001019060200180831161123657829003601f168201915b505050505081565b6112653382612b7b565b6112815760405162461bcd60e51b8152600401610d9e90613ec6565b610e3f838383612bfa565b6021818154811061129c57600080fd5b6000918252602090912001546001600160a01b0316905081565b600c546001600160a01b031633146112e05760405162461bcd60e51b8152600401610d9e90613e47565b6112e86126f1565b60006112fc600a546001600160a01b031690565b6040519091506001600160a01b0382169083156108fc029084906000818181858888f19350505050158015611335573d6000803e3d6000fd5b50506113416001600b55565b50565b600061134f83611934565b82106113b15760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610d9e565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600c546001600160a01b031633146114045760405162461bcd60e51b8152600401610d9e90613e47565b602054610100900460ff166114495760405162461bcd60e51b815260206004820152600b60248201526a2737ba103830bab9b2b21760a91b6044820152606401610d9e565b6020805461ff00191690556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3390600090a1565b600c546001600160a01b031633146114a95760405162461bcd60e51b8152600401610d9e90613e47565b601f6114b58282613f61565b5050565b610e3f83838360405180602001604052806000815250611f67565b60006114df60085490565b82106115425760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610d9e565b6008828154811061155557611555613e9d565b90600052602060002001549050919050565b600c546001600160a01b031633146115915760405162461bcd60e51b8152600401610d9e90613e47565b60005b81811015610e3f576000602260008585858181106115b4576115b4613e9d565b90506020020160208101906115c99190613c6d565b6001600160a01b0316815260208101919091526040016000908120805460ff19169215159290921790915560228185858581811061160957611609613e9d565b905060200201602081019061161e9190613c6d565b6001600160a01b03166001600160a01b031681526020019081526020016000206001018190555060006022600085858581811061165d5761165d613e9d565b90506020020160208101906116729190613c6d565b6001600160a01b03166001600160a01b03168152602001908152602001600020600201819055506000602260008585858181106116b1576116b1613e9d565b90506020020160208101906116c69190613c6d565b6001600160a01b03166001600160a01b031681526020019081526020016000206003018190555060006022600085858581811061170557611705613e9d565b905060200201602081019061171a9190613c6d565b6001600160a01b03166001600160a01b031681526020019081526020016000206004018190555060006022600085858581811061175957611759613e9d565b905060200201602081019061176e9190613c6d565b6001600160a01b03166001600160a01b03168152602001908152602001600020600501819055506000602260008585858181106117ad576117ad613e9d565b90506020020160208101906117c29190613c6d565b6001600160a01b03168152602081019190915260400160002060060155806117e981614021565b915050611594565b600c546001600160a01b0316331461181b5760405162461bcd60e51b8152600401610d9e90613e47565b60205460ff16611834576020805460ff19166001179055565b6020805460ff19169055565b600c546001600160a01b0316331461186a5760405162461bcd60e51b8152600401610d9e90613e47565b60005b81811015610e3f5760016023600085858581811061188d5761188d613e9d565b60209081029290920135835250810191909152604001600020805460ff1916911515919091179055806118bf81614021565b91505061186d565b6000818152600260205260408120546001600160a01b031680610c6b5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610d9e565b600f80546111da90613e0d565b60006001600160a01b03821661199e5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610d9e565b506001600160a01b031660009081526003602052604090205490565b6119c2612d6b565b6111cb6000612dc5565b600c546001600160a01b031633146119f65760405162461bcd60e51b8152600401610d9e90613e47565b60005b83811015611ac957600160226000878785818110611a1957611a19613e9d565b9050602002016020810190611a2e9190613c6d565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055828282818110611a6857611a68613e9d565b9050602002013560226000878785818110611a8557611a85613e9d565b9050602002016020810190611a9a9190613c6d565b6001600160a01b0316815260208101919091526040016000206004015580611ac181614021565b9150506119f9565b5050505050565b600c546001600160a01b03163314611afa5760405162461bcd60e51b8152600401610d9e90613e47565b60005b83811015611ac957600160226000878785818110611b1d57611b1d613e9d565b9050602002016020810190611b329190613c6d565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055828282818110611b6c57611b6c613e9d565b9050602002013560226000878785818110611b8957611b89613e9d565b9050602002016020810190611b9e9190613c6d565b6001600160a01b0316815260208101919091526040016000206003015580611bc581614021565b915050611afd565b600c546001600160a01b03163314611bf75760405162461bcd60e51b8152600401610d9e90613e47565b602054610100900460ff1615611c415760405162461bcd60e51b815260206004820152600f60248201526e20b63932b0b23c903830bab9b2b21760891b6044820152606401610d9e565b6020805461ff0019166101001790556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62590600090a1565b600c546001600160a01b03163314611ca55760405162461bcd60e51b8152600401610d9e90613e47565b60408051602081019091526001600160a01b0391821681526021805460018101825560009190915290517f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57090910180546001600160a01b03191691909216179055565b600c546001600160a01b03163314611d325760405162461bcd60e51b8152600401610d9e90613e47565b600e80546001600160a01b039384166001600160a01b031991821617909155600d8054929093169116179055565b600c546001600160a01b03163314611d8a5760405162461bcd60e51b8152600401610d9e90613e47565b60005b81811015610e3f57600060236000858585818110611dad57611dad613e9d565b60209081029290920135835250810191909152604001600020805460ff191691151591909117905580611ddf81614021565b915050611d8d565b600c546001600160a01b03163314611e115760405162461bcd60e51b8152600401610d9e90613e47565b600f6114b58282613f61565b606060018054610c8090613e0d565b600c546001600160a01b03163314611e565760405162461bcd60e51b8152600401610d9e90613e47565b60005b83811015611ac957600160226000878785818110611e7957611e79613e9d565b9050602002016020810190611e8e9190613c6d565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055828282818110611ec857611ec8613e9d565b9050602002013560226000878785818110611ee557611ee5613e9d565b9050602002016020810190611efa9190613c6d565b6001600160a01b0316815260208101919091526040016000206001015580611f2181614021565b915050611e59565b6114b5338383612e17565b600c546001600160a01b03163314611f5e5760405162461bcd60e51b8152600401610d9e90613e47565b6113418161255e565b611f713383612b7b565b611f8d5760405162461bcd60e51b8152600401610d9e90613ec6565b611f9984848484612ee5565b50505050565b600c546001600160a01b03163314611fc95760405162461bcd60e51b8152600401610d9e90613e47565b60005b83811015611ac957600160226000878785818110611fec57611fec613e9d565b90506020020160208101906120019190613c6d565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905582828281811061203b5761203b613e9d565b905060200201356022600087878581811061205857612058613e9d565b905060200201602081019061206d9190613c6d565b6001600160a01b031681526020810191909152604001600020600601558061209481614021565b915050611fcc565b600c546001600160a01b031633146120c65760405162461bcd60e51b8152600401610d9e90613e47565b60005b83811015611ac9576001602260008787858181106120e9576120e9613e9d565b90506020020160208101906120fe9190613c6d565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905582828281811061213857612138613e9d565b905060200201356022600087878581811061215557612155613e9d565b905060200201602081019061216a9190613c6d565b6001600160a01b031681526020810191909152604001600020600201558061219181614021565b9150506120c9565b60606121a460085490565b8211156121df5760405162461bcd60e51b8152602060048201526009602482015268139bdd08119bdd5b9960ba1b6044820152606401610d9e565b6000600f80546121ee90613e0d565b80601f016020809104026020016040519081016040528092919081815260200182805461221a90613e0d565b80156122675780601f1061223c57610100808354040283529160200191612267565b820191906000526020600020905b81548152906001019060200180831161224a57829003601f168201915b505050600086815260236020526040902054929350505060ff16156122cc5760008151116122a457604051806020016040528060008152506122c5565b806040516020016122b5919061403a565b6040516020818303038152906040525b9392505050565b60205460ff16156123105760008151116122f557604051806020016040528060008152506122c5565b806122ff84612f18565b6040516020016122b5929190614077565b600081511161232e57604051806020016040528060008152506122c5565b806040516020016122b591906140b6565b600c546001600160a01b031633146123695760405162461bcd60e51b8152600401610d9e90613e47565b6123716126f1565b60006021838154811061238657612386613e9d565b6000918252602090912001805460405163a9059cbb60e01b8152336004820152602481018590529192506001600160a01b031690819063a9059cbb906044016020604051808303816000875af11580156123e4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240891906140ed565b5050506114b56001600b55565b600c546001600160a01b0316331461243f5760405162461bcd60e51b8152600401610d9e90613e47565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b600c546001600160a01b0316331461248b5760405162461bcd60e51b8152600401610d9e90613e47565b60005b83811015611ac9576001602260008787858181106124ae576124ae613e9d565b90506020020160208101906124c39190613c6d565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558282828181106124fd576124fd613e9d565b905060200201356022600087878581811061251a5761251a613e9d565b905060200201602081019061252f9190613c6d565b6001600160a01b031681526020810191909152604001600020600501558061255681614021565b91505061248e565b612566612d6b565b6001600160a01b0381166125cb5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d9e565b61134181612dc5565b60006001600160e01b031982166380ac58cd60e01b148061260557506001600160e01b03198216635b5e139f60e01b145b80610c6b57506301ffc9a760e01b6001600160e01b0319831614610c6b565b6000818152600260205260409020546001600160a01b03166113415760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610d9e565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906126b8826118c7565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6002600b54036127435760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610d9e565b6002600b55565b3360009081526022602052604081205460ff166127675750600090565b6000612771612fab565b90506000811180156127865750612786613062565b1561279357600191505090565b600091505090565b60006127a660085490565b90507f0000000000000000000000000000000000000000000000000000000000000d0581106128065760405162461bcd60e51b815260206004820152600c60248201526b13585e08115e18d95959195960a21b6044820152606401610d9e565b6000612813826001613eb3565b905060008211801561282d575061282b600a83614120565b155b156128d057600c54612848906001600160a01b031682613308565b60408051602080820183526000808352848152602382528381209251835460ff191690151517909255600c546001600160a01b031682526024905290812080549161289283614021565b909155505060405181907facb55af3158df90a7759d626bd07a674a61a33c821bfd3816649a8757df0233290600090a2806128cc81614021565b9150505b6128da3382613308565b3360009081526024602052604081208054916128f583614021565b90915550506040805160208082018352600080835284815260239091528281209151825460ff191690151517909155905182917facb55af3158df90a7759d626bd07a674a61a33c821bfd3816649a8757df0233291a25050565b600060216012548154811061296657612966613e9d565b600091825260209091200180546040516323b872dd60e01b8152336004820152306024820152604481018590529192506001600160a01b03169081906323b872dd906064016020604051808303816000875af11580156129ca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9991906140ed565b600060646129fc8385613e86565b612a069190614134565b90506000606460165483612a1a9190613e86565b612a249190614134565b90506000606460175484612a389190613e86565b612a429190614134565b90506000602160125481548110612a5b57612a5b613e9d565b60009182526020909120018054600e5460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018790529293501690819063a9059cbb906044016020604051808303816000875af1158015612abe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ae291906140ed565b50600d5460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018590529082169063a9059cbb906044016020604051808303816000875af1158015612b36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b5a91906140ed565b508360186000828254612b6d9190613eb3565b909155505050505050505050565b600080612b87836118c7565b9050806001600160a01b0316846001600160a01b03161480612bce57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80612bf25750836001600160a01b0316612be784610d03565b6001600160a01b0316145b949350505050565b826001600160a01b0316612c0d826118c7565b6001600160a01b031614612c335760405162461bcd60e51b8152600401610d9e90614148565b6001600160a01b038216612c955760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610d9e565b612ca283838360016134a1565b826001600160a01b0316612cb5826118c7565b6001600160a01b031614612cdb5760405162461bcd60e51b8152600401610d9e90614148565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a546001600160a01b031633146111cb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d9e565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b031603612e785760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610d9e565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612ef0848484612bfa565b612efc848484846135ce565b611f995760405162461bcd60e51b8152600401610d9e9061418d565b60606000612f25836136cf565b600101905060008167ffffffffffffffff811115612f4557612f45613b56565b6040519080825280601f01601f191660200182016040528015612f6f576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084612f7957509392505050565b3360009081526024602090815260408083205460229092528220600681015460058201546004830154600384015460028501546001909501548795612fef91613eb3565b612ff99190613eb3565b6130039190613eb3565b61300d9190613eb3565b6130179190613eb3565b9050600061302583836141df565b9050818311156122c55760405162461bcd60e51b81526020600482015260086024820152676661696c7361666560c01b6044820152606401610d9e565b33600090815260246020526040812054600111156130d45733600090815260226020908152604080832060018082015460249094529190932090810191909155600280830154908201556003808301549082015560048083015490820155600580830154908201556006918201549101555b33600090815260246020526040902060010154158015906130f757506000601b54115b1561313b5733600090815260246020526040812060010180549161311a836141f2565b9091555050601b805490600061312f836141f2565b91905055506001905090565b336000908152602460205260409020600201541580159061315e57506000601a54115b1561319657336000908152602460205260408120600201805491613181836141f2565b9091555050601a805490600061312f836141f2565b33600090815260246020526040902060030154158015906131b957506000601954115b156131f1573360009081526024602052604081206003018054916131dc836141f2565b90915550506019805490600061312f836141f2565b336000908152602460205260409020600401541580159061321457506000601d54115b1561324c57336000908152602460205260408120600401805491613237836141f2565b9091555050601d805490600061312f836141f2565b336000908152602460205260409020600501541580159061326f57506000601c54115b156132a757336000908152602460205260408120600501805491613292836141f2565b9091555050601c805490600061312f836141f2565b33600090815260246020526040902060060154158015906132ca57506000601e54115b15613302573360009081526024602052604081206006018054916132ed836141f2565b9091555050601e805490600061312f836141f2565b50600090565b6001600160a01b03821661335e5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610d9e565b6000818152600260205260409020546001600160a01b0316156133c35760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610d9e565b6133d16000838360016134a1565b6000818152600260205260409020546001600160a01b0316156134365760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610d9e565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60018111156135105760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610d9e565b816001600160a01b03851661356c5761356781600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b61358f565b836001600160a01b0316856001600160a01b03161461358f5761358f85826137a7565b6001600160a01b0384166135ab576135a681613844565b611ac9565b846001600160a01b0316846001600160a01b031614611ac957611ac984826138f3565b60006001600160a01b0384163b156136c457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613612903390899088908890600401614209565b6020604051808303816000875af192505050801561364d575060408051601f3d908101601f1916820190925261364a91810190614246565b60015b6136aa573d80801561367b576040519150601f19603f3d011682016040523d82523d6000602084013e613680565b606091505b5080516000036136a25760405162461bcd60e51b8152600401610d9e9061418d565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612bf2565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b831061370e5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061373a576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061375857662386f26fc10000830492506010015b6305f5e1008310613770576305f5e100830492506008015b612710831061378457612710830492506004015b60648310613796576064830492506002015b600a8310610c6b5760010192915050565b600060016137b484611934565b6137be91906141df565b600083815260076020526040902054909150808214613811576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090613856906001906141df565b6000838152600960205260408120546008805493945090928490811061387e5761387e613e9d565b90600052602060002001549050806008838154811061389f5761389f613e9d565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806138d7576138d7614263565b6001900381819060005260206000200160009055905550505050565b60006138fe83611934565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160e01b03198116811461134157600080fd5b60006020828403121561395f57600080fd5b81356122c581613937565b60005b8381101561398557818101518382015260200161396d565b50506000910152565b600081518084526139a681602086016020860161396a565b601f01601f19169290920160200192915050565b6020815260006122c5602083018461398e565b6000602082840312156139df57600080fd5b5035919050565b6001600160a01b038116811461134157600080fd5b60008060408385031215613a0e57600080fd5b8235613a19816139e6565b946020939093013593505050565b60008083601f840112613a3957600080fd5b50813567ffffffffffffffff811115613a5157600080fd5b6020830191508360208260051b8501011115613a6c57600080fd5b9250929050565b600080600080600080600080600060e08a8c031215613a9157600080fd5b8935985060208a0135975060408a0135965060608a013567ffffffffffffffff80821115613abe57600080fd5b613aca8d838e01613a27565b909850965060808c0135955060a08c0135945060c08c0135915080821115613af157600080fd5b50613afe8c828d01613a27565b915080935050809150509295985092959850929598565b600080600060608486031215613b2a57600080fd5b8335613b35816139e6565b92506020840135613b45816139e6565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115613b8757613b87613b56565b604051601f8501601f19908116603f01168101908282118183101715613baf57613baf613b56565b81604052809350858152868686011115613bc857600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215613bf457600080fd5b813567ffffffffffffffff811115613c0b57600080fd5b8201601f81018413613c1c57600080fd5b612bf284823560208401613b6c565b60008060208385031215613c3e57600080fd5b823567ffffffffffffffff811115613c5557600080fd5b613c6185828601613a27565b90969095509350505050565b600060208284031215613c7f57600080fd5b81356122c5816139e6565b60008060008060408587031215613ca057600080fd5b843567ffffffffffffffff80821115613cb857600080fd5b613cc488838901613a27565b90965094506020870135915080821115613cdd57600080fd5b50613cea87828801613a27565b95989497509550505050565b60008060408385031215613d0957600080fd5b8235613d14816139e6565b91506020830135613d24816139e6565b809150509250929050565b801515811461134157600080fd5b60008060408385031215613d5057600080fd5b8235613d5b816139e6565b91506020830135613d2481613d2f565b60008060008060808587031215613d8157600080fd5b8435613d8c816139e6565b93506020850135613d9c816139e6565b925060408501359150606085013567ffffffffffffffff811115613dbf57600080fd5b8501601f81018713613dd057600080fd5b613ddf87823560208401613b6c565b91505092959194509250565b60008060408385031215613dfe57600080fd5b50508035926020909101359150565b600181811c90821680613e2157607f821691505b602082108103613e4157634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600f908201526e2737ba1030baba3437b934bd32b21760891b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610c6b57610c6b613e70565b634e487b7160e01b600052603260045260246000fd5b80820180821115610c6b57610c6b613e70565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b601f821115610e3f57600081815260208120601f850160051c81016020861015613f3a5750805b601f850160051c820191505b81811015613f5957828155600101613f46565b505050505050565b815167ffffffffffffffff811115613f7b57613f7b613b56565b613f8f81613f898454613e0d565b84613f13565b602080601f831160018114613fc45760008415613fac5750858301515b600019600386901b1c1916600185901b178555613f59565b600085815260208120601f198616915b82811015613ff357888601518255948401946001909101908401613fd4565b50858210156140115787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006001820161403357614033613e70565b5060010190565b6000825161404c81846020870161396a565b6a189b1858dadb1a5cdd195960aa1b92019182525064173539b7b760d91b600b820152601001919050565b6000835161408981846020880161396a565b83519083019061409d81836020880161396a565b64173539b7b760d91b9101908152600501949350505050565b600082516140c881846020870161396a565b64616c70686160d81b92019182525064173539b7b760d91b6005820152600a01919050565b6000602082840312156140ff57600080fd5b81516122c581613d2f565b634e487b7160e01b600052601260045260246000fd5b60008261412f5761412f61410a565b500690565b6000826141435761414361410a565b500490565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b81810381811115610c6b57610c6b613e70565b60008161420157614201613e70565b506000190190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061423c9083018461398e565b9695505050505050565b60006020828403121561425857600080fd5b81516122c581613937565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220686af8cc5eee68810ddf412555cbfae667e4370cf09432729a1b0fc1911532cd64736f6c63430008120033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000008b40fc00d483b8a6a31539bbb399b14e1d36e454000000000000000000000000000000000000000000000000000000000000000f54616c6573206f662053706172746100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003544f530000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): Tales of Sparta
Arg [1] : _symbol (string): TOS
Arg [2] : _spartanDAO (address): 0x8B40FC00D483b8A6A31539BbB399B14e1d36E454
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 0000000000000000000000008b40fc00d483b8a6a31539bbb399b14e1d36e454
Arg [3] : 000000000000000000000000000000000000000000000000000000000000000f
Arg [4] : 54616c6573206f66205370617274610000000000000000000000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [6] : 544f530000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
113688:15715:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107467:224;;;;;;;;;;-1:-1:-1;107467:224:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;107467:224:0;;;;;;;;91516:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;93028:171::-;;;;;;;;;;-1:-1:-1;93028:171:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1697:32:1;;;1679:51;;1667:2;1652:18;93028:171:0;1533:203:1;92546:416:0;;;;;;;;;;-1:-1:-1;92546:416:0;;;;;:::i;:::-;;:::i;:::-;;123231:748;;;;;;;;;;-1:-1:-1;123231:748:0;;;;;:::i;:::-;;:::i;121689:781::-;;;:::i;114832:31::-;;;;;;;;;;-1:-1:-1;114832:31:0;;;;;;;;108107:113;;;;;;;;;;-1:-1:-1;108195:10:0;:17;108107:113;;;3837:25:1;;;3825:2;3810:18;108107:113:0;3691:177:1;114792:33:0;;;;;;;;;;;;;:::i;93728:301::-;;;;;;;;;;-1:-1:-1;93728:301:0;;;;;:::i;:::-;;:::i;115777:49::-;;;;;;;;;;-1:-1:-1;115777:49:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;115668:32;;;;;;;;;;-1:-1:-1;115668:32:0;;;;;:::i;:::-;;:::i;114428:25::-;;;;;;;;;;;;;;;;124154:175;;;;;;:::i;:::-;;:::i;107775:256::-;;;;;;;;;;-1:-1:-1;107775:256:0;;;;;:::i;:::-;;:::i;114561:30::-;;;;;;;;;;;;;;;;114598:34;;;;;;;;;;;;;;;;125946:140;;;;;;;;;;;;;:::i;129298:102::-;;;;;;;;;;-1:-1:-1;129298:102:0;;;;;:::i;:::-;;:::i;94100:151::-;;;;;;;;;;-1:-1:-1;94100:151:0;;;;;:::i;:::-;;:::i;108297:233::-;;;;;;;;;;-1:-1:-1;108297:233:0;;;;;:::i;:::-;;:::i;128220:563::-;;;;;;;;;;-1:-1:-1;128220:563:0;;;;;:::i;:::-;;:::i;124855:171::-;;;;;;;;;;;;;:::i;114871:26::-;;;;;;;;;;-1:-1:-1;114871:26:0;;;;;;;;;;;128012:200;;;;;;;;;;-1:-1:-1;128012:200:0;;;;;:::i;:::-;;:::i;114460:26::-;;;;;;;;;;;;;;;;91226:223;;;;;;;;;;-1:-1:-1;91226:223:0;;;;;:::i;:::-;;:::i;114140:21::-;;;;;;;;;;;;;:::i;114243:24::-;;;;;;;;;;;;;;;;90957:207;;;;;;;;;;-1:-1:-1;90957:207:0;;;;;:::i;:::-;;:::i;114107:26::-;;;;;;;;;;-1:-1:-1;114107:26:0;;;;-1:-1:-1;;;;;114107:26:0;;;61829:103;;;;;;;;;;;;;:::i;114205:31::-;;;;;;;;;;;;;;;;127063:307;;;;;;;;;;-1:-1:-1;127063:307:0;;;;;:::i;:::-;;:::i;114033:25::-;;;;;;;;;;-1:-1:-1;114033:25:0;;;;-1:-1:-1;;;;;114033:25:0;;;126749:306;;;;;;;;;;-1:-1:-1;126749:306:0;;;;;:::i;:::-;;:::i;125776:140::-;;;;;;;;;;;;;:::i;115897:190::-;;;;;;;;;;-1:-1:-1;115897:190:0;;;;;:::i;:::-;;:::i;114493:25::-;;;;;;;;;;;;;;;;61188:87;;;;;;;;;;-1:-1:-1;61261:6:0;;-1:-1:-1;;;;;61261:6:0;61188:87;;114274:41;;;;;;;;;;;;;;;129118:168;;;;;;;;;;-1:-1:-1;129118:168:0;;;;;:::i;:::-;;:::i;128791:206::-;;;;;;;;;;-1:-1:-1;128791:206:0;;;;;:::i;:::-;;:::i;124737:110::-;;;;;;;;;;-1:-1:-1;124737:110:0;;;;;:::i;:::-;;:::i;91685:104::-;;;;;;;;;;;;;:::i;114749:36::-;;;;;;;;;;;;;;;;126111:308;;;;;;;;;;-1:-1:-1;126111:308:0;;;;;:::i;:::-;;:::i;93271:155::-;;;;;;;;;;-1:-1:-1;93271:155:0;;;;;:::i;:::-;;:::i;123991:::-;;;;;;;;;;-1:-1:-1;123991:155:0;;;;;:::i;:::-;;:::i;115833:51::-;;;;;;;;;;-1:-1:-1;115833:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9179:25:1;;;9235:2;9220:18;;9213:34;;;;9263:18;;;9256:34;;;;9321:2;9306:18;;9299:34;;;;9364:3;9349:19;;9342:35;9408:3;9393:19;;9386:35;9452:3;9437:19;;9430:35;9166:3;9151:19;115833:51:0;8864:607:1;94322:279:0;;;;;;;;;;-1:-1:-1;94322:279:0;;;;;:::i;:::-;;:::i;127693:311::-;;;;;;;;;;-1:-1:-1;127693:311:0;;;;;:::i;:::-;;:::i;126427:314::-;;;;;;;;;;-1:-1:-1;126427:314:0;;;;;:::i;:::-;;:::i;125034:714::-;;;;;;;;;;-1:-1:-1;125034:714:0;;;;;:::i;:::-;;:::i;114713:29::-;;;;;;;;;;;;;;;;114677;;;;;;;;;;;;;;;;115721:49;;;;;;;;;;-1:-1:-1;115721:49:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10610:14:1;;10603:22;10585:41;;10657:2;10642:18;;10635:34;;;;10685:18;;;10678:34;;;;10743:2;10728:18;;10721:34;;;;10786:3;10771:19;;10764:35;10830:3;10815:19;;10808:35;10874:3;10859:19;;10852:35;10572:3;10557:19;115721:49:0;10276:617:1;114168:30:0;;;;;;;;;;;;;;;;124337:280;;;;;;:::i;:::-;;:::i;129005:105::-;;;;;;;;;;-1:-1:-1;129005:105:0;;;;;:::i;:::-;;:::i;93497:164::-;;;;;;;;;;-1:-1:-1;93497:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;93618:25:0;;;93594:4;93618:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;93497:164;127378:307;;;;;;;;;;-1:-1:-1;127378:307:0;;;;;:::i;:::-;;:::i;62087:201::-;;;;;;;;;;-1:-1:-1;62087:201:0;;;;;:::i;:::-;;:::i;114639:31::-;;;;;;;;;;;;;;;;114525:29;;;;;;;;;;;;;;;;107467:224;107569:4;-1:-1:-1;;;;;;107593:50:0;;-1:-1:-1;;;107593:50:0;;:90;;;107647:36;107671:11;107647:23;:36::i;:::-;107586:97;107467:224;-1:-1:-1;;107467:224:0:o;91516:100::-;91570:13;91603:5;91596:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91516:100;:::o;93028:171::-;93104:7;93124:23;93139:7;93124:14;:23::i;:::-;-1:-1:-1;93167:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;93167:24:0;;93028:171::o;92546:416::-;92627:13;92643:23;92658:7;92643:14;:23::i;:::-;92627:39;;92691:5;-1:-1:-1;;;;;92685:11:0;:2;-1:-1:-1;;;;;92685:11:0;;92677:57;;;;-1:-1:-1;;;92677:57:0;;11738:2:1;92677:57:0;;;11720:21:1;11777:2;11757:18;;;11750:30;11816:34;11796:18;;;11789:62;-1:-1:-1;;;11867:18:1;;;11860:31;11908:19;;92677:57:0;;;;;;;;;59819:10;-1:-1:-1;;;;;92769:21:0;;;;:62;;-1:-1:-1;92794:37:0;92811:5;59819:10;93497:164;:::i;92794:37::-;92747:173;;;;-1:-1:-1;;;92747:173:0;;12140:2:1;92747:173:0;;;12122:21:1;12179:2;12159:18;;;12152:30;12218:34;12198:18;;;12191:62;12289:31;12269:18;;;12262:59;12338:19;;92747:173:0;11938:425:1;92747:173:0;92933:21;92942:2;92946:7;92933:8;:21::i;:::-;92616:346;92546:416;;:::o;123231:748::-;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;123457:19:::1;:9:::0;123469:7:::1;123457:19;:::i;:::-;123451:3;:25:::0;123496:22:::1;:12:::0;123511:7:::1;123496:22;:::i;:::-;123487:6;:31:::0;123529:5:::1;:14:::0;;;123561:6;;-1:-1:-1;123561:9:0;::::1;;;;:::i;:::-;;;::::0;;;::::1;;123554:4;:16:::0;-1:-1:-1;123591:6:0;;123598:1:::1;123591:9:::0;;::::1;;;;;:::i;:::-;;;::::0;;;::::1;;123581:7;:19:::0;-1:-1:-1;123620:6:0;;123627:1:::1;123620:9:::0;;::::1;;;;;:::i;:::-;;;::::0;;;::::1;;123611:6;:18:::0;-1:-1:-1;123671:19:0::1;:10:::0;123684:6:::1;123671:19;:::i;:::-;123652:39;::::0;:15:::1;:39;:::i;:::-;123640:9;:51:::0;123715:23:::1;:11:::0;123729:9:::1;123715:23;:::i;:::-;123702:10;:36:::0;123762:11;;123774:1:::1;123762:14:::0;::::1;;;;:::i;:::-;;;::::0;;;::::1;;123749:10;:27:::0;-1:-1:-1;123799:11:0;;123811:1:::1;123799:14:::0;;::::1;;;;;:::i;:::-;;;::::0;;;::::1;;123787:9;:26:::0;-1:-1:-1;123840:11:0;;123852:1:::1;123840:14:::0;;::::1;;;;;:::i;:::-;;;::::0;;;::::1;;123824:13;:30:::0;-1:-1:-1;123877:11:0;;123889:1:::1;123877:14:::0;;::::1;;;;;:::i;:::-;;;::::0;;;::::1;;123865:9;:26:::0;-1:-1:-1;123913:11:0;;123925:1:::1;123913:14:::0;;::::1;;;;;:::i;:::-;;;::::0;;;::::1;;123902:8;:25:::0;-1:-1:-1;123957:11:0;;123969:1:::1;123957:14:::0;;::::1;;;;;:::i;:::-;;;::::0;;;::::1;;123938:16;:33:::0;-1:-1:-1;;;;;;;;;;123231:748:0:o;121689:781::-;2387:21;:19;:21::i;:::-;121753:6:::1;::::0;::::1;::::0;::::1;;;121752:7;121744:35;;;::::0;-1:-1:-1;;;121744:35:0;;13481:2:1;121744:35:0::1;::::0;::::1;13463:21:1::0;13520:2;13500:18;;;13493:30;-1:-1:-1;;;13539:18:1;;;13532:45;13594:18;;121744:35:0::1;13279:339:1::0;121744:35:0::1;121790:14;121807:13;108195:10:::0;:17;;108107:113;121807:13:::1;121790:30;;121849:9;121840:6;:18;121831:45;;;::::0;-1:-1:-1;;;121831:45:0;;13825:2:1;121831:45:0::1;::::0;::::1;13807:21:1::0;13864:2;13844:18;;;13837:30;-1:-1:-1;;;13883:18:1;;;13876:43;13936:18;;121831:45:0::1;13623:337:1::0;121831:45:0::1;121908:15;121896:9;;:27;121887:55;;;::::0;-1:-1:-1;;;121887:55:0;;14167:2:1;121887:55:0::1;::::0;::::1;14149:21:1::0;14206:2;14186:18;;;14179:30;-1:-1:-1;;;14225:18:1;;;14218:44;14279:18;;121887:55:0::1;13965:338:1::0;121887:55:0::1;121959:16;:14;:16::i;:::-;121955:508;;;122020:16;:14;:16::i;:::-;121955:508;;;122105:15;122091:10;;122079:9;;:22;;;;:::i;:::-;122078:42;122070:85;;;::::0;-1:-1:-1;;;122070:85:0;;14510:2:1;122070:85:0::1;::::0;::::1;14492:21:1::0;14549:2;14529:18;;;14522:30;14588:32;14568:18;;;14561:60;14638:18;;122070:85:0::1;14308:354:1::0;122070:85:0::1;122189:3;;122176:9;:16;122168:45;;;::::0;-1:-1:-1;;;122168:45:0;;14869:2:1;122168:45:0::1;::::0;::::1;14851:21:1::0;14908:2;14888:18;;;14881:30;-1:-1:-1;;;14927:18:1;;;14920:46;14983:18;;122168:45:0::1;14667:340:1::0;122168:45:0::1;122289:22;122304:6;;122289:14;:22::i;:::-;122378:18;122383:6;;122391:4;;122378;:18::i;:::-;122440:11;:9;:11::i;:::-;121733:737;2431:20:::0;1825:1;2951:7;:22;2768:213;2431:20;121689:781::o;114792:33::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;93728:301::-;93889:41;59819:10;93922:7;93889:18;:41::i;:::-;93881:99;;;;-1:-1:-1;;;93881:99:0;;;;;;;:::i;:::-;93993:28;94003:4;94009:2;94013:7;93993:9;:28::i;115668:32::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;115668:32:0;;-1:-1:-1;115668:32:0;:::o;124154:175::-;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;2387:21:::1;:19;:21::i;:::-;124245:22:::2;124278:7;61261:6:::0;;-1:-1:-1;;;;;61261:6:0;;61188:87;124278:7:::2;124297:24;::::0;124245:41;;-1:-1:-1;;;;;;124297:15:0;::::2;::::0;:24;::::2;;;::::0;124313:7;;124297:24:::2;::::0;;;124313:7;124297:15;:24;::::2;;;;;;;;;;;;;::::0;::::2;;;;;;124234:95;2431:20:::1;1825:1:::0;2951:7;:22;2768:213;2431:20:::1;124154:175:::0;:::o;107775:256::-;107872:7;107908:23;107925:5;107908:16;:23::i;:::-;107900:5;:31;107892:87;;;;-1:-1:-1;;;107892:87:0;;15628:2:1;107892:87:0;;;15610:21:1;15667:2;15647:18;;;15640:30;15706:34;15686:18;;;15679:62;-1:-1:-1;;;15757:18:1;;;15750:41;15808:19;;107892:87:0;15426:407:1;107892:87:0;-1:-1:-1;;;;;;107997:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;107775:256::o;125946:140::-;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;126006:6:::1;::::0;::::1;::::0;::::1;;;125998:30;;;::::0;-1:-1:-1;;;125998:30:0;;16040:2:1;125998:30:0::1;::::0;::::1;16022:21:1::0;16079:2;16059:18;;;16052:30;-1:-1:-1;;;16098:18:1;;;16091:41;16149:18;;125998:30:0::1;15838:335:1::0;125998:30:0::1;126039:6;:14:::0;;-1:-1:-1;;126039:14:0::1;::::0;;126069:9:::1;::::0;::::1;::::0;126048:5:::1;::::0;126069:9:::1;125946:140::o:0;129298:102::-;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;129376:6:::1;:16;129385:7:::0;129376:6;:16:::1;:::i;:::-;;129298:102:::0;:::o;94100:151::-;94204:39;94221:4;94227:2;94231:7;94204:39;;;;;;;;;;;;:16;:39::i;108297:233::-;108372:7;108408:30;108195:10;:17;;108107:113;108408:30;108400:5;:38;108392:95;;;;-1:-1:-1;;;108392:95:0;;18584:2:1;108392:95:0;;;18566:21:1;18623:2;18603:18;;;18596:30;18662:34;18642:18;;;18635:62;-1:-1:-1;;;18713:18:1;;;18706:42;18765:19;;108392:95:0;18382:408:1;108392:95:0;108505:10;108516:5;108505:17;;;;;;;;:::i;:::-;;;;;;;;;108498:24;;108297:233;;;:::o;128220:563::-;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;128318:9:::1;128313:463;128333:19:::0;;::::1;128313:463;;;128411:5;128374:11;:24;128386:8;;128395:1;128386:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;128374:24:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;128374:24:0;;;:42;;-1:-1:-1;;128374:42:0::1;::::0;::::1;;::::0;;;::::1;::::0;;;128431:11:::1;-1:-1:-1::0;128443:8:0;;128452:1;128443:11;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;128431:24:0::1;-1:-1:-1::0;;;;;128431:24:0::1;;;;;;;;;;;;:38;;:42;;;;128532:1;128488:11;:24;128500:8;;128509:1;128500:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;128488:24:0::1;-1:-1:-1::0;;;;;128488:24:0::1;;;;;;;;;;;;:41;;:45;;;;128588:1;128548:11;:24;128560:8;;128569:1;128560:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;128548:24:0::1;-1:-1:-1::0;;;;;128548:24:0::1;;;;;;;;;;;;:37;;:41;;;;128645:1;128604:11;:24;128616:8;;128625:1;128616:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;128604:24:0::1;-1:-1:-1::0;;;;;128604:24:0::1;;;;;;;;;;;;:38;;:42;;;;128703:1;128661:11;:24;128673:8;;128682:1;128673:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;128661:24:0::1;-1:-1:-1::0;;;;;128661:24:0::1;;;;;;;;;;;;:39;;:43;;;;128763:1;128719:11;:24;128731:8;;128740:1;128731:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;128719:24:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;128719:24:0;:41:::1;;:45:::0;128354:3;::::1;::::0;::::1;:::i;:::-;;;;128313:463;;124855:171:::0;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;124921:11:::1;::::0;::::1;;124916:103;;124945:11;:18:::0;;-1:-1:-1;;124945:18:0::1;124959:4;124945:18;::::0;;121689:781::o;124916:103::-:1;124990:11;:19:::0;;-1:-1:-1;;124990:19:0::1;::::0;;124855:171::o;128012:200::-;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;128102:9:::1;128097:108;128117:16:::0;;::::1;128097:108;;;128189:4;128155:11;:21;128167:5;;128173:1;128167:8;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;::::1;;128155:21:::0;;-1:-1:-1;128155:21:0;::::1;::::0;;;;;;-1:-1:-1;128155:21:0;:38;;-1:-1:-1;;128155:38:0::1;::::0;::::1;;::::0;;;::::1;::::0;;128135:3;::::1;::::0;::::1;:::i;:::-;;;;128097:108;;91226:223:::0;91298:7;95959:16;;;:7;:16;;;;;;-1:-1:-1;;;;;95959:16:0;;91362:56;;;;-1:-1:-1;;;91362:56:0;;19137:2:1;91362:56:0;;;19119:21:1;19176:2;19156:18;;;19149:30;-1:-1:-1;;;19195:18:1;;;19188:54;19259:18;;91362:56:0;18935:348:1;114140:21:0;;;;;;;:::i;90957:207::-;91029:7;-1:-1:-1;;;;;91057:19:0;;91049:73;;;;-1:-1:-1;;;91049:73:0;;19490:2:1;91049:73:0;;;19472:21:1;19529:2;19509:18;;;19502:30;19568:34;19548:18;;;19541:62;-1:-1:-1;;;19619:18:1;;;19612:39;19668:19;;91049:73:0;19288:405:1;91049:73:0;-1:-1:-1;;;;;;91140:16:0;;;;;:9;:16;;;;;;;90957:207::o;61829:103::-;61074:13;:11;:13::i;:::-;61894:30:::1;61921:1;61894:18;:30::i;127063:307::-:0;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;127188:9:::1;127183:180;127203:19:::0;;::::1;127183:180;;;127281:4;127244:11;:24;127256:8;;127265:1;127256:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;127244:24:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;127244:24:0;:41;;-1:-1:-1;;127244:41:0::1;::::0;::::1;;::::0;;;::::1;::::0;;127341:7;;127349:1;127341:10;;::::1;;;;;:::i;:::-;;;;;;;127300:11;:24;127312:8;;127321:1;127312:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;127300:24:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;127300:24:0;:38:::1;;:51:::0;127224:3;::::1;::::0;::::1;:::i;:::-;;;;127183:180;;;;127063:307:::0;;;;:::o;126749:306::-;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;126874:9:::1;126869:179;126889:19:::0;;::::1;126869:179;;;126967:4;126930:11;:24;126942:8;;126951:1;126942:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;126930:24:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;126930:24:0;:41;;-1:-1:-1;;126930:41:0::1;::::0;::::1;;::::0;;;::::1;::::0;;127026:7;;127034:1;127026:10;;::::1;;;;;:::i;:::-;;;;;;;126986:11;:24;126998:8;;127007:1;126998:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;126986:24:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;126986:24:0;:37:::1;;:50:::0;126910:3;::::1;::::0;::::1;:::i;:::-;;;;126869:179;;125776:140:::0;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;125835:6:::1;::::0;::::1;::::0;::::1;;;125834:7;125826:35;;;::::0;-1:-1:-1;;;125826:35:0;;19900:2:1;125826:35:0::1;::::0;::::1;19882:21:1::0;19939:2;19919:18;;;19912:30;-1:-1:-1;;;19958:18:1;;;19951:45;20013:18;;125826:35:0::1;19698:339:1::0;125826:35:0::1;125872:6;:13:::0;;-1:-1:-1;;125872:13:0::1;;;::::0;;125901:7:::1;::::0;::::1;::::0;125872:13;;125901:7:::1;125776:140::o:0;115897:190::-;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;116004:64:::1;::::0;;::::1;::::0;::::1;::::0;;;-1:-1:-1;;;;;116004:64:0;;::::1;::::0;;115971:13:::1;:108:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;115971:108:0;;;;;;;;;::::1;::::0;;-1:-1:-1;;;;;;115971:108:0::1;::::0;;;::::1;;::::0;;115897:190::o;129118:168::-;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;129214:11:::1;:23:::0;;-1:-1:-1;;;;;129214:23:0;;::::1;-1:-1:-1::0;;;;;;129214:23:0;;::::1;;::::0;;;129248:18:::1;:30:::0;;;;;::::1;::::0;::::1;;::::0;;129118:168::o;128791:206::-;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;128886:9:::1;128881:109;128901:16:::0;;::::1;128881:109;;;128973:5;128939:11;:21;128951:5;;128957:1;128951:8;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;::::1;;128939:21:::0;;-1:-1:-1;128939:21:0;::::1;::::0;;;;;;-1:-1:-1;128939:21:0;:39;;-1:-1:-1;;128939:39:0::1;::::0;::::1;;::::0;;;::::1;::::0;;128919:3;::::1;::::0;::::1;:::i;:::-;;;;128881:109;;124737:110:::0;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;124821:7:::1;:18;124831:8:::0;124821:7;:18:::1;:::i;91685:104::-:0;91741:13;91774:7;91767:14;;;;;:::i;126111:308::-;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;126237:9:::1;126232:180;126252:19:::0;;::::1;126232:180;;;126330:4;126293:11;:24;126305:8;;126314:1;126305:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;126293:24:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;126293:24:0;:41;;-1:-1:-1;;126293:41:0::1;::::0;::::1;;::::0;;;::::1;::::0;;126390:7;;126398:1;126390:10;;::::1;;;;;:::i;:::-;;;;;;;126349:11;:24;126361:8;;126370:1;126361:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;126349:24:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;126349:24:0;:38:::1;;:51:::0;126273:3;::::1;::::0;::::1;:::i;:::-;;;;126232:180;;93271:155:::0;93366:52;59819:10;93399:8;93409;93366:18;:52::i;123991:155::-;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;124111:27:::1;124129:8;124111:17;:27::i;94322:279::-:0;94453:41;59819:10;94486:7;94453:18;:41::i;:::-;94445:99;;;;-1:-1:-1;;;94445:99:0;;;;;;;:::i;:::-;94555:38;94569:4;94575:2;94579:7;94588:4;94555:13;:38::i;:::-;94322:279;;;;:::o;127693:311::-;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;127819:9:::1;127814:183;127834:19:::0;;::::1;127814:183;;;127912:4;127875:11;:24;127887:8;;127896:1;127887:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;127875:24:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;127875:24:0;:41;;-1:-1:-1;;127875:41:0::1;::::0;::::1;;::::0;;;::::1;::::0;;127975:7;;127983:1;127975:10;;::::1;;;;;:::i;:::-;;;;;;;127931:11;:24;127943:8;;127952:1;127943:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;127931:24:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;127931:24:0;:41:::1;;:54:::0;127855:3;::::1;::::0;::::1;:::i;:::-;;;;127814:183;;126427:314:::0;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;126556:9:::1;126551:183;126571:19:::0;;::::1;126551:183;;;126649:4;126612:11;:24;126624:8;;126633:1;126624:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;126612:24:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;126612:24:0;:41;;-1:-1:-1;;126612:41:0::1;::::0;::::1;;::::0;;;::::1;::::0;;126712:7;;126720:1;126712:10;;::::1;;;;;:::i;:::-;;;;;;;126668:11;:24;126680:8;;126689:1;126680:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;126668:24:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;126668:24:0;:41:::1;;:54:::0;126592:3;::::1;::::0;::::1;:::i;:::-;;;;126551:183;;125034:714:::0;125100:13;125142;108195:10;:17;;108107:113;125142:13;125130:8;:25;;125122:47;;;;-1:-1:-1;;;125122:47:0;;20244:2:1;125122:47:0;;;20226:21:1;20283:1;20263:18;;;20256:29;-1:-1:-1;;;20301:18:1;;;20294:39;20350:18;;125122:47:0;20042:332:1;125122:47:0;125178:21;125202:7;125178:31;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;125222:21:0;;;;:11;:21;;;;;:31;125178;;-1:-1:-1;;;125222:31:0;;125218:193;;;125309:1;125291:7;125285:21;:25;:116;;;;;;;;;;;;;;;;;125350:7;125333:49;;;;;;;;:::i;:::-;;;;;;;;;;;;;125285:116;125267:134;125034:714;-1:-1:-1;;;125034:714:0:o;125218:193::-;125425:11;;;;125421:180;;;125491:1;125473:7;125467:21;:25;:122;;;;;;;;;;;;;;;;;125532:7;125541:19;:8;:17;:19::i;:::-;125515:55;;;;;;;;;:::i;125421:180::-;125654:1;125636:7;125630:21;:25;:110;;;;;;;;;;;;;;;;;125695:7;125678:43;;;;;;;;:::i;124337:280::-;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;2387:21:::1;:19;:21::i;:::-;124449:24:::2;124476:13;124490:6;124476:21;;;;;;;;:::i;:::-;;::::0;;;::::2;::::0;;;::::2;124545:15:::0;;124571:38:::2;::::0;-1:-1:-1;;;124571:38:0;;124589:10:::2;124571:38;::::0;::::2;22432:51:1::0;22499:18;;;22492:34;;;124476:21:0;;-1:-1:-1;;;;;;124545:15:0::2;::::0;;;124571:17:::2;::::0;22405:18:1;;124571:38:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;124438:179;;2431:20:::1;1825:1:::0;2951:7;:22;2768:213;129005:105;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;129078:10:::1;:24:::0;;-1:-1:-1;;;;;;129078:24:0::1;-1:-1:-1::0;;;;;129078:24:0;;;::::1;::::0;;;::::1;::::0;;129005:105::o;127378:307::-;114966:10;;-1:-1:-1;;;;;114966:10:0;114952;:24;114944:52;;;;-1:-1:-1;;;114944:52:0;;;;;;;:::i;:::-;127502:9:::1;127497:181;127517:19:::0;;::::1;127497:181;;;127595:4;127558:11;:24;127570:8;;127579:1;127570:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;127558:24:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;127558:24:0;:41;;-1:-1:-1;;127558:41:0::1;::::0;::::1;;::::0;;;::::1;::::0;;127656:7;;127664:1;127656:10;;::::1;;;;;:::i;:::-;;;;;;;127614:11;:24;127626:8;;127635:1;127626:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;127614:24:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;127614:24:0;:39:::1;;:52:::0;127538:3;::::1;::::0;::::1;:::i;:::-;;;;127497:181;;62087:201:::0;61074:13;:11;:13::i;:::-;-1:-1:-1;;;;;62176:22:0;::::1;62168:73;;;::::0;-1:-1:-1;;;62168:73:0;;22989:2:1;62168:73:0::1;::::0;::::1;22971:21:1::0;23028:2;23008:18;;;23001:30;23067:34;23047:18;;;23040:62;-1:-1:-1;;;23118:18:1;;;23111:36;23164:19;;62168:73:0::1;22787:402:1::0;62168:73:0::1;62252:28;62271:8;62252:18;:28::i;90588:305::-:0;90690:4;-1:-1:-1;;;;;;90727:40:0;;-1:-1:-1;;;90727:40:0;;:105;;-1:-1:-1;;;;;;;90784:48:0;;-1:-1:-1;;;90784:48:0;90727:105;:158;;;-1:-1:-1;;;;;;;;;;82241:40:0;;;90849:36;82132:157;102591:135;96361:4;95959:16;;;:7;:16;;;;;;-1:-1:-1;;;;;95959:16:0;102665:53;;;;-1:-1:-1;;;102665:53:0;;19137:2:1;102665:53:0;;;19119:21:1;19176:2;19156:18;;;19149:30;-1:-1:-1;;;19195:18:1;;;19188:54;19259:18;;102665:53:0;18935:348:1;101904:174:0;101979:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;101979:29:0;-1:-1:-1;;;;;101979:29:0;;;;;;;;:24;;102033:23;101979:24;102033:14;:23::i;:::-;-1:-1:-1;;;;;102024:46:0;;;;;;;;;;;101904:174;;:::o;2467:293::-;1869:1;2601:7;;:19;2593:63;;;;-1:-1:-1;;;2593:63:0;;23396:2:1;2593:63:0;;;23378:21:1;23435:2;23415:18;;;23408:30;23474:33;23454:18;;;23447:61;23525:18;;2593:63:0;23194:355:1;2593:63:0;1869:1;2734:7;:18;2467:293::o;116095:303::-;116173:10;116139:4;116161:23;;;:11;:23;;;;;:33;;;116156:52;;-1:-1:-1;116203:5:0;;116095:303::o;116156:52::-;116224:21;116248:15;:13;:15::i;:::-;116224:39;;116297:1;116281:13;:17;:38;;;;;116302:17;:15;:17::i;:::-;116277:82;;;116343:4;116336:11;;;116095:303;:::o;116277:82::-;116377:5;116370:12;;;116095:303;:::o;119538:1071::-;119584:21;119608:13;108195:10;:17;;108107:113;119608:13;119584:37;;119656:9;119640:13;:25;119632:50;;;;-1:-1:-1;;;119632:50:0;;23756:2:1;119632:50:0;;;23738:21:1;23795:2;23775:18;;;23768:30;-1:-1:-1;;;23814:18:1;;;23807:42;23866:18;;119632:50:0;23554:336:1;119632:50:0;119699:15;119717:17;:13;119733:1;119717:17;:::i;:::-;119699:35;;119876:1;119860:13;:17;:44;;;;-1:-1:-1;119881:18:0;119897:2;119881:13;:18;:::i;:::-;:23;119860:44;119856:406;;;119931:10;;119925:26;;-1:-1:-1;;;;;119931:10:0;119943:7;119925:5;:26::i;:::-;120019:69;;;;;;;;;-1:-1:-1;120019:69:0;;;119996:20;;;:11;:20;;;;;:92;;;;-1:-1:-1;;119996:92:0;;;;;;;;120119:10;;-1:-1:-1;;;;;120119:10:0;120107:23;;:11;:23;;;;;:35;;;;;;:::i;:::-;;;;-1:-1:-1;;120166:20:0;;120178:7;;120166:20;;;;;120205:9;;;;:::i;:::-;;;;119856:406;120307:26;120313:10;120325:7;120307:5;:26::i;:::-;120387:10;120375:23;;;;:11;:23;;;;;:35;;;;;;:::i;:::-;;;;-1:-1:-1;;120484:61:0;;;;;;;;;-1:-1:-1;120484:61:0;;;120461:20;;;:11;:20;;;;;;:84;;;;-1:-1:-1;;120461:84:0;;;;;;;;120579:20;;120461;;120579;;;119573:1036;;119538:1071::o;122981:242::-;123040:24;123067:13;123081:5;;123067:20;;;;;;;;:::i;:::-;;;;;;;;;;123135:15;;123161:54;;-1:-1:-1;;;123161:54:0;;123183:10;123161:54;;;24384:34:1;123202:4:0;24434:18:1;;;24427:43;24486:18;;;24479:34;;;123067:20:0;;-1:-1:-1;;;;;;123135:15:0;;;;123161:21;;24319:18:1;;123161:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;122478:491::-;122547:13;122584:3;122564:18;122578:4;122564:11;:18;:::i;:::-;122563:24;;;;:::i;:::-;122547:40;;122601:12;122634:3;122625:7;;122617:5;:15;;;;:::i;:::-;122616:21;;;;:::i;:::-;122601:36;;122648:11;122680:3;122672:6;;122664:5;:14;;;;:::i;:::-;122663:20;;;;:::i;:::-;122648:35;;122696:24;122723:13;122737:5;;122723:20;;;;;;;;:::i;:::-;;;;;;;;;;122791:15;;122850:11;;122832:36;;-1:-1:-1;;;122832:36:0;;-1:-1:-1;;;;;122850:11:0;;;122832:36;;;22432:51:1;22499:18;;;22492:34;;;122723:20:0;;-1:-1:-1;122791:15:0;;;;122832:17;;22405:18:1;;122832:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;122900:18:0;;122882:42;;-1:-1:-1;;;122882:42:0;;-1:-1:-1;;;;;122900:18:0;;;122882:42;;;22432:51:1;22499:18;;;22492:34;;;122882:17:0;;;;;;22405:18:1;;122882:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;122950:4;122936:10;;:18;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;;;122478:491:0:o;96591:264::-;96684:4;96701:13;96717:23;96732:7;96717:14;:23::i;:::-;96701:39;;96770:5;-1:-1:-1;;;;;96759:16:0;:7;-1:-1:-1;;;;;96759:16:0;;:52;;;-1:-1:-1;;;;;;93618:25:0;;;93594:4;93618:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;96779:32;96759:87;;;;96839:7;-1:-1:-1;;;;;96815:31:0;:20;96827:7;96815:11;:20::i;:::-;-1:-1:-1;;;;;96815:31:0;;96759:87;96751:96;96591:264;-1:-1:-1;;;;96591:264:0:o;100556:1229::-;100681:4;-1:-1:-1;;;;;100654:31:0;:23;100669:7;100654:14;:23::i;:::-;-1:-1:-1;;;;;100654:31:0;;100646:81;;;;-1:-1:-1;;;100646:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;100746:16:0;;100738:65;;;;-1:-1:-1;;;100738:65:0;;25257:2:1;100738:65:0;;;25239:21:1;25296:2;25276:18;;;25269:30;25335:34;25315:18;;;25308:62;-1:-1:-1;;;25386:18:1;;;25379:34;25430:19;;100738:65:0;25055:400:1;100738:65:0;100816:42;100837:4;100843:2;100847:7;100856:1;100816:20;:42::i;:::-;100988:4;-1:-1:-1;;;;;100961:31:0;:23;100976:7;100961:14;:23::i;:::-;-1:-1:-1;;;;;100961:31:0;;100953:81;;;;-1:-1:-1;;;100953:81:0;;;;;;;:::i;:::-;101106:24;;;;:15;:24;;;;;;;;101099:31;;-1:-1:-1;;;;;;101099:31:0;;;;;;-1:-1:-1;;;;;101582:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;101582:20:0;;;101617:13;;;;;;;;;:18;;101099:31;101617:18;;;101657:16;;;:7;:16;;;;;;:21;;;;;;;;;;101696:27;;101122:7;;101696:27;;;92616:346;92546:416;;:::o;61353:132::-;61261:6;;-1:-1:-1;;;;;61261:6:0;59819:10;61417:23;61409:68;;;;-1:-1:-1;;;61409:68:0;;25662:2:1;61409:68:0;;;25644:21:1;;;25681:18;;;25674:30;25740:34;25720:18;;;25713:62;25792:18;;61409:68:0;25460:356:1;62448:191:0;62541:6;;;-1:-1:-1;;;;;62558:17:0;;;-1:-1:-1;;;;;;62558:17:0;;;;;;;62591:40;;62541:6;;;62558:17;62541:6;;62591:40;;62522:16;;62591:40;62511:128;62448:191;:::o;102221:281::-;102342:8;-1:-1:-1;;;;;102333:17:0;:5;-1:-1:-1;;;;;102333:17:0;;102325:55;;;;-1:-1:-1;;;102325:55:0;;26023:2:1;102325:55:0;;;26005:21:1;26062:2;26042:18;;;26035:30;26101:27;26081:18;;;26074:55;26146:18;;102325:55:0;25821:349:1;102325:55:0;-1:-1:-1;;;;;102391:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;102391:46:0;;;;;;;;;;102453:41;;540::1;;;102453::0;;513:18:1;102453:41:0;;;;;;;102221:281;;;:::o;95482:270::-;95595:28;95605:4;95611:2;95615:7;95595:9;:28::i;:::-;95642:47;95665:4;95671:2;95675:7;95684:4;95642:22;:47::i;:::-;95634:110;;;;-1:-1:-1;;;95634:110:0;;;;;;;:::i;56658:716::-;56714:13;56765:14;56782:17;56793:5;56782:10;:17::i;:::-;56802:1;56782:21;56765:38;;56818:20;56852:6;56841:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56841:18:0;-1:-1:-1;56818:41:0;-1:-1:-1;56983:28:0;;;56999:2;56983:28;57040:288;-1:-1:-1;;57072:5:0;-1:-1:-1;;;57209:2:0;57198:14;;57193:30;57072:5;57180:44;57270:2;57261:11;;;-1:-1:-1;57291:21:0;57040:288;57291:21;-1:-1:-1;57349:6:0;56658:716;-1:-1:-1;;;56658:716:0:o;116406:575::-;116507:10;116454:7;116495:23;;;:11;:23;;;;;;;;:33;116780:11;:23;;;;;:40;;;;116739:38;;;;116699:37;;;;116646:36;;;;116603:40;;;;116563:37;;;;;116454:7;;116563:80;;;:::i;:::-;:119;;;;:::i;:::-;:173;;;;:::i;:::-;:214;;;;:::i;:::-;:257;;;;:::i;:::-;116539:281;-1:-1:-1;116831:21:0;116855:26;116871:10;116539:281;116855:26;:::i;:::-;116831:50;;116916:13;116902:10;:27;;116894:48;;;;-1:-1:-1;;;116894:48:0;;26929:2:1;116894:48:0;;;26911:21:1;26968:1;26948:18;;;26941:29;-1:-1:-1;;;26986:18:1;;;26979:38;27034:18;;116894:48:0;26727:331:1;116989:2486:0;117067:10;117034:4;117055:23;;;:11;:23;;;;;:33;117091:1;-1:-1:-1;117051:651:0;;;117223:10;117211:23;;;;:11;:23;;;;;;;;:37;;;;;117171:11;:23;;;;;;;:37;;;:77;;;;117302:40;;;;;117259;;;:83;117392:36;;;;;117353;;;:75;117475:37;;;;;117439:33;;;:73;117558:38;;;;;117523:32;;;:73;117650:40;;;;;117607;;:83;117051:651;117808:10;117836:1;117796:23;;;:11;:23;;;;;:37;;;:41;;;;:59;;;117854:1;117841:10;;:14;117796:59;117792:1637;;;117888:10;117876:23;;;;:11;:23;;;;;:37;;:39;;;;;;:::i;:::-;;;;-1:-1:-1;;118000:10:0;:12;;;:10;:12;;;:::i;:::-;;;;;;118038:4;118031:11;;116989:2486;:::o;117792:1637::-;118080:10;118111:1;118068:23;;;:11;:23;;;;;:40;;;:44;;;;:65;;;118132:1;118116:13;;:17;118068:65;118064:1365;;;118166:10;118154:23;;;;:11;:23;;;;;:40;;:42;;;;;;:::i;:::-;;;;-1:-1:-1;;118285:13:0;:15;;;:13;:15;;;:::i;118064:1365::-;118368:10;118395:1;118356:23;;;:11;:23;;;;;:36;;;:40;;;;:57;;;118412:1;118400:9;;:13;118356:57;118352:1077;;;118446:10;118434:23;;;;:11;:23;;;;;:36;;:38;;;;;;:::i;:::-;;;;-1:-1:-1;;118556:9:0;:11;;;:9;:11;;;:::i;118352:1077::-;118635:10;118659:1;118623:23;;;:11;:23;;;;;:33;;;:37;;;;:54;;;118676:1;118664:9;;:13;118623:54;118619:810;;;118710:10;118698:23;;;;:11;:23;;;;;:33;;:35;;;;;;:::i;:::-;;;;-1:-1:-1;;118818:9:0;:11;;;:9;:11;;;:::i;118619:810::-;118897:10;118920:1;118885:23;;;:11;:23;;;;;:32;;;:36;;;;:52;;;118936:1;118925:8;;:12;118885:52;118881:548;;;118970:10;118958:23;;;;:11;:23;;;;;:32;;:34;;;;;;:::i;:::-;;;;-1:-1:-1;;119076:8:0;:10;;;:8;:10;;;:::i;118881:548::-;119154:10;119185:1;119142:23;;;:11;:23;;;;;:40;;;:44;;;;:68;;;119209:1;119190:16;;:20;119142:68;119138:291;;;119243:10;119231:23;;;;:11;:23;;;;;:40;;:42;;;;;;:::i;:::-;;;;-1:-1:-1;;119365:16:0;:18;;;:16;:18;;;:::i;119138:291::-;-1:-1:-1;119462:5:0;;116989:2486::o;98155:942::-;-1:-1:-1;;;;;98235:16:0;;98227:61;;;;-1:-1:-1;;;98227:61:0;;27406:2:1;98227:61:0;;;27388:21:1;;;27425:18;;;27418:30;27484:34;27464:18;;;27457:62;27536:18;;98227:61:0;27204:356:1;98227:61:0;96361:4;95959:16;;;:7;:16;;;;;;-1:-1:-1;;;;;95959:16:0;96385:31;98299:58;;;;-1:-1:-1;;;98299:58:0;;27767:2:1;98299:58:0;;;27749:21:1;27806:2;27786:18;;;27779:30;27845;27825:18;;;27818:58;27893:18;;98299:58:0;27565:352:1;98299:58:0;98370:48;98399:1;98403:2;98407:7;98416:1;98370:20;:48::i;:::-;96361:4;95959:16;;;:7;:16;;;;;;-1:-1:-1;;;;;95959:16:0;96385:31;98508:58;;;;-1:-1:-1;;;98508:58:0;;27767:2:1;98508:58:0;;;27749:21:1;27806:2;27786:18;;;27779:30;27845;27825:18;;;27818:58;27893:18;;98508:58:0;27565:352:1;98508:58:0;-1:-1:-1;;;;;98915:13:0;;;;;;:9;:13;;;;;;;;:18;;98932:1;98915:18;;;98957:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;98957:21:0;;;;;98996:33;98965:7;;98915:13;;98996:33;;98915:13;;98996:33;129376:16:::1;129298:102:::0;:::o;108604:915::-;108871:1;108859:9;:13;108855:222;;;109002:63;;-1:-1:-1;;;109002:63:0;;28124:2:1;109002:63:0;;;28106:21:1;28163:2;28143:18;;;28136:30;28202:34;28182:18;;;28175:62;-1:-1:-1;;;28253:18:1;;;28246:51;28314:19;;109002:63:0;27922:417:1;108855:222:0;109107:12;-1:-1:-1;;;;;109136:18:0;;109132:187;;109171:40;109203:7;110346:10;:17;;110319:24;;;;:15;:24;;;;;:44;;;110374:24;;;;;;;;;;;;110242:164;109171:40;109132:187;;;109241:2;-1:-1:-1;;;;;109233:10:0;:4;-1:-1:-1;;;;;109233:10:0;;109229:90;;109260:47;109293:4;109299:7;109260:32;:47::i;:::-;-1:-1:-1;;;;;109333:16:0;;109329:183;;109366:45;109403:7;109366:36;:45::i;:::-;109329:183;;;109439:4;-1:-1:-1;;;;;109433:10:0;:2;-1:-1:-1;;;;;109433:10:0;;109429:83;;109460:40;109488:2;109492:7;109460:27;:40::i;103290:853::-;103444:4;-1:-1:-1;;;;;103465:13:0;;64415:19;:23;103461:675;;103501:71;;-1:-1:-1;;;103501:71:0;;-1:-1:-1;;;;;103501:36:0;;;;;:71;;59819:10;;103552:4;;103558:7;;103567:4;;103501:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;103501:71:0;;;;;;;;-1:-1:-1;;103501:71:0;;;;;;;;;;;;:::i;:::-;;;103497:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;103742:6;:13;103759:1;103742:18;103738:328;;103785:60;;-1:-1:-1;;;103785:60:0;;;;;;;:::i;103738:328::-;104016:6;104010:13;104001:6;103997:2;103993:15;103986:38;103497:584;-1:-1:-1;;;;;;103623:51:0;-1:-1:-1;;;103623:51:0;;-1:-1:-1;103616:58:0;;103461:675;-1:-1:-1;104120:4:0;103290:853;;;;;;:::o;53492:948::-;53545:7;;-1:-1:-1;;;53623:17:0;;53619:106;;-1:-1:-1;;;53661:17:0;;;-1:-1:-1;53707:2:0;53697:12;53619:106;53752:8;53743:5;:17;53739:106;;53790:8;53781:17;;;-1:-1:-1;53827:2:0;53817:12;53739:106;53872:8;53863:5;:17;53859:106;;53910:8;53901:17;;;-1:-1:-1;53947:2:0;53937:12;53859:106;53992:7;53983:5;:16;53979:103;;54029:7;54020:16;;;-1:-1:-1;54065:1:0;54055:11;53979:103;54109:7;54100:5;:16;54096:103;;54146:7;54137:16;;;-1:-1:-1;54182:1:0;54172:11;54096:103;54226:7;54217:5;:16;54213:103;;54263:7;54254:16;;;-1:-1:-1;54299:1:0;54289:11;54213:103;54343:7;54334:5;:16;54330:68;;54381:1;54371:11;54426:6;53492:948;-1:-1:-1;;53492:948:0:o;111033:988::-;111299:22;111349:1;111324:22;111341:4;111324:16;:22::i;:::-;:26;;;;:::i;:::-;111361:18;111382:26;;;:17;:26;;;;;;111299:51;;-1:-1:-1;111515:28:0;;;111511:328;;-1:-1:-1;;;;;111582:18:0;;111560:19;111582:18;;;:12;:18;;;;;;;;:34;;;;;;;;;111633:30;;;;;;:44;;;111750:30;;:17;:30;;;;;:43;;;111511:328;-1:-1:-1;111935:26:0;;;;:17;:26;;;;;;;;111928:33;;;-1:-1:-1;;;;;111979:18:0;;;;;:12;:18;;;;;:34;;;;;;;111972:41;111033:988::o;112316:1079::-;112594:10;:17;112569:22;;112594:21;;112614:1;;112594:21;:::i;:::-;112626:18;112647:24;;;:15;:24;;;;;;113020:10;:26;;112569:46;;-1:-1:-1;112647:24:0;;112569:46;;113020:26;;;;;;:::i;:::-;;;;;;;;;112998:48;;113084:11;113059:10;113070;113059:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;113164:28;;;:15;:28;;;;;;;:41;;;113336:24;;;;;113329:31;113371:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;112387:1008;;;112316:1079;:::o;109820:221::-;109905:14;109922:20;109939:2;109922:16;:20::i;:::-;-1:-1:-1;;;;;109953:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;109998:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;109820:221:0:o;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:1;816:16;;809:27;592:250::o;847:271::-;889:3;927:5;921:12;954:6;949:3;942:19;970:76;1039:6;1032:4;1027:3;1023:14;1016:4;1009:5;1005:16;970:76;:::i;:::-;1100:2;1079:15;-1:-1:-1;;1075:29:1;1066:39;;;;1107:4;1062:50;;847:271;-1:-1:-1;;847:271:1:o;1123:220::-;1272:2;1261:9;1254:21;1235:4;1292:45;1333:2;1322:9;1318:18;1310:6;1292:45;:::i;1348:180::-;1407:6;1460:2;1448:9;1439:7;1435:23;1431:32;1428:52;;;1476:1;1473;1466:12;1428:52;-1:-1:-1;1499:23:1;;1348:180;-1:-1:-1;1348:180:1:o;1741:131::-;-1:-1:-1;;;;;1816:31:1;;1806:42;;1796:70;;1862:1;1859;1852:12;1877:315;1945:6;1953;2006:2;1994:9;1985:7;1981:23;1977:32;1974:52;;;2022:1;2019;2012:12;1974:52;2061:9;2048:23;2080:31;2105:5;2080:31;:::i;:::-;2130:5;2182:2;2167:18;;;;2154:32;;-1:-1:-1;;;1877:315:1:o;2197:367::-;2260:8;2270:6;2324:3;2317:4;2309:6;2305:17;2301:27;2291:55;;2342:1;2339;2332:12;2291:55;-1:-1:-1;2365:20:1;;2408:18;2397:30;;2394:50;;;2440:1;2437;2430:12;2394:50;2477:4;2469:6;2465:17;2453:29;;2537:3;2530:4;2520:6;2517:1;2513:14;2505:6;2501:27;2497:38;2494:47;2491:67;;;2554:1;2551;2544:12;2491:67;2197:367;;;;;:::o;2569:1117::-;2736:6;2744;2752;2760;2768;2776;2784;2792;2800;2853:3;2841:9;2832:7;2828:23;2824:33;2821:53;;;2870:1;2867;2860:12;2821:53;2906:9;2893:23;2883:33;;2963:2;2952:9;2948:18;2935:32;2925:42;;3014:2;3003:9;2999:18;2986:32;2976:42;;3069:2;3058:9;3054:18;3041:32;3092:18;3133:2;3125:6;3122:14;3119:34;;;3149:1;3146;3139:12;3119:34;3188:70;3250:7;3241:6;3230:9;3226:22;3188:70;:::i;:::-;3277:8;;-1:-1:-1;3162:96:1;-1:-1:-1;3359:3:1;3344:19;;3331:33;;-1:-1:-1;3411:3:1;3396:19;;3383:33;;-1:-1:-1;3469:3:1;3454:19;;3441:33;;-1:-1:-1;3486:16:1;;;3483:36;;;3515:1;3512;3505:12;3483:36;;3554:72;3618:7;3607:8;3596:9;3592:24;3554:72;:::i;:::-;3528:98;;3645:8;3635:18;;;3672:8;3662:18;;;2569:1117;;;;;;;;;;;:::o;3873:456::-;3950:6;3958;3966;4019:2;4007:9;3998:7;3994:23;3990:32;3987:52;;;4035:1;4032;4025:12;3987:52;4074:9;4061:23;4093:31;4118:5;4093:31;:::i;:::-;4143:5;-1:-1:-1;4200:2:1;4185:18;;4172:32;4213:33;4172:32;4213:33;:::i;:::-;3873:456;;4265:7;;-1:-1:-1;;;4319:2:1;4304:18;;;;4291:32;;3873:456::o;4556:127::-;4617:10;4612:3;4608:20;4605:1;4598:31;4648:4;4645:1;4638:15;4672:4;4669:1;4662:15;4688:632;4753:5;4783:18;4824:2;4816:6;4813:14;4810:40;;;4830:18;;:::i;:::-;4905:2;4899:9;4873:2;4959:15;;-1:-1:-1;;4955:24:1;;;4981:2;4951:33;4947:42;4935:55;;;5005:18;;;5025:22;;;5002:46;4999:72;;;5051:18;;:::i;:::-;5091:10;5087:2;5080:22;5120:6;5111:15;;5150:6;5142;5135:22;5190:3;5181:6;5176:3;5172:16;5169:25;5166:45;;;5207:1;5204;5197:12;5166:45;5257:6;5252:3;5245:4;5237:6;5233:17;5220:44;5312:1;5305:4;5296:6;5288;5284:19;5280:30;5273:41;;;;4688:632;;;;;:::o;5325:451::-;5394:6;5447:2;5435:9;5426:7;5422:23;5418:32;5415:52;;;5463:1;5460;5453:12;5415:52;5503:9;5490:23;5536:18;5528:6;5525:30;5522:50;;;5568:1;5565;5558:12;5522:50;5591:22;;5644:4;5636:13;;5632:27;-1:-1:-1;5622:55:1;;5673:1;5670;5663:12;5622:55;5696:74;5762:7;5757:2;5744:16;5739:2;5735;5731:11;5696:74;:::i;5781:437::-;5867:6;5875;5928:2;5916:9;5907:7;5903:23;5899:32;5896:52;;;5944:1;5941;5934:12;5896:52;5984:9;5971:23;6017:18;6009:6;6006:30;6003:50;;;6049:1;6046;6039:12;6003:50;6088:70;6150:7;6141:6;6130:9;6126:22;6088:70;:::i;:::-;6177:8;;6062:96;;-1:-1:-1;5781:437:1;-1:-1:-1;;;;5781:437:1:o;6665:247::-;6724:6;6777:2;6765:9;6756:7;6752:23;6748:32;6745:52;;;6793:1;6790;6783:12;6745:52;6832:9;6819:23;6851:31;6876:5;6851:31;:::i;6917:773::-;7039:6;7047;7055;7063;7116:2;7104:9;7095:7;7091:23;7087:32;7084:52;;;7132:1;7129;7122:12;7084:52;7172:9;7159:23;7201:18;7242:2;7234:6;7231:14;7228:34;;;7258:1;7255;7248:12;7228:34;7297:70;7359:7;7350:6;7339:9;7335:22;7297:70;:::i;:::-;7386:8;;-1:-1:-1;7271:96:1;-1:-1:-1;7474:2:1;7459:18;;7446:32;;-1:-1:-1;7490:16:1;;;7487:36;;;7519:1;7516;7509:12;7487:36;;7558:72;7622:7;7611:8;7600:9;7596:24;7558:72;:::i;:::-;6917:773;;;;-1:-1:-1;7649:8:1;-1:-1:-1;;;;6917:773:1:o;7961:388::-;8029:6;8037;8090:2;8078:9;8069:7;8065:23;8061:32;8058:52;;;8106:1;8103;8096:12;8058:52;8145:9;8132:23;8164:31;8189:5;8164:31;:::i;:::-;8214:5;-1:-1:-1;8271:2:1;8256:18;;8243:32;8284:33;8243:32;8284:33;:::i;:::-;8336:7;8326:17;;;7961:388;;;;;:::o;8354:118::-;8440:5;8433:13;8426:21;8419:5;8416:32;8406:60;;8462:1;8459;8452:12;8477:382;8542:6;8550;8603:2;8591:9;8582:7;8578:23;8574:32;8571:52;;;8619:1;8616;8609:12;8571:52;8658:9;8645:23;8677:31;8702:5;8677:31;:::i;:::-;8727:5;-1:-1:-1;8784:2:1;8769:18;;8756:32;8797:30;8756:32;8797:30;:::i;9476:795::-;9571:6;9579;9587;9595;9648:3;9636:9;9627:7;9623:23;9619:33;9616:53;;;9665:1;9662;9655:12;9616:53;9704:9;9691:23;9723:31;9748:5;9723:31;:::i;:::-;9773:5;-1:-1:-1;9830:2:1;9815:18;;9802:32;9843:33;9802:32;9843:33;:::i;:::-;9895:7;-1:-1:-1;9949:2:1;9934:18;;9921:32;;-1:-1:-1;10004:2:1;9989:18;;9976:32;10031:18;10020:30;;10017:50;;;10063:1;10060;10053:12;10017:50;10086:22;;10139:4;10131:13;;10127:27;-1:-1:-1;10117:55:1;;10168:1;10165;10158:12;10117:55;10191:74;10257:7;10252:2;10239:16;10234:2;10230;10226:11;10191:74;:::i;:::-;10181:84;;;9476:795;;;;;;;:::o;10898:248::-;10966:6;10974;11027:2;11015:9;11006:7;11002:23;10998:32;10995:52;;;11043:1;11040;11033:12;10995:52;-1:-1:-1;;11066:23:1;;;11136:2;11121:18;;;11108:32;;-1:-1:-1;10898:248:1:o;11151:380::-;11230:1;11226:12;;;;11273;;;11294:61;;11348:4;11340:6;11336:17;11326:27;;11294:61;11401:2;11393:6;11390:14;11370:18;11367:38;11364:161;;11447:10;11442:3;11438:20;11435:1;11428:31;11482:4;11479:1;11472:15;11510:4;11507:1;11500:15;11364:161;;11151:380;;;:::o;12368:339::-;12570:2;12552:21;;;12609:2;12589:18;;;12582:30;-1:-1:-1;;;12643:2:1;12628:18;;12621:45;12698:2;12683:18;;12368:339::o;12712:127::-;12773:10;12768:3;12764:20;12761:1;12754:31;12804:4;12801:1;12794:15;12828:4;12825:1;12818:15;12844:168;12917:9;;;12948;;12965:15;;;12959:22;;12945:37;12935:71;;12986:18;;:::i;13017:127::-;13078:10;13073:3;13069:20;13066:1;13059:31;13109:4;13106:1;13099:15;13133:4;13130:1;13123:15;13149:125;13214:9;;;13235:10;;;13232:36;;;13248:18;;:::i;15012:409::-;15214:2;15196:21;;;15253:2;15233:18;;;15226:30;15292:34;15287:2;15272:18;;15265:62;-1:-1:-1;;;15358:2:1;15343:18;;15336:43;15411:3;15396:19;;15012:409::o;16304:545::-;16406:2;16401:3;16398:11;16395:448;;;16442:1;16467:5;16463:2;16456:17;16512:4;16508:2;16498:19;16582:2;16570:10;16566:19;16563:1;16559:27;16553:4;16549:38;16618:4;16606:10;16603:20;16600:47;;;-1:-1:-1;16641:4:1;16600:47;16696:2;16691:3;16687:12;16684:1;16680:20;16674:4;16670:31;16660:41;;16751:82;16769:2;16762:5;16759:13;16751:82;;;16814:17;;;16795:1;16784:13;16751:82;;;16755:3;;;16304:545;;;:::o;17025:1352::-;17151:3;17145:10;17178:18;17170:6;17167:30;17164:56;;;17200:18;;:::i;:::-;17229:97;17319:6;17279:38;17311:4;17305:11;17279:38;:::i;:::-;17273:4;17229:97;:::i;:::-;17381:4;;17445:2;17434:14;;17462:1;17457:663;;;;18164:1;18181:6;18178:89;;;-1:-1:-1;18233:19:1;;;18227:26;18178:89;-1:-1:-1;;16982:1:1;16978:11;;;16974:24;16970:29;16960:40;17006:1;17002:11;;;16957:57;18280:81;;17427:944;;17457:663;16251:1;16244:14;;;16288:4;16275:18;;-1:-1:-1;;17493:20:1;;;17611:236;17625:7;17622:1;17619:14;17611:236;;;17714:19;;;17708:26;17693:42;;17806:27;;;;17774:1;17762:14;;;;17641:19;;17611:236;;;17615:3;17875:6;17866:7;17863:19;17860:201;;;17936:19;;;17930:26;-1:-1:-1;;18019:1:1;18015:14;;;18031:3;18011:24;18007:37;18003:42;17988:58;17973:74;;17860:201;-1:-1:-1;;;;;18107:1:1;18091:14;;;18087:22;18074:36;;-1:-1:-1;17025:1352:1:o;18795:135::-;18834:3;18855:17;;;18852:43;;18875:18;;:::i;:::-;-1:-1:-1;18922:1:1;18911:13;;18795:135::o;20379:604::-;20712:3;20750:6;20744:13;20766:66;20825:6;20820:3;20813:4;20805:6;20801:17;20766:66;:::i;:::-;-1:-1:-1;;;20854:16:1;;20879:28;;;-1:-1:-1;;;;20934:2:1;20923:14;;20916:31;20974:2;20963:14;;20379:604;-1:-1:-1;20379:604:1:o;20988:663::-;21268:3;21306:6;21300:13;21322:66;21381:6;21376:3;21369:4;21361:6;21357:17;21322:66;:::i;:::-;21451:13;;21410:16;;;;21473:70;21451:13;21410:16;21520:4;21508:17;;21473:70;:::i;:::-;-1:-1:-1;;;21565:20:1;;21594:22;;;21643:1;21632:13;;20988:663;-1:-1:-1;;;;20988:663:1:o;21656:597::-;21989:3;22027:6;22021:13;22043:66;22102:6;22097:3;22090:4;22082:6;22078:17;22043:66;:::i;:::-;-1:-1:-1;;;22131:16:1;;22156:22;;;-1:-1:-1;;;;22205:1:1;22194:13;;22187:30;22244:2;22233:14;;21656:597;-1:-1:-1;21656:597:1:o;22537:245::-;22604:6;22657:2;22645:9;22636:7;22632:23;22628:32;22625:52;;;22673:1;22670;22663:12;22625:52;22705:9;22699:16;22724:28;22746:5;22724:28;:::i;23895:127::-;23956:10;23951:3;23947:20;23944:1;23937:31;23987:4;23984:1;23977:15;24011:4;24008:1;24001:15;24027:112;24059:1;24085;24075:35;;24090:18;;:::i;:::-;-1:-1:-1;24124:9:1;;24027:112::o;24524:120::-;24564:1;24590;24580:35;;24595:18;;:::i;:::-;-1:-1:-1;24629:9:1;;24524:120::o;24649:401::-;24851:2;24833:21;;;24890:2;24870:18;;;24863:30;24929:34;24924:2;24909:18;;24902:62;-1:-1:-1;;;24995:2:1;24980:18;;24973:35;25040:3;25025:19;;24649:401::o;26175:414::-;26377:2;26359:21;;;26416:2;26396:18;;;26389:30;26455:34;26450:2;26435:18;;26428:62;-1:-1:-1;;;26521:2:1;26506:18;;26499:48;26579:3;26564:19;;26175:414::o;26594:128::-;26661:9;;;26682:11;;;26679:37;;;26696:18;;:::i;27063:136::-;27102:3;27130:5;27120:39;;27139:18;;:::i;:::-;-1:-1:-1;;;27175:18:1;;27063:136::o;28344:489::-;-1:-1:-1;;;;;28613:15:1;;;28595:34;;28665:15;;28660:2;28645:18;;28638:43;28712:2;28697:18;;28690:34;;;28760:3;28755:2;28740:18;;28733:31;;;28538:4;;28781:46;;28807:19;;28799:6;28781:46;:::i;:::-;28773:54;28344:489;-1:-1:-1;;;;;;28344:489:1:o;28838:249::-;28907:6;28960:2;28948:9;28939:7;28935:23;28931:32;28928:52;;;28976:1;28973;28966:12;28928:52;29008:9;29002:16;29027:30;29051:5;29027:30;:::i;29092:127::-;29153:10;29148:3;29144:20;29141:1;29134:31;29184:4;29181:1;29174:15;29208:4;29205:1;29198:15
Swarm Source
ipfs://686af8cc5eee68810ddf412555cbfae667e4370cf09432729a1b0fc1911532cd
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.