Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 2,391 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Set Approval For... | 398492647 | 77 days ago | IN | 0 ETH | 0.00000025 | ||||
| Set Approval For... | 396394807 | 83 days ago | IN | 0 ETH | 0.00000029 | ||||
| Set Approval For... | 377276420 | 138 days ago | IN | 0 ETH | 0.00000026 | ||||
| Safe Transfer Fr... | 370431344 | 158 days ago | IN | 0 ETH | 0.00000557 | ||||
| Safe Transfer Fr... | 370431273 | 158 days ago | IN | 0 ETH | 0.00000759 | ||||
| Set Approval For... | 366744911 | 169 days ago | IN | 0 ETH | 0.00000027 | ||||
| Mint | 359491957 | 190 days ago | IN | 0 ETH | 0.00000077 | ||||
| Mint | 359490656 | 190 days ago | IN | 0 ETH | 0.00000079 | ||||
| Mint | 359490250 | 190 days ago | IN | 0 ETH | 0.00000078 | ||||
| Mint | 358907608 | 191 days ago | IN | 0 ETH | 0.00000158 | ||||
| Mint | 358907366 | 191 days ago | IN | 0 ETH | 0.00000174 | ||||
| Mint | 358905857 | 191 days ago | IN | 0 ETH | 0.00000173 | ||||
| Mint | 358905428 | 191 days ago | IN | 0 ETH | 0.00000192 | ||||
| Mint | 358903438 | 191 days ago | IN | 0 ETH | 0.00000257 | ||||
| Mint | 358524666 | 193 days ago | IN | 0 ETH | 0.00000086 | ||||
| Mint | 358523676 | 193 days ago | IN | 0 ETH | 0.00000083 | ||||
| Mint | 358521338 | 193 days ago | IN | 0 ETH | 0.00000096 | ||||
| Mint | 358520322 | 193 days ago | IN | 0 ETH | 0.00000125 | ||||
| Mint | 358399717 | 193 days ago | IN | 0 ETH | 0.00000218 | ||||
| Mint | 358397531 | 193 days ago | IN | 0 ETH | 0.0000024 | ||||
| Mint | 358396869 | 193 days ago | IN | 0 ETH | 0.00000228 | ||||
| Mint | 357846593 | 195 days ago | IN | 0 ETH | 0.00000079 | ||||
| Mint | 357845951 | 195 days ago | IN | 0 ETH | 0.00000079 | ||||
| Mint | 357845832 | 195 days ago | IN | 0 ETH | 0.00000079 | ||||
| Mint | 357484929 | 196 days ago | IN | 0 ETH | 0.00000489 |
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 47733636 | 1131 days ago | 0 ETH | ||||
| 47716079 | 1132 days ago | 0 ETH | ||||
| 47699566 | 1132 days ago | 0 ETH | ||||
| 47694443 | 1132 days ago | 0 ETH | ||||
| 47681523 | 1132 days ago | 0 ETH | ||||
| 47677176 | 1132 days ago | 0 ETH | ||||
| 47676917 | 1132 days ago | 0 ETH | ||||
| 47675967 | 1132 days ago | 0 ETH | ||||
| 47673998 | 1132 days ago | 0 ETH | ||||
| 47673698 | 1132 days ago | 0 ETH | ||||
| 47667705 | 1132 days ago | 0 ETH | ||||
| 47667130 | 1132 days ago | 0 ETH | ||||
| 47666257 | 1132 days ago | 0 ETH | ||||
| 47666218 | 1132 days ago | 0 ETH | ||||
| 47665581 | 1132 days ago | 0 ETH | ||||
| 47664543 | 1132 days ago | 0 ETH | ||||
| 47664520 | 1132 days ago | 0 ETH | ||||
| 47664518 | 1132 days ago | 0 ETH | ||||
| 47663956 | 1132 days ago | 0 ETH | ||||
| 47663828 | 1132 days ago | 0 ETH | ||||
| 47663132 | 1132 days ago | 0 ETH | ||||
| 47662816 | 1132 days ago | 0 ETH | ||||
| 47662224 | 1132 days ago | 0 ETH | ||||
| 47662123 | 1132 days ago | 0 ETH | ||||
| 47662108 | 1132 days ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
DininhoItems
Compiler Version
v0.8.7+commit.e28d00a7
Contract Source Code (Solidity)
/**
*Submitted for verification at Arbiscan.io on 2022-12-19
*/
/**
*Submitted for verification at Arbiscan on 2022-12-18
*/
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.7;
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1);
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}
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 `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);
}
}
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV // Deprecated in v4.8
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} else if (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} else if (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature` or error string. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*
* Documentation for signature generation:
* - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
* - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
*
* _Available since v4.3._
*/
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
/// @solidity memory-safe-assembly
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
*
* See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
*
* _Available since v4.3._
*/
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address, RecoverError) {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*
* _Available since v4.2._
*/
function recover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*
* _Available since v4.3._
*/
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function recover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
/**
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
// 32 is the length in bytes of hash,
// enforced by the type signature above
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
/**
* @dev Returns an Ethereum Signed Message, created from `s`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
}
/**
* @dev Returns an Ethereum Signed Typed Data, created from a
* `domainSeparator` and a `structHash`. This produces hash corresponding
* to the one signed with the
* https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
* JSON-RPC method as part of EIP-712.
*
* See {recover}.
*/
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
}
}
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
interface ERC721A__IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
interface IERC721A {
/**
* The caller must own the token or be an approved operator.
*/
error ApprovalCallerNotOwnerNorApproved();
/**
* The token does not exist.
*/
error ApprovalQueryForNonexistentToken();
/**
* Cannot query the balance for the zero address.
*/
error BalanceQueryForZeroAddress();
/**
* Cannot mint to the zero address.
*/
error MintToZeroAddress();
/**
* The quantity of tokens minted must be more than zero.
*/
error MintZeroQuantity();
/**
* The token does not exist.
*/
error OwnerQueryForNonexistentToken();
/**
* The caller must own the token or be an approved operator.
*/
error TransferCallerNotOwnerNorApproved();
/**
* The token must be owned by `from`.
*/
error TransferFromIncorrectOwner();
/**
* Cannot safely transfer to a contract that does not implement the
* ERC721Receiver interface.
*/
error TransferToNonERC721ReceiverImplementer();
/**
* Cannot transfer to the zero address.
*/
error TransferToZeroAddress();
/**
* The token does not exist.
*/
error URIQueryForNonexistentToken();
/**
* The `quantity` minted with ERC2309 exceeds the safety limit.
*/
error MintERC2309QuantityExceedsLimit();
/**
* The `extraData` cannot be set on an unintialized ownership slot.
*/
error OwnershipNotInitializedForExtraData();
// =============================================================
// STRUCTS
// =============================================================
struct TokenOwnership {
// The address of the owner.
address addr;
// Stores the start time of ownership with minimal overhead for tokenomics.
uint64 startTimestamp;
// Whether the token has been burned.
bool burned;
// Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.
uint24 extraData;
}
// =============================================================
// TOKEN COUNTERS
// =============================================================
/**
* @dev Returns the total number of tokens in existence.
* Burned tokens will reduce the count.
* To get the total number of tokens minted, please see {_totalMinted}.
*/
function totalSupply() external view returns (uint256);
// =============================================================
// IERC165
// =============================================================
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
* to learn more about how these ids are created.
*
* This function call must use less than 30000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
// =============================================================
// IERC721
// =============================================================
/**
* @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`,
* 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 be 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,
bytes calldata data
) external payable;
/**
* @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external payable;
/**
* @dev Transfers `tokenId` from `from` to `to`.
*
* WARNING: Usage of this method is discouraged, use {safeTransferFrom}
* whenever possible.
*
* 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 payable;
/**
* @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 payable;
/**
* @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);
// =============================================================
// IERC721Metadata
// =============================================================
/**
* @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);
// =============================================================
// IERC2309
// =============================================================
/**
* @dev Emitted when tokens in `fromTokenId` to `toTokenId`
* (inclusive) is transferred from `from` to `to`, as defined in the
* [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
*
* See {_mintERC2309} for more details.
*/
event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}
contract ERC721A is IERC721A {
// Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364).
struct TokenApprovalRef {
address value;
}
// =============================================================
// CONSTANTS
// =============================================================
// Mask of an entry in packed address data.
uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;
// The bit position of `numberMinted` in packed address data.
uint256 private constant _BITPOS_NUMBER_MINTED = 64;
// The bit position of `numberBurned` in packed address data.
uint256 private constant _BITPOS_NUMBER_BURNED = 128;
// The bit position of `aux` in packed address data.
uint256 private constant _BITPOS_AUX = 192;
// Mask of all 256 bits in packed address data except the 64 bits for `aux`.
uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;
// The bit position of `startTimestamp` in packed ownership.
uint256 private constant _BITPOS_START_TIMESTAMP = 160;
// The bit mask of the `burned` bit in packed ownership.
uint256 private constant _BITMASK_BURNED = 1 << 224;
// The bit position of the `nextInitialized` bit in packed ownership.
uint256 private constant _BITPOS_NEXT_INITIALIZED = 225;
// The bit mask of the `nextInitialized` bit in packed ownership.
uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225;
// The bit position of `extraData` in packed ownership.
uint256 private constant _BITPOS_EXTRA_DATA = 232;
// Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`.
uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;
// The mask of the lower 160 bits for addresses.
uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;
// The maximum `quantity` that can be minted with {_mintERC2309}.
// This limit is to prevent overflows on the address data entries.
// For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309}
// is required to cause an overflow, which is unrealistic.
uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;
// The `Transfer` event signature is given by:
// `keccak256(bytes("Transfer(address,address,uint256)"))`.
bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;
// =============================================================
// STORAGE
// =============================================================
// The next token ID to be minted.
uint256 private _currentIndex;
// The number of tokens burned.
uint256 private _burnCounter;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to ownership details
// An empty struct value does not necessarily mean the token is unowned.
// See {_packedOwnershipOf} implementation for details.
//
// Bits Layout:
// - [0..159] `addr`
// - [160..223] `startTimestamp`
// - [224] `burned`
// - [225] `nextInitialized`
// - [232..255] `extraData`
mapping(uint256 => uint256) private _packedOwnerships;
// Mapping owner address to address data.
//
// Bits Layout:
// - [0..63] `balance`
// - [64..127] `numberMinted`
// - [128..191] `numberBurned`
// - [192..255] `aux`
mapping(address => uint256) private _packedAddressData;
// Mapping from token ID to approved address.
mapping(uint256 => TokenApprovalRef) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
// =============================================================
// CONSTRUCTOR
// =============================================================
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
_currentIndex = _startTokenId();
}
// =============================================================
// TOKEN COUNTING OPERATIONS
// =============================================================
/**
* @dev Returns the starting token ID.
* To change the starting token ID, please override this function.
*/
function _startTokenId() internal view virtual returns (uint256) {
return 0;
}
/**
* @dev Returns the next token ID to be minted.
*/
function _nextTokenId() internal view virtual returns (uint256) {
return _currentIndex;
}
/**
* @dev Returns the total number of tokens in existence.
* Burned tokens will reduce the count.
* To get the total number of tokens minted, please see {_totalMinted}.
*/
function totalSupply() public view virtual override returns (uint256) {
// Counter underflow is impossible as _burnCounter cannot be incremented
// more than `_currentIndex - _startTokenId()` times.
unchecked {
return _currentIndex - _burnCounter - _startTokenId();
}
}
/**
* @dev Returns the total amount of tokens minted in the contract.
*/
function _totalMinted() internal view virtual returns (uint256) {
// Counter underflow is impossible as `_currentIndex` does not decrement,
// and it is initialized to `_startTokenId()`.
unchecked {
return _currentIndex - _startTokenId();
}
}
/**
* @dev Returns the total number of tokens burned.
*/
function _totalBurned() internal view virtual returns (uint256) {
return _burnCounter;
}
// =============================================================
// ADDRESS DATA OPERATIONS
// =============================================================
/**
* @dev Returns the number of tokens in `owner`'s account.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
if (owner == address(0)) revert BalanceQueryForZeroAddress();
return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
}
/**
* Returns the number of tokens minted by `owner`.
*/
function _numberMinted(address owner) internal view returns (uint256) {
return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY;
}
/**
* Returns the number of tokens burned by or on behalf of `owner`.
*/
function _numberBurned(address owner) internal view returns (uint256) {
return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY;
}
/**
* Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
*/
function _getAux(address owner) internal view returns (uint64) {
return uint64(_packedAddressData[owner] >> _BITPOS_AUX);
}
/**
* Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
* If there are multiple variables, please pack them into a uint64.
*/
function _setAux(address owner, uint64 aux) internal virtual {
uint256 packed = _packedAddressData[owner];
uint256 auxCasted;
// Cast `aux` with assembly to avoid redundant masking.
assembly {
auxCasted := aux
}
packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX);
_packedAddressData[owner] = packed;
}
// =============================================================
// IERC165
// =============================================================
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
* to learn more about how these ids are created.
*
* This function call must use less than 30000 gas.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
// The interface IDs are constants representing the first 4 bytes
// of the XOR of all function selectors in the interface.
// See: [ERC165](https://eips.ethereum.org/EIPS/eip-165)
// (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`)
return
interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
}
// =============================================================
// IERC721Metadata
// =============================================================
/**
* @dev Returns the token collection name.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the token collection symbol.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
string memory baseURI = _baseURI();
return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
}
/**
* @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, it can be overridden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return '';
}
// =============================================================
// OWNERSHIPS OPERATIONS
// =============================================================
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
return address(uint160(_packedOwnershipOf(tokenId)));
}
/**
* @dev Gas spent here starts off proportional to the maximum mint batch size.
* It gradually moves to O(1) as tokens get transferred around over time.
*/
function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) {
return _unpackedOwnership(_packedOwnershipOf(tokenId));
}
/**
* @dev Returns the unpacked `TokenOwnership` struct at `index`.
*/
function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) {
return _unpackedOwnership(_packedOwnerships[index]);
}
/**
* @dev Initializes the ownership slot minted at `index` for efficiency purposes.
*/
function _initializeOwnershipAt(uint256 index) internal virtual {
if (_packedOwnerships[index] == 0) {
_packedOwnerships[index] = _packedOwnershipOf(index);
}
}
/**
* Returns the packed ownership data of `tokenId`.
*/
function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
uint256 curr = tokenId;
unchecked {
if (_startTokenId() <= curr)
if (curr < _currentIndex) {
uint256 packed = _packedOwnerships[curr];
// If not burned.
if (packed & _BITMASK_BURNED == 0) {
// Invariant:
// There will always be an initialized ownership slot
// (i.e. `ownership.addr != address(0) && ownership.burned == false`)
// before an unintialized ownership slot
// (i.e. `ownership.addr == address(0) && ownership.burned == false`)
// Hence, `curr` will not underflow.
//
// We can directly compare the packed value.
// If the address is zero, packed will be zero.
while (packed == 0) {
packed = _packedOwnerships[--curr];
}
return packed;
}
}
}
revert OwnerQueryForNonexistentToken();
}
/**
* @dev Returns the unpacked `TokenOwnership` struct from `packed`.
*/
function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
ownership.addr = address(uint160(packed));
ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP);
ownership.burned = packed & _BITMASK_BURNED != 0;
ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
}
/**
* @dev Packs ownership data into a single uint256.
*/
function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
assembly {
// Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
owner := and(owner, _BITMASK_ADDRESS)
// `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`.
result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags))
}
}
/**
* @dev Returns the `nextInitialized` flag set if `quantity` equals 1.
*/
function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
// For branchless setting of the `nextInitialized` flag.
assembly {
// `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`.
result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
}
}
// =============================================================
// APPROVAL OPERATIONS
// =============================================================
/**
* @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) public payable virtual override {
address owner = ownerOf(tokenId);
if (_msgSenderERC721A() != owner)
if (!isApprovedForAll(owner, _msgSenderERC721A())) {
revert ApprovalCallerNotOwnerNorApproved();
}
_tokenApprovals[tokenId].value = to;
emit Approval(owner, to, tokenId);
}
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();
return _tokenApprovals[tokenId].value;
}
/**
* @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) public virtual override {
_operatorApprovals[_msgSenderERC721A()][operator] = approved;
emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
}
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @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. See {_mint}.
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return
_startTokenId() <= tokenId &&
tokenId < _currentIndex && // If within bounds,
_packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned.
}
/**
* @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`.
*/
function _isSenderApprovedOrOwner(
address approvedAddress,
address owner,
address msgSender
) private pure returns (bool result) {
assembly {
// Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
owner := and(owner, _BITMASK_ADDRESS)
// Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
msgSender := and(msgSender, _BITMASK_ADDRESS)
// `msgSender == owner || msgSender == approvedAddress`.
result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
}
}
/**
* @dev Returns the storage slot and value for the approved address of `tokenId`.
*/
function _getApprovedSlotAndAddress(uint256 tokenId)
private
view
returns (uint256 approvedAddressSlot, address approvedAddress)
{
TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];
// The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`.
assembly {
approvedAddressSlot := tokenApproval.slot
approvedAddress := sload(approvedAddressSlot)
}
}
// =============================================================
// TRANSFER OPERATIONS
// =============================================================
/**
* @dev Transfers `tokenId` from `from` to `to`.
*
* 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
) public payable virtual override {
uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();
(uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);
// The nested ifs save around 20+ gas over a compound boolean condition.
if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
if (to == address(0)) revert TransferToZeroAddress();
_beforeTokenTransfers(from, to, tokenId, 1);
// Clear approvals from the previous owner.
assembly {
if approvedAddress {
// This is equivalent to `delete _tokenApprovals[tokenId]`.
sstore(approvedAddressSlot, 0)
}
}
// Underflow of the sender's balance is impossible because we check for
// ownership above and the recipient's balance can't realistically overflow.
// Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
unchecked {
// We can directly increment and decrement the balances.
--_packedAddressData[from]; // Updates: `balance -= 1`.
++_packedAddressData[to]; // Updates: `balance += 1`.
// Updates:
// - `address` to the next owner.
// - `startTimestamp` to the timestamp of transfering.
// - `burned` to `false`.
// - `nextInitialized` to `true`.
_packedOwnerships[tokenId] = _packOwnershipData(
to,
_BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
);
// If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
uint256 nextTokenId = tokenId + 1;
// If the next slot's address is zero and not burned (i.e. packed value is zero).
if (_packedOwnerships[nextTokenId] == 0) {
// If the next slot is within bounds.
if (nextTokenId != _currentIndex) {
// Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
_packedOwnerships[nextTokenId] = prevOwnershipPacked;
}
}
}
}
emit Transfer(from, to, tokenId);
_afterTokenTransfers(from, to, tokenId, 1);
}
/**
* @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public payable virtual override {
safeTransferFrom(from, to, tokenId, '');
}
/**
* @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 memory _data
) public payable virtual override {
transferFrom(from, to, tokenId);
if (to.code.length != 0)
if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
revert TransferToNonERC721ReceiverImplementer();
}
}
/**
* @dev Hook that is called before a set of serially-ordered token IDs
* are about to be transferred. This includes minting.
* And also called before burning one token.
*
* `startTokenId` - the first token ID to be transferred.
* `quantity` - the amount to be transferred.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, `tokenId` will be burned by `from`.
* - `from` and `to` are never both zero.
*/
function _beforeTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual {}
/**
* @dev Hook that is called after a set of serially-ordered token IDs
* have been transferred. This includes minting.
* And also called after one token has been burned.
*
* `startTokenId` - the first token ID to be transferred.
* `quantity` - the amount to be transferred.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
* transferred to `to`.
* - When `from` is zero, `tokenId` has been minted for `to`.
* - When `to` is zero, `tokenId` has been burned by `from`.
* - `from` and `to` are never both zero.
*/
function _afterTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual {}
/**
* @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract.
*
* `from` - Previous owner of the given token ID.
* `to` - Target address that will receive the token.
* `tokenId` - Token ID to be transferred.
* `_data` - Optional data to send along with the call.
*
* Returns whether the call correctly returned the expected magic value.
*/
function _checkContractOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
bytes4 retval
) {
return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert TransferToNonERC721ReceiverImplementer();
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
}
// =============================================================
// MINT OPERATIONS
// =============================================================
/**
* @dev Mints `quantity` tokens and transfers them to `to`.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `quantity` must be greater than 0.
*
* Emits a {Transfer} event for each mint.
*/
function _mint(address to, uint256 quantity) internal virtual {
uint256 startTokenId = _currentIndex;
if (quantity == 0) revert MintZeroQuantity();
_beforeTokenTransfers(address(0), to, startTokenId, quantity);
// Overflows are incredibly unrealistic.
// `balance` and `numberMinted` have a maximum limit of 2**64.
// `tokenId` has a maximum limit of 2**256.
unchecked {
// Updates:
// - `balance += quantity`.
// - `numberMinted += quantity`.
//
// We can directly add to the `balance` and `numberMinted`.
_packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);
// Updates:
// - `address` to the owner.
// - `startTimestamp` to the timestamp of minting.
// - `burned` to `false`.
// - `nextInitialized` to `quantity == 1`.
_packedOwnerships[startTokenId] = _packOwnershipData(
to,
_nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
);
uint256 toMasked;
uint256 end = startTokenId + quantity;
// Use assembly to loop and emit the `Transfer` event for gas savings.
// The duplicated `log4` removes an extra check and reduces stack juggling.
// The assembly, together with the surrounding Solidity code, have been
// delicately arranged to nudge the compiler into producing optimized opcodes.
assembly {
// Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
toMasked := and(to, _BITMASK_ADDRESS)
// Emit the `Transfer` event.
log4(
0, // Start of data (0, since no data).
0, // End of data (0, since no data).
_TRANSFER_EVENT_SIGNATURE, // Signature.
0, // `address(0)`.
toMasked, // `to`.
startTokenId // `tokenId`.
)
// The `iszero(eq(,))` check ensures that large values of `quantity`
// that overflows uint256 will make the loop run out of gas.
// The compiler will optimize the `iszero` away for performance.
for {
let tokenId := add(startTokenId, 1)
} iszero(eq(tokenId, end)) {
tokenId := add(tokenId, 1)
} {
// Emit the `Transfer` event. Similar to above.
log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
}
}
if (toMasked == 0) revert MintToZeroAddress();
_currentIndex = end;
}
_afterTokenTransfers(address(0), to, startTokenId, quantity);
}
/**
* @dev Mints `quantity` tokens and transfers them to `to`.
*
* This function is intended for efficient minting only during contract creation.
*
* It emits only one {ConsecutiveTransfer} as defined in
* [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
* instead of a sequence of {Transfer} event(s).
*
* Calling this function outside of contract creation WILL make your contract
* non-compliant with the ERC721 standard.
* For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
* {ConsecutiveTransfer} event is only permissible during contract creation.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `quantity` must be greater than 0.
*
* Emits a {ConsecutiveTransfer} event.
*/
function _mintERC2309(address to, uint256 quantity) internal virtual {
uint256 startTokenId = _currentIndex;
if (to == address(0)) revert MintToZeroAddress();
if (quantity == 0) revert MintZeroQuantity();
if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit();
_beforeTokenTransfers(address(0), to, startTokenId, quantity);
// Overflows are unrealistic due to the above check for `quantity` to be below the limit.
unchecked {
// Updates:
// - `balance += quantity`.
// - `numberMinted += quantity`.
//
// We can directly add to the `balance` and `numberMinted`.
_packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);
// Updates:
// - `address` to the owner.
// - `startTimestamp` to the timestamp of minting.
// - `burned` to `false`.
// - `nextInitialized` to `quantity == 1`.
_packedOwnerships[startTokenId] = _packOwnershipData(
to,
_nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
);
emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);
_currentIndex = startTokenId + quantity;
}
_afterTokenTransfers(address(0), to, startTokenId, quantity);
}
/**
* @dev Safely mints `quantity` tokens and transfers them to `to`.
*
* Requirements:
*
* - If `to` refers to a smart contract, it must implement
* {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
* - `quantity` must be greater than 0.
*
* See {_mint}.
*
* Emits a {Transfer} event for each mint.
*/
function _safeMint(
address to,
uint256 quantity,
bytes memory _data
) internal virtual {
_mint(to, quantity);
unchecked {
if (to.code.length != 0) {
uint256 end = _currentIndex;
uint256 index = end - quantity;
do {
if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
revert TransferToNonERC721ReceiverImplementer();
}
} while (index < end);
// Reentrancy protection.
if (_currentIndex != end) revert();
}
}
}
/**
* @dev Equivalent to `_safeMint(to, quantity, '')`.
*/
function _safeMint(address to, uint256 quantity) internal virtual {
_safeMint(to, quantity, '');
}
// =============================================================
// BURN OPERATIONS
// =============================================================
/**
* @dev Equivalent to `_burn(tokenId, false)`.
*/
function _burn(uint256 tokenId) internal virtual {
_burn(tokenId, false);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
address from = address(uint160(prevOwnershipPacked));
(uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);
if (approvalCheck) {
// The nested ifs save around 20+ gas over a compound boolean condition.
if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
}
_beforeTokenTransfers(from, address(0), tokenId, 1);
// Clear approvals from the previous owner.
assembly {
if approvedAddress {
// This is equivalent to `delete _tokenApprovals[tokenId]`.
sstore(approvedAddressSlot, 0)
}
}
// Underflow of the sender's balance is impossible because we check for
// ownership above and the recipient's balance can't realistically overflow.
// Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
unchecked {
// Updates:
// - `balance -= 1`.
// - `numberBurned += 1`.
//
// We can directly decrement the balance, and increment the number burned.
// This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`.
_packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1;
// Updates:
// - `address` to the last owner.
// - `startTimestamp` to the timestamp of burning.
// - `burned` to `true`.
// - `nextInitialized` to `true`.
_packedOwnerships[tokenId] = _packOwnershipData(
from,
(_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
);
// If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
uint256 nextTokenId = tokenId + 1;
// If the next slot's address is zero and not burned (i.e. packed value is zero).
if (_packedOwnerships[nextTokenId] == 0) {
// If the next slot is within bounds.
if (nextTokenId != _currentIndex) {
// Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
_packedOwnerships[nextTokenId] = prevOwnershipPacked;
}
}
}
}
emit Transfer(from, address(0), tokenId);
_afterTokenTransfers(from, address(0), tokenId, 1);
// Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
unchecked {
_burnCounter++;
}
}
// =============================================================
// EXTRA DATA OPERATIONS
// =============================================================
/**
* @dev Directly sets the extra data for the ownership data `index`.
*/
function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual {
uint256 packed = _packedOwnerships[index];
if (packed == 0) revert OwnershipNotInitializedForExtraData();
uint256 extraDataCasted;
// Cast `extraData` with assembly to avoid redundant masking.
assembly {
extraDataCasted := extraData
}
packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA);
_packedOwnerships[index] = packed;
}
/**
* @dev Called during each token transfer to set the 24bit `extraData` field.
* Intended to be overridden by the cosumer contract.
*
* `previousExtraData` - the value of `extraData` before transfer.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, `tokenId` will be burned by `from`.
* - `from` and `to` are never both zero.
*/
function _extraData(
address from,
address to,
uint24 previousExtraData
) internal view virtual returns (uint24) {}
/**
* @dev Returns the next extra data for the packed ownership data.
* The returned result is shifted into position.
*/
function _nextExtraData(
address from,
address to,
uint256 prevOwnershipPacked
) private view returns (uint256) {
uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA);
return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA;
}
// =============================================================
// OTHER OPERATIONS
// =============================================================
/**
* @dev Returns the message sender (defaults to `msg.sender`).
*
* If you are writing GSN compatible contracts, you need to override this function.
*/
function _msgSenderERC721A() internal view virtual returns (address) {
return msg.sender;
}
/**
* @dev Converts a uint256 to its ASCII string decimal representation.
*/
function _toString(uint256 value) internal pure virtual returns (string memory str) {
assembly {
// The maximum value of a uint256 contains 78 digits (1 byte per digit), but
// we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
// We will need 1 word for the trailing zeros padding, 1 word for the length,
// and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
let m := add(mload(0x40), 0xa0)
// Update the free memory pointer to allocate.
mstore(0x40, m)
// Assign the `str` to the end.
str := sub(m, 0x20)
// Zeroize the slot after the string.
mstore(str, 0)
// Cache the end of the memory to calculate the length later.
let end := str
// We write the string from rightmost digit to leftmost digit.
// The following is essentially a do-while loop that also handles the zero case.
// prettier-ignore
for { let temp := value } 1 {} {
str := sub(str, 1)
// Write the character to the pointer.
// The ASCII index of the '0' character is 48.
mstore8(str, add(48, mod(temp, 10)))
// Keep dividing `temp` until zero.
temp := div(temp, 10)
// prettier-ignore
if iszero(temp) { break }
}
let length := sub(end, str)
// Move the pointer 32 bytes leftwards to make room for the length.
str := sub(str, 0x20)
// Store the length.
mstore(str, length)
}
}
}
interface IERC721AQueryable is IERC721A {
/**
* Invalid query range (`start` >= `stop`).
*/
error InvalidQueryRange();
/**
* @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
*
* If the `tokenId` is out of bounds:
*
* - `addr = address(0)`
* - `startTimestamp = 0`
* - `burned = false`
* - `extraData = 0`
*
* If the `tokenId` is burned:
*
* - `addr = <Address of owner before token was burned>`
* - `startTimestamp = <Timestamp when token was burned>`
* - `burned = true`
* - `extraData = <Extra data when token was burned>`
*
* Otherwise:
*
* - `addr = <Address of owner>`
* - `startTimestamp = <Timestamp of start of ownership>`
* - `burned = false`
* - `extraData = <Extra data at start of ownership>`
*/
function explicitOwnershipOf(uint256 tokenId) external view returns (TokenOwnership memory);
/**
* @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
* See {ERC721AQueryable-explicitOwnershipOf}
*/
function explicitOwnershipsOf(uint256[] memory tokenIds) external view returns (TokenOwnership[] memory);
/**
* @dev Returns an array of token IDs owned by `owner`,
* in the range [`start`, `stop`)
* (i.e. `start <= tokenId < stop`).
*
* This function allows for tokens to be queried if the collection
* grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
*
* Requirements:
*
* - `start < stop`
*/
function tokensOfOwnerIn(
address owner,
uint256 start,
uint256 stop
) external view returns (uint256[] memory);
/**
* @dev Returns an array of token IDs owned by `owner`.
*
* This function scans the ownership mapping and is O(`totalSupply`) in complexity.
* It is meant to be called off-chain.
*
* See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
* multiple smaller scans if the collection is large enough to cause
* an out-of-gas error (10K collections should be fine).
*/
function tokensOfOwner(address owner) external view returns (uint256[] memory);
}
abstract contract ERC721AQueryable is ERC721A, IERC721AQueryable {
/**
* @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
*
* If the `tokenId` is out of bounds:
*
* - `addr = address(0)`
* - `startTimestamp = 0`
* - `burned = false`
* - `extraData = 0`
*
* If the `tokenId` is burned:
*
* - `addr = <Address of owner before token was burned>`
* - `startTimestamp = <Timestamp when token was burned>`
* - `burned = true`
* - `extraData = <Extra data when token was burned>`
*
* Otherwise:
*
* - `addr = <Address of owner>`
* - `startTimestamp = <Timestamp of start of ownership>`
* - `burned = false`
* - `extraData = <Extra data at start of ownership>`
*/
function explicitOwnershipOf(uint256 tokenId) public view virtual override returns (TokenOwnership memory) {
TokenOwnership memory ownership;
if (tokenId < _startTokenId() || tokenId >= _nextTokenId()) {
return ownership;
}
ownership = _ownershipAt(tokenId);
if (ownership.burned) {
return ownership;
}
return _ownershipOf(tokenId);
}
/**
* @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
* See {ERC721AQueryable-explicitOwnershipOf}
*/
function explicitOwnershipsOf(uint256[] calldata tokenIds)
external
view
virtual
override
returns (TokenOwnership[] memory)
{
unchecked {
uint256 tokenIdsLength = tokenIds.length;
TokenOwnership[] memory ownerships = new TokenOwnership[](tokenIdsLength);
for (uint256 i; i != tokenIdsLength; ++i) {
ownerships[i] = explicitOwnershipOf(tokenIds[i]);
}
return ownerships;
}
}
/**
* @dev Returns an array of token IDs owned by `owner`,
* in the range [`start`, `stop`)
* (i.e. `start <= tokenId < stop`).
*
* This function allows for tokens to be queried if the collection
* grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
*
* Requirements:
*
* - `start < stop`
*/
function tokensOfOwnerIn(
address owner,
uint256 start,
uint256 stop
) external view virtual override returns (uint256[] memory) {
unchecked {
if (start >= stop) revert InvalidQueryRange();
uint256 tokenIdsIdx;
uint256 stopLimit = _nextTokenId();
// Set `start = max(start, _startTokenId())`.
if (start < _startTokenId()) {
start = _startTokenId();
}
// Set `stop = min(stop, stopLimit)`.
if (stop > stopLimit) {
stop = stopLimit;
}
uint256 tokenIdsMaxLength = balanceOf(owner);
// Set `tokenIdsMaxLength = min(balanceOf(owner), stop - start)`,
// to cater for cases where `balanceOf(owner)` is too big.
if (start < stop) {
uint256 rangeLength = stop - start;
if (rangeLength < tokenIdsMaxLength) {
tokenIdsMaxLength = rangeLength;
}
} else {
tokenIdsMaxLength = 0;
}
uint256[] memory tokenIds = new uint256[](tokenIdsMaxLength);
if (tokenIdsMaxLength == 0) {
return tokenIds;
}
// We need to call `explicitOwnershipOf(start)`,
// because the slot at `start` may not be initialized.
TokenOwnership memory ownership = explicitOwnershipOf(start);
address currOwnershipAddr;
// If the starting slot exists (i.e. not burned), initialize `currOwnershipAddr`.
// `ownership.address` will not be zero, as `start` is clamped to the valid token ID range.
if (!ownership.burned) {
currOwnershipAddr = ownership.addr;
}
for (uint256 i = start; i != stop && tokenIdsIdx != tokenIdsMaxLength; ++i) {
ownership = _ownershipAt(i);
if (ownership.burned) {
continue;
}
if (ownership.addr != address(0)) {
currOwnershipAddr = ownership.addr;
}
if (currOwnershipAddr == owner) {
tokenIds[tokenIdsIdx++] = i;
}
}
// Downsize the array to fit.
assembly {
mstore(tokenIds, tokenIdsIdx)
}
return tokenIds;
}
}
/**
* @dev Returns an array of token IDs owned by `owner`.
*
* This function scans the ownership mapping and is O(`totalSupply`) in complexity.
* It is meant to be called off-chain.
*
* See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
* multiple smaller scans if the collection is large enough to cause
* an out-of-gas error (10K collections should be fine).
*/
function tokensOfOwner(address owner) external view virtual override returns (uint256[] memory) {
unchecked {
uint256 tokenIdsIdx;
address currOwnershipAddr;
uint256 tokenIdsLength = balanceOf(owner);
uint256[] memory tokenIds = new uint256[](tokenIdsLength);
TokenOwnership memory ownership;
for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) {
ownership = _ownershipAt(i);
if (ownership.burned) {
continue;
}
if (ownership.addr != address(0)) {
currOwnershipAddr = ownership.addr;
}
if (currOwnershipAddr == owner) {
tokenIds[tokenIdsIdx++] = i;
}
}
return tokenIds;
}
}
}
interface IERC721ABurnable is IERC721A {
/**
* @dev Burns `tokenId`. See {ERC721A-_burn}.
*
* Requirements:
*
* - The caller must own `tokenId` or be an approved operator.
*/
function burn(uint256 tokenId) external;
}
abstract contract ERC721ABurnable is ERC721A, IERC721ABurnable {
/**
* @dev Burns `tokenId`. See {ERC721A-_burn}.
*
* Requirements:
*
* - The caller must own `tokenId` or be an approved operator.
*/
function burn(uint256 tokenId) public virtual override {
_burn(tokenId, true);
}
}
contract DininhoItems is ERC721AQueryable, ERC721ABurnable, Ownable {
using ECDSA for bytes32;
uint public salesTimestamp = 1660496400;
mapping(address => uint) private _totalMintPerAccount;
address private _signerPublicKey = 0x62ca88AfE969a6a65a256A99Aa987cf64aEB703b;
string private _contractUri;
string private _baseUri;
constructor() ERC721A("DininhoItems", "DI"){
}
function mint(uint amount, bytes calldata signature) external payable {
require( _isMessageValid(signature,msg.sender,amount) == _signerPublicKey , "invalid signature");
require(isSalesActive(), "sales is not active");
require(amount > 0, "invalid amount");
_totalMintPerAccount[msg.sender] += amount;
_safeMint(msg.sender, amount);
}
function isSalesActive() public view returns (bool) {
return salesTimestamp <= block.timestamp;
}
function totalMintPerAccount(address account) public view returns (uint) {
return _totalMintPerAccount[account];
}
function contractURI() external view returns (string memory) {
return _contractUri;
}
function _baseURI() internal view override returns (string memory) {
return _baseUri;
}
function setContractURI(string memory contractURI_) external onlyOwner {
_contractUri = contractURI_;
}
function setBaseURI(string memory baseURI_) external onlyOwner {
_baseUri = baseURI_;
}
function setSignerPublicKey(address signerPublicKey_) external onlyOwner {
_signerPublicKey = signerPublicKey_;
}
function setsalesTimestamp(uint timestamp) external onlyOwner {
salesTimestamp = timestamp;
}
function withdrawAll() external onlyOwner {
require(payable(msg.sender).send(address(this).balance));
}
function _isMessageValid(bytes memory _signature, address account, uint amount) public view returns (address){
bytes32 messageHash = keccak256(abi.encodePacked(address(this),account, _totalMintPerAccount[account],amount));
return messageHash.toEthSignedMessageHash().recover(_signature);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"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":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"_isMessageValid","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"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":"isSalesActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"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":"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":"payable","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":"payable","type":"function"},{"inputs":[],"name":"salesTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"baseURI_","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"contractURI_","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signerPublicKey_","type":"address"}],"name":"setSignerPublicKey","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"setsalesTimestamp","outputs":[],"stateMutability":"nonpayable","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":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"totalMintPerAccount","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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040526362f92a106009557362ca88afe969a6a65a256a99aa987cf64aeb703b600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503480156200006e57600080fd5b506040518060400160405280600c81526020017f44696e696e686f4974656d7300000000000000000000000000000000000000008152506040518060400160405280600281526020017f44490000000000000000000000000000000000000000000000000000000000008152508160029080519060200190620000f39291906200021e565b5080600390805190602001906200010c9291906200021e565b506200011d6200014b60201b60201c565b600081905550505062000145620001396200015060201b60201c565b6200015860201b60201c565b62000333565b600090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8280546200022c90620002ce565b90600052602060002090601f0160209004810192826200025057600085556200029c565b82601f106200026b57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029b5782518255916020019190600101906200027e565b5b509050620002ab9190620002af565b5090565b5b80821115620002ca576000816000905550600101620002b0565b5090565b60006002820490506001821680620002e757607f821691505b60208210811415620002fe57620002fd62000304565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b613f0680620003436000396000f3fe6080604052600436106101ee5760003560e01c806381ce8f971161010d578063b88d4fde116100a0578063db7fd4081161006f578063db7fd408146106eb578063e8a3d48514610707578063e985e9c514610732578063ec288a651461076f578063f2fde38b146107ac576101ee565b8063b88d4fde1461062a578063c23dc68f14610646578063c87b56dd14610683578063daa81cdd146106c0576101ee565b8063938e3d7b116100dc578063938e3d7b1461057057806395d89b411461059957806399a2557a146105c4578063a22cb46514610601576101ee565b806381ce8f97146104c85780638462151c146104f1578063853828b61461052e5780638da5cb5b14610545576101ee565b806342842e0e116101855780635bbb2177116101545780635bbb2177146103fa5780636352211e1461043757806370a0823114610474578063715018a6146104b1576101ee565b806342842e0e1461034f57806342966c681461036b57806353c412a01461039457806355f804b3146103d1576101ee565b80630a080cd5116101c15780630a080cd5146102b457806318160ddd146102df57806323b872dd1461030a5780633006178314610326576101ee565b806301ffc9a7146101f357806306fdde0314610230578063081812fc1461025b578063095ea7b314610298575b600080fd5b3480156101ff57600080fd5b5061021a60048036038101906102159190612f8a565b6107d5565b60405161022791906136bb565b60405180910390f35b34801561023c57600080fd5b50610245610867565b604051610252919061371b565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d919061309c565b6108f9565b60405161028f9190613610565b60405180910390f35b6102b260048036038101906102ad9190612eaa565b610978565b005b3480156102c057600080fd5b506102c9610abc565b6040516102d69190613858565b60405180910390f35b3480156102eb57600080fd5b506102f4610ac2565b6040516103019190613858565b60405180910390f35b610324600480360381019061031f9190612d94565b610ad9565b005b34801561033257600080fd5b5061034d60048036038101906103489190612d27565b610dfe565b005b61036960048036038101906103649190612d94565b610e4a565b005b34801561037757600080fd5b50610392600480360381019061038d919061309c565b610e6a565b005b3480156103a057600080fd5b506103bb60048036038101906103b69190612fe4565b610e78565b6040516103c89190613610565b60405180910390f35b3480156103dd57600080fd5b506103f860048036038101906103f39190613053565b610f0e565b005b34801561040657600080fd5b50610421600480360381019061041c9190612f3d565b610f30565b60405161042e9190613677565b60405180910390f35b34801561044357600080fd5b5061045e6004803603810190610459919061309c565b610ff3565b60405161046b9190613610565b60405180910390f35b34801561048057600080fd5b5061049b60048036038101906104969190612d27565b611005565b6040516104a89190613858565b60405180910390f35b3480156104bd57600080fd5b506104c66110be565b005b3480156104d457600080fd5b506104ef60048036038101906104ea919061309c565b6110d2565b005b3480156104fd57600080fd5b5061051860048036038101906105139190612d27565b6110e4565b6040516105259190613699565b60405180910390f35b34801561053a57600080fd5b5061054361122e565b005b34801561055157600080fd5b5061055a611276565b6040516105679190613610565b60405180910390f35b34801561057c57600080fd5b5061059760048036038101906105929190613053565b6112a0565b005b3480156105a557600080fd5b506105ae6112c2565b6040516105bb919061371b565b60405180910390f35b3480156105d057600080fd5b506105eb60048036038101906105e69190612eea565b611354565b6040516105f89190613699565b60405180910390f35b34801561060d57600080fd5b5061062860048036038101906106239190612e6a565b611568565b005b610644600480360381019061063f9190612de7565b611673565b005b34801561065257600080fd5b5061066d6004803603810190610668919061309c565b6116e6565b60405161067a919061383d565b60405180910390f35b34801561068f57600080fd5b506106aa60048036038101906106a5919061309c565b611750565b6040516106b7919061371b565b60405180910390f35b3480156106cc57600080fd5b506106d56117ef565b6040516106e291906136bb565b60405180910390f35b610705600480360381019061070091906130c9565b6117fc565b005b34801561071357600080fd5b5061071c6119c9565b604051610729919061371b565b60405180910390f35b34801561073e57600080fd5b5061075960048036038101906107549190612d54565b611a5b565b60405161076691906136bb565b60405180910390f35b34801561077b57600080fd5b5061079660048036038101906107919190612d27565b611aef565b6040516107a39190613858565b60405180910390f35b3480156107b857600080fd5b506107d360048036038101906107ce9190612d27565b611b38565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061083057506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108605750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461087690613af5565b80601f01602080910402602001604051908101604052809291908181526020018280546108a290613af5565b80156108ef5780601f106108c4576101008083540402835291602001916108ef565b820191906000526020600020905b8154815290600101906020018083116108d257829003601f168201915b5050505050905090565b600061090482611bbc565b61093a576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061098382610ff3565b90508073ffffffffffffffffffffffffffffffffffffffff166109a4611c1b565b73ffffffffffffffffffffffffffffffffffffffff1614610a07576109d0816109cb611c1b565b611a5b565b610a06576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60095481565b6000610acc611c23565b6001546000540303905090565b6000610ae482611c28565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b4b576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610b5784611cf6565b91509150610b6d8187610b68611c1b565b611d1d565b610bb957610b8286610b7d611c1b565b611a5b565b610bb8576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610c20576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c2d8686866001611d61565b8015610c3857600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610d0685610ce2888887611d67565b7c020000000000000000000000000000000000000000000000000000000017611d8f565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084161415610d8e576000600185019050600060046000838152602001908152602001600020541415610d8c576000548114610d8b578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610df68686866001611dba565b505050505050565b610e06611dc0565b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610e6583838360405180602001604052806000815250611673565b505050565b610e75816001611e3e565b50565b6000803084600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485604051602001610ed19493929190613578565b604051602081830303815290604052805190602001209050610f0485610ef683612092565b6120c290919063ffffffff16565b9150509392505050565b610f16611dc0565b80600d9080519060200190610f2c929190612a40565b5050565b6060600083839050905060008167ffffffffffffffff811115610f5657610f55613c4c565b5b604051908082528060200260200182016040528015610f8f57816020015b610f7c612ac6565b815260200190600190039081610f745790505b50905060005b828114610fe757610fbe868683818110610fb257610fb1613c1d565b5b905060200201356116e6565b828281518110610fd157610fd0613c1d565b5b6020026020010181905250806001019050610f95565b50809250505092915050565b6000610ffe82611c28565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561106d576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6110c6611dc0565b6110d060006120e9565b565b6110da611dc0565b8060098190555050565b606060008060006110f485611005565b905060008167ffffffffffffffff81111561111257611111613c4c565b5b6040519080825280602002602001820160405280156111405781602001602082028036833780820191505090505b50905061114b612ac6565b6000611155611c23565b90505b83861461122057611168816121af565b915081604001511561117957611215565b600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16146111b957816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415611214578083878060010198508151811061120757611206613c1d565b5b6020026020010181815250505b5b806001019050611158565b508195505050505050919050565b611236611dc0565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505061127457600080fd5b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6112a8611dc0565b80600c90805190602001906112be929190612a40565b5050565b6060600380546112d190613af5565b80601f01602080910402602001604051908101604052809291908181526020018280546112fd90613af5565b801561134a5780601f1061131f5761010080835404028352916020019161134a565b820191906000526020600020905b81548152906001019060200180831161132d57829003601f168201915b5050505050905090565b606081831061138f576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061139a6121da565b90506113a4611c23565b8510156113b6576113b3611c23565b94505b808411156113c2578093505b60006113cd87611005565b9050848610156113f05760008686039050818110156113ea578091505b506113f5565b600090505b60008167ffffffffffffffff81111561141157611410613c4c565b5b60405190808252806020026020018201604052801561143f5781602001602082028036833780820191505090505b50905060008214156114575780945050505050611561565b6000611462886116e6565b90506000816040015161147757816000015190505b60008990505b88811415801561148d5750848714155b156115535761149b816121af565b92508260400151156114ac57611548565b600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16146114ec57826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611547578084888060010199508151811061153a57611539613c1d565b5b6020026020010181815250505b5b80600101905061147d565b508583528296505050505050505b9392505050565b8060076000611575611c1b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611622611c1b565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161166791906136bb565b60405180910390a35050565b61167e848484610ad9565b60008373ffffffffffffffffffffffffffffffffffffffff163b146116e0576116a9848484846121e3565b6116df576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6116ee612ac6565b6116f6612ac6565b6116fe611c23565b831080611712575061170e6121da565b8310155b15611720578091505061174b565b611729836121af565b905080604001511561173e578091505061174b565b61174783612343565b9150505b919050565b606061175b82611bbc565b611791576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061179b612363565b90506000815114156117bc57604051806020016040528060008152506117e7565b806117c6846123f5565b6040516020016117d79291906135c6565b6040516020818303038152906040525b915050919050565b6000426009541115905090565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661188483838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050503386610e78565b73ffffffffffffffffffffffffffffffffffffffff16146118da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118d19061375d565b60405180910390fd5b6118e26117ef565b611921576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119189061381d565b60405180910390fd5b60008311611964576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195b906137bd565b60405180910390fd5b82600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546119b391906139af565b925050819055506119c4338461244e565b505050565b6060600c80546119d890613af5565b80601f0160208091040260200160405190810160405280929190818152602001828054611a0490613af5565b8015611a515780601f10611a2657610100808354040283529160200191611a51565b820191906000526020600020905b815481529060010190602001808311611a3457829003601f168201915b5050505050905090565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611b40611dc0565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba79061379d565b60405180910390fd5b611bb9816120e9565b50565b600081611bc7611c23565b11158015611bd6575060005482105b8015611c14575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b600090565b60008082905080611c37611c23565b11611cbf57600054811015611cbe5760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082161415611cbc575b6000811415611cb2576004600083600190039350838152602001908152602001600020549050611c87565b8092505050611cf1565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611d7e86868461246c565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b611dc8612475565b73ffffffffffffffffffffffffffffffffffffffff16611de6611276565b73ffffffffffffffffffffffffffffffffffffffff1614611e3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e33906137fd565b60405180910390fd5b565b6000611e4983611c28565b90506000819050600080611e5c86611cf6565b915091508415611ec557611e788184611e73611c1b565b611d1d565b611ec457611e8d83611e88611c1b565b611a5b565b611ec3576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b611ed3836000886001611d61565b8015611ede57600082555b600160806001901b03600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611f8683611f4385600088611d67565b7c02000000000000000000000000000000000000000000000000000000007c01000000000000000000000000000000000000000000000000000000001717611d8f565b600460008881526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008516141561200e57600060018701905060006004600083815260200190815260200160002054141561200c57600054811461200b578460046000838152602001908152602001600020819055505b5b505b85600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612078836000886001611dba565b600160008154809291906001019190505550505050505050565b6000816040516020016120a591906135ea565b604051602081830303815290604052805190602001209050919050565b60008060006120d1858561247d565b915091506120de816124cf565b819250505092915050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6121b7612ac6565b6121d3600460008481526020019081526020016000205461263d565b9050919050565b60008054905090565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612209611c1b565b8786866040518563ffffffff1660e01b815260040161222b949392919061362b565b602060405180830381600087803b15801561224557600080fd5b505af192505050801561227657506040513d601f19601f820116820180604052508101906122739190612fb7565b60015b6122f0573d80600081146122a6576040519150601f19603f3d011682016040523d82523d6000602084013e6122ab565b606091505b506000815114156122e8576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b61234b612ac6565b61235c61235783611c28565b61263d565b9050919050565b6060600d805461237290613af5565b80601f016020809104026020016040519081016040528092919081815260200182805461239e90613af5565b80156123eb5780601f106123c0576101008083540402835291602001916123eb565b820191906000526020600020905b8154815290600101906020018083116123ce57829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b60011561243957600184039350600a81066030018453600a810490508061243457612439565b61240e565b50828103602084039350808452505050919050565b6124688282604051806020016040528060008152506126f3565b5050565b60009392505050565b600033905090565b6000806041835114156124bf5760008060006020860151925060408601519150606086015160001a90506124b387828585612790565b945094505050506124c8565b60006002915091505b9250929050565b600060048111156124e3576124e2613bbf565b5b8160048111156124f6576124f5613bbf565b5b14156125015761263a565b6001600481111561251557612514613bbf565b5b81600481111561252857612527613bbf565b5b1415612569576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125609061373d565b60405180910390fd5b6002600481111561257d5761257c613bbf565b5b8160048111156125905761258f613bbf565b5b14156125d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125c89061377d565b60405180910390fd5b600360048111156125e5576125e4613bbf565b5b8160048111156125f8576125f7613bbf565b5b1415612639576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612630906137dd565b60405180910390fd5b5b50565b612645612ac6565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b6126fd8383612873565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461278b57600080549050600083820390505b61273d60008683806001019450866121e3565b612773576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81811061272a57816000541461278857600080fd5b50505b505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c11156127cb57600060039150915061286a565b6000600187878787604051600081526020016040526040516127f094939291906136d6565b6020604051602081039080840390855afa158015612812573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156128615760006001925092505061286a565b80600092509250505b94509492505050565b60008054905060008214156128b4576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128c16000848385611d61565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612938836129296000866000611d67565b61293285612a30565b17611d8f565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146129d957808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460018101905061299e565b506000821415612a15576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050612a2b6000848385611dba565b505050565b60006001821460e11b9050919050565b828054612a4c90613af5565b90600052602060002090601f016020900481019282612a6e5760008555612ab5565b82601f10612a8757805160ff1916838001178555612ab5565b82800160010185558215612ab5579182015b82811115612ab4578251825591602001919060010190612a99565b5b509050612ac29190612b15565b5090565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b5b80821115612b2e576000816000905550600101612b16565b5090565b6000612b45612b4084613898565b613873565b905082815260208101848484011115612b6157612b60613c8a565b5b612b6c848285613ab3565b509392505050565b6000612b87612b82846138c9565b613873565b905082815260208101848484011115612ba357612ba2613c8a565b5b612bae848285613ab3565b509392505050565b600081359050612bc581613e74565b92915050565b60008083601f840112612be157612be0613c80565b5b8235905067ffffffffffffffff811115612bfe57612bfd613c7b565b5b602083019150836020820283011115612c1a57612c19613c85565b5b9250929050565b600081359050612c3081613e8b565b92915050565b600081359050612c4581613ea2565b92915050565b600081519050612c5a81613ea2565b92915050565b60008083601f840112612c7657612c75613c80565b5b8235905067ffffffffffffffff811115612c9357612c92613c7b565b5b602083019150836001820283011115612caf57612cae613c85565b5b9250929050565b600082601f830112612ccb57612cca613c80565b5b8135612cdb848260208601612b32565b91505092915050565b600082601f830112612cf957612cf8613c80565b5b8135612d09848260208601612b74565b91505092915050565b600081359050612d2181613eb9565b92915050565b600060208284031215612d3d57612d3c613c94565b5b6000612d4b84828501612bb6565b91505092915050565b60008060408385031215612d6b57612d6a613c94565b5b6000612d7985828601612bb6565b9250506020612d8a85828601612bb6565b9150509250929050565b600080600060608486031215612dad57612dac613c94565b5b6000612dbb86828701612bb6565b9350506020612dcc86828701612bb6565b9250506040612ddd86828701612d12565b9150509250925092565b60008060008060808587031215612e0157612e00613c94565b5b6000612e0f87828801612bb6565b9450506020612e2087828801612bb6565b9350506040612e3187828801612d12565b925050606085013567ffffffffffffffff811115612e5257612e51613c8f565b5b612e5e87828801612cb6565b91505092959194509250565b60008060408385031215612e8157612e80613c94565b5b6000612e8f85828601612bb6565b9250506020612ea085828601612c21565b9150509250929050565b60008060408385031215612ec157612ec0613c94565b5b6000612ecf85828601612bb6565b9250506020612ee085828601612d12565b9150509250929050565b600080600060608486031215612f0357612f02613c94565b5b6000612f1186828701612bb6565b9350506020612f2286828701612d12565b9250506040612f3386828701612d12565b9150509250925092565b60008060208385031215612f5457612f53613c94565b5b600083013567ffffffffffffffff811115612f7257612f71613c8f565b5b612f7e85828601612bcb565b92509250509250929050565b600060208284031215612fa057612f9f613c94565b5b6000612fae84828501612c36565b91505092915050565b600060208284031215612fcd57612fcc613c94565b5b6000612fdb84828501612c4b565b91505092915050565b600080600060608486031215612ffd57612ffc613c94565b5b600084013567ffffffffffffffff81111561301b5761301a613c8f565b5b61302786828701612cb6565b935050602061303886828701612bb6565b925050604061304986828701612d12565b9150509250925092565b60006020828403121561306957613068613c94565b5b600082013567ffffffffffffffff81111561308757613086613c8f565b5b61309384828501612ce4565b91505092915050565b6000602082840312156130b2576130b1613c94565b5b60006130c084828501612d12565b91505092915050565b6000806000604084860312156130e2576130e1613c94565b5b60006130f086828701612d12565b935050602084013567ffffffffffffffff81111561311157613110613c8f565b5b61311d86828701612c60565b92509250509250925092565b6000613135838361346c565b60808301905092915050565b600061314d8383613525565b60208301905092915050565b61316281613a05565b82525050565b61317181613a05565b82525050565b61318861318382613a05565b613b58565b82525050565b60006131998261391a565b6131a38185613960565b93506131ae836138fa565b8060005b838110156131df5781516131c68882613129565b97506131d183613946565b9250506001810190506131b2565b5085935050505092915050565b60006131f782613925565b6132018185613971565b935061320c8361390a565b8060005b8381101561323d5781516132248882613141565b975061322f83613953565b925050600181019050613210565b5085935050505092915050565b61325381613a17565b82525050565b61326281613a17565b82525050565b61327181613a23565b82525050565b61328861328382613a23565b613b6a565b82525050565b600061329982613930565b6132a38185613982565b93506132b3818560208601613ac2565b6132bc81613c99565b840191505092915050565b60006132d28261393b565b6132dc8185613993565b93506132ec818560208601613ac2565b6132f581613c99565b840191505092915050565b600061330b8261393b565b61331581856139a4565b9350613325818560208601613ac2565b80840191505092915050565b600061333e601883613993565b915061334982613cb7565b602082019050919050565b6000613361601183613993565b915061336c82613ce0565b602082019050919050565b6000613384601f83613993565b915061338f82613d09565b602082019050919050565b60006133a7601c836139a4565b91506133b282613d32565b601c82019050919050565b60006133ca602683613993565b91506133d582613d5b565b604082019050919050565b60006133ed600e83613993565b91506133f882613daa565b602082019050919050565b6000613410602283613993565b915061341b82613dd3565b604082019050919050565b6000613433602083613993565b915061343e82613e22565b602082019050919050565b6000613456601383613993565b915061346182613e4b565b602082019050919050565b6080820160008201516134826000850182613159565b506020820151613495602085018261355a565b5060408201516134a8604085018261324a565b5060608201516134bb6060850182613516565b50505050565b6080820160008201516134d76000850182613159565b5060208201516134ea602085018261355a565b5060408201516134fd604085018261324a565b5060608201516135106060850182613516565b50505050565b61351f81613a79565b82525050565b61352e81613a88565b82525050565b61353d81613a88565b82525050565b61355461354f82613a88565b613b86565b82525050565b61356381613a92565b82525050565b61357281613aa6565b82525050565b60006135848287613177565b6014820191506135948286613177565b6014820191506135a48285613543565b6020820191506135b48284613543565b60208201915081905095945050505050565b60006135d28285613300565b91506135de8284613300565b91508190509392505050565b60006135f58261339a565b91506136018284613277565b60208201915081905092915050565b60006020820190506136256000830184613168565b92915050565b60006080820190506136406000830187613168565b61364d6020830186613168565b61365a6040830185613534565b818103606083015261366c818461328e565b905095945050505050565b60006020820190508181036000830152613691818461318e565b905092915050565b600060208201905081810360008301526136b381846131ec565b905092915050565b60006020820190506136d06000830184613259565b92915050565b60006080820190506136eb6000830187613268565b6136f86020830186613569565b6137056040830185613268565b6137126060830184613268565b95945050505050565b6000602082019050818103600083015261373581846132c7565b905092915050565b6000602082019050818103600083015261375681613331565b9050919050565b6000602082019050818103600083015261377681613354565b9050919050565b6000602082019050818103600083015261379681613377565b9050919050565b600060208201905081810360008301526137b6816133bd565b9050919050565b600060208201905081810360008301526137d6816133e0565b9050919050565b600060208201905081810360008301526137f681613403565b9050919050565b6000602082019050818103600083015261381681613426565b9050919050565b6000602082019050818103600083015261383681613449565b9050919050565b600060808201905061385260008301846134c1565b92915050565b600060208201905061386d6000830184613534565b92915050565b600061387d61388e565b90506138898282613b27565b919050565b6000604051905090565b600067ffffffffffffffff8211156138b3576138b2613c4c565b5b6138bc82613c99565b9050602081019050919050565b600067ffffffffffffffff8211156138e4576138e3613c4c565b5b6138ed82613c99565b9050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b60006139ba82613a88565b91506139c583613a88565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156139fa576139f9613b90565b5b828201905092915050565b6000613a1082613a59565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062ffffff82169050919050565b6000819050919050565b600067ffffffffffffffff82169050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b83811015613ae0578082015181840152602081019050613ac5565b83811115613aef576000848401525b50505050565b60006002820490506001821680613b0d57607f821691505b60208210811415613b2157613b20613bee565b5b50919050565b613b3082613c99565b810181811067ffffffffffffffff82111715613b4f57613b4e613c4c565b5b80604052505050565b6000613b6382613b74565b9050919050565b6000819050919050565b6000613b7f82613caa565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b7f696e76616c6964207369676e6174757265000000000000000000000000000000600082015250565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f696e76616c696420616d6f756e74000000000000000000000000000000000000600082015250565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f73616c6573206973206e6f742061637469766500000000000000000000000000600082015250565b613e7d81613a05565b8114613e8857600080fd5b50565b613e9481613a17565b8114613e9f57600080fd5b50565b613eab81613a2d565b8114613eb657600080fd5b50565b613ec281613a88565b8114613ecd57600080fd5b5056fea2646970667358221220ee398dd6f5b84400b913bece98c23fc45508148cd2778f33d2248d215f4c81b364736f6c63430008070033
Deployed Bytecode
0x6080604052600436106101ee5760003560e01c806381ce8f971161010d578063b88d4fde116100a0578063db7fd4081161006f578063db7fd408146106eb578063e8a3d48514610707578063e985e9c514610732578063ec288a651461076f578063f2fde38b146107ac576101ee565b8063b88d4fde1461062a578063c23dc68f14610646578063c87b56dd14610683578063daa81cdd146106c0576101ee565b8063938e3d7b116100dc578063938e3d7b1461057057806395d89b411461059957806399a2557a146105c4578063a22cb46514610601576101ee565b806381ce8f97146104c85780638462151c146104f1578063853828b61461052e5780638da5cb5b14610545576101ee565b806342842e0e116101855780635bbb2177116101545780635bbb2177146103fa5780636352211e1461043757806370a0823114610474578063715018a6146104b1576101ee565b806342842e0e1461034f57806342966c681461036b57806353c412a01461039457806355f804b3146103d1576101ee565b80630a080cd5116101c15780630a080cd5146102b457806318160ddd146102df57806323b872dd1461030a5780633006178314610326576101ee565b806301ffc9a7146101f357806306fdde0314610230578063081812fc1461025b578063095ea7b314610298575b600080fd5b3480156101ff57600080fd5b5061021a60048036038101906102159190612f8a565b6107d5565b60405161022791906136bb565b60405180910390f35b34801561023c57600080fd5b50610245610867565b604051610252919061371b565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d919061309c565b6108f9565b60405161028f9190613610565b60405180910390f35b6102b260048036038101906102ad9190612eaa565b610978565b005b3480156102c057600080fd5b506102c9610abc565b6040516102d69190613858565b60405180910390f35b3480156102eb57600080fd5b506102f4610ac2565b6040516103019190613858565b60405180910390f35b610324600480360381019061031f9190612d94565b610ad9565b005b34801561033257600080fd5b5061034d60048036038101906103489190612d27565b610dfe565b005b61036960048036038101906103649190612d94565b610e4a565b005b34801561037757600080fd5b50610392600480360381019061038d919061309c565b610e6a565b005b3480156103a057600080fd5b506103bb60048036038101906103b69190612fe4565b610e78565b6040516103c89190613610565b60405180910390f35b3480156103dd57600080fd5b506103f860048036038101906103f39190613053565b610f0e565b005b34801561040657600080fd5b50610421600480360381019061041c9190612f3d565b610f30565b60405161042e9190613677565b60405180910390f35b34801561044357600080fd5b5061045e6004803603810190610459919061309c565b610ff3565b60405161046b9190613610565b60405180910390f35b34801561048057600080fd5b5061049b60048036038101906104969190612d27565b611005565b6040516104a89190613858565b60405180910390f35b3480156104bd57600080fd5b506104c66110be565b005b3480156104d457600080fd5b506104ef60048036038101906104ea919061309c565b6110d2565b005b3480156104fd57600080fd5b5061051860048036038101906105139190612d27565b6110e4565b6040516105259190613699565b60405180910390f35b34801561053a57600080fd5b5061054361122e565b005b34801561055157600080fd5b5061055a611276565b6040516105679190613610565b60405180910390f35b34801561057c57600080fd5b5061059760048036038101906105929190613053565b6112a0565b005b3480156105a557600080fd5b506105ae6112c2565b6040516105bb919061371b565b60405180910390f35b3480156105d057600080fd5b506105eb60048036038101906105e69190612eea565b611354565b6040516105f89190613699565b60405180910390f35b34801561060d57600080fd5b5061062860048036038101906106239190612e6a565b611568565b005b610644600480360381019061063f9190612de7565b611673565b005b34801561065257600080fd5b5061066d6004803603810190610668919061309c565b6116e6565b60405161067a919061383d565b60405180910390f35b34801561068f57600080fd5b506106aa60048036038101906106a5919061309c565b611750565b6040516106b7919061371b565b60405180910390f35b3480156106cc57600080fd5b506106d56117ef565b6040516106e291906136bb565b60405180910390f35b610705600480360381019061070091906130c9565b6117fc565b005b34801561071357600080fd5b5061071c6119c9565b604051610729919061371b565b60405180910390f35b34801561073e57600080fd5b5061075960048036038101906107549190612d54565b611a5b565b60405161076691906136bb565b60405180910390f35b34801561077b57600080fd5b5061079660048036038101906107919190612d27565b611aef565b6040516107a39190613858565b60405180910390f35b3480156107b857600080fd5b506107d360048036038101906107ce9190612d27565b611b38565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061083057506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108605750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461087690613af5565b80601f01602080910402602001604051908101604052809291908181526020018280546108a290613af5565b80156108ef5780601f106108c4576101008083540402835291602001916108ef565b820191906000526020600020905b8154815290600101906020018083116108d257829003601f168201915b5050505050905090565b600061090482611bbc565b61093a576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061098382610ff3565b90508073ffffffffffffffffffffffffffffffffffffffff166109a4611c1b565b73ffffffffffffffffffffffffffffffffffffffff1614610a07576109d0816109cb611c1b565b611a5b565b610a06576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60095481565b6000610acc611c23565b6001546000540303905090565b6000610ae482611c28565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b4b576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610b5784611cf6565b91509150610b6d8187610b68611c1b565b611d1d565b610bb957610b8286610b7d611c1b565b611a5b565b610bb8576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610c20576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c2d8686866001611d61565b8015610c3857600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610d0685610ce2888887611d67565b7c020000000000000000000000000000000000000000000000000000000017611d8f565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084161415610d8e576000600185019050600060046000838152602001908152602001600020541415610d8c576000548114610d8b578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610df68686866001611dba565b505050505050565b610e06611dc0565b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610e6583838360405180602001604052806000815250611673565b505050565b610e75816001611e3e565b50565b6000803084600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485604051602001610ed19493929190613578565b604051602081830303815290604052805190602001209050610f0485610ef683612092565b6120c290919063ffffffff16565b9150509392505050565b610f16611dc0565b80600d9080519060200190610f2c929190612a40565b5050565b6060600083839050905060008167ffffffffffffffff811115610f5657610f55613c4c565b5b604051908082528060200260200182016040528015610f8f57816020015b610f7c612ac6565b815260200190600190039081610f745790505b50905060005b828114610fe757610fbe868683818110610fb257610fb1613c1d565b5b905060200201356116e6565b828281518110610fd157610fd0613c1d565b5b6020026020010181905250806001019050610f95565b50809250505092915050565b6000610ffe82611c28565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561106d576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6110c6611dc0565b6110d060006120e9565b565b6110da611dc0565b8060098190555050565b606060008060006110f485611005565b905060008167ffffffffffffffff81111561111257611111613c4c565b5b6040519080825280602002602001820160405280156111405781602001602082028036833780820191505090505b50905061114b612ac6565b6000611155611c23565b90505b83861461122057611168816121af565b915081604001511561117957611215565b600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16146111b957816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415611214578083878060010198508151811061120757611206613c1d565b5b6020026020010181815250505b5b806001019050611158565b508195505050505050919050565b611236611dc0565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505061127457600080fd5b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6112a8611dc0565b80600c90805190602001906112be929190612a40565b5050565b6060600380546112d190613af5565b80601f01602080910402602001604051908101604052809291908181526020018280546112fd90613af5565b801561134a5780601f1061131f5761010080835404028352916020019161134a565b820191906000526020600020905b81548152906001019060200180831161132d57829003601f168201915b5050505050905090565b606081831061138f576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061139a6121da565b90506113a4611c23565b8510156113b6576113b3611c23565b94505b808411156113c2578093505b60006113cd87611005565b9050848610156113f05760008686039050818110156113ea578091505b506113f5565b600090505b60008167ffffffffffffffff81111561141157611410613c4c565b5b60405190808252806020026020018201604052801561143f5781602001602082028036833780820191505090505b50905060008214156114575780945050505050611561565b6000611462886116e6565b90506000816040015161147757816000015190505b60008990505b88811415801561148d5750848714155b156115535761149b816121af565b92508260400151156114ac57611548565b600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16146114ec57826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611547578084888060010199508151811061153a57611539613c1d565b5b6020026020010181815250505b5b80600101905061147d565b508583528296505050505050505b9392505050565b8060076000611575611c1b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611622611c1b565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161166791906136bb565b60405180910390a35050565b61167e848484610ad9565b60008373ffffffffffffffffffffffffffffffffffffffff163b146116e0576116a9848484846121e3565b6116df576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6116ee612ac6565b6116f6612ac6565b6116fe611c23565b831080611712575061170e6121da565b8310155b15611720578091505061174b565b611729836121af565b905080604001511561173e578091505061174b565b61174783612343565b9150505b919050565b606061175b82611bbc565b611791576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061179b612363565b90506000815114156117bc57604051806020016040528060008152506117e7565b806117c6846123f5565b6040516020016117d79291906135c6565b6040516020818303038152906040525b915050919050565b6000426009541115905090565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661188483838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050503386610e78565b73ffffffffffffffffffffffffffffffffffffffff16146118da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118d19061375d565b60405180910390fd5b6118e26117ef565b611921576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119189061381d565b60405180910390fd5b60008311611964576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195b906137bd565b60405180910390fd5b82600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546119b391906139af565b925050819055506119c4338461244e565b505050565b6060600c80546119d890613af5565b80601f0160208091040260200160405190810160405280929190818152602001828054611a0490613af5565b8015611a515780601f10611a2657610100808354040283529160200191611a51565b820191906000526020600020905b815481529060010190602001808311611a3457829003601f168201915b5050505050905090565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611b40611dc0565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba79061379d565b60405180910390fd5b611bb9816120e9565b50565b600081611bc7611c23565b11158015611bd6575060005482105b8015611c14575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b600090565b60008082905080611c37611c23565b11611cbf57600054811015611cbe5760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082161415611cbc575b6000811415611cb2576004600083600190039350838152602001908152602001600020549050611c87565b8092505050611cf1565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611d7e86868461246c565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b611dc8612475565b73ffffffffffffffffffffffffffffffffffffffff16611de6611276565b73ffffffffffffffffffffffffffffffffffffffff1614611e3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e33906137fd565b60405180910390fd5b565b6000611e4983611c28565b90506000819050600080611e5c86611cf6565b915091508415611ec557611e788184611e73611c1b565b611d1d565b611ec457611e8d83611e88611c1b565b611a5b565b611ec3576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b611ed3836000886001611d61565b8015611ede57600082555b600160806001901b03600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611f8683611f4385600088611d67565b7c02000000000000000000000000000000000000000000000000000000007c01000000000000000000000000000000000000000000000000000000001717611d8f565b600460008881526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008516141561200e57600060018701905060006004600083815260200190815260200160002054141561200c57600054811461200b578460046000838152602001908152602001600020819055505b5b505b85600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612078836000886001611dba565b600160008154809291906001019190505550505050505050565b6000816040516020016120a591906135ea565b604051602081830303815290604052805190602001209050919050565b60008060006120d1858561247d565b915091506120de816124cf565b819250505092915050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6121b7612ac6565b6121d3600460008481526020019081526020016000205461263d565b9050919050565b60008054905090565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612209611c1b565b8786866040518563ffffffff1660e01b815260040161222b949392919061362b565b602060405180830381600087803b15801561224557600080fd5b505af192505050801561227657506040513d601f19601f820116820180604052508101906122739190612fb7565b60015b6122f0573d80600081146122a6576040519150601f19603f3d011682016040523d82523d6000602084013e6122ab565b606091505b506000815114156122e8576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b61234b612ac6565b61235c61235783611c28565b61263d565b9050919050565b6060600d805461237290613af5565b80601f016020809104026020016040519081016040528092919081815260200182805461239e90613af5565b80156123eb5780601f106123c0576101008083540402835291602001916123eb565b820191906000526020600020905b8154815290600101906020018083116123ce57829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b60011561243957600184039350600a81066030018453600a810490508061243457612439565b61240e565b50828103602084039350808452505050919050565b6124688282604051806020016040528060008152506126f3565b5050565b60009392505050565b600033905090565b6000806041835114156124bf5760008060006020860151925060408601519150606086015160001a90506124b387828585612790565b945094505050506124c8565b60006002915091505b9250929050565b600060048111156124e3576124e2613bbf565b5b8160048111156124f6576124f5613bbf565b5b14156125015761263a565b6001600481111561251557612514613bbf565b5b81600481111561252857612527613bbf565b5b1415612569576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125609061373d565b60405180910390fd5b6002600481111561257d5761257c613bbf565b5b8160048111156125905761258f613bbf565b5b14156125d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125c89061377d565b60405180910390fd5b600360048111156125e5576125e4613bbf565b5b8160048111156125f8576125f7613bbf565b5b1415612639576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612630906137dd565b60405180910390fd5b5b50565b612645612ac6565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b6126fd8383612873565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461278b57600080549050600083820390505b61273d60008683806001019450866121e3565b612773576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81811061272a57816000541461278857600080fd5b50505b505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c11156127cb57600060039150915061286a565b6000600187878787604051600081526020016040526040516127f094939291906136d6565b6020604051602081039080840390855afa158015612812573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156128615760006001925092505061286a565b80600092509250505b94509492505050565b60008054905060008214156128b4576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128c16000848385611d61565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612938836129296000866000611d67565b61293285612a30565b17611d8f565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146129d957808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460018101905061299e565b506000821415612a15576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050612a2b6000848385611dba565b505050565b60006001821460e11b9050919050565b828054612a4c90613af5565b90600052602060002090601f016020900481019282612a6e5760008555612ab5565b82601f10612a8757805160ff1916838001178555612ab5565b82800160010185558215612ab5579182015b82811115612ab4578251825591602001919060010190612a99565b5b509050612ac29190612b15565b5090565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b5b80821115612b2e576000816000905550600101612b16565b5090565b6000612b45612b4084613898565b613873565b905082815260208101848484011115612b6157612b60613c8a565b5b612b6c848285613ab3565b509392505050565b6000612b87612b82846138c9565b613873565b905082815260208101848484011115612ba357612ba2613c8a565b5b612bae848285613ab3565b509392505050565b600081359050612bc581613e74565b92915050565b60008083601f840112612be157612be0613c80565b5b8235905067ffffffffffffffff811115612bfe57612bfd613c7b565b5b602083019150836020820283011115612c1a57612c19613c85565b5b9250929050565b600081359050612c3081613e8b565b92915050565b600081359050612c4581613ea2565b92915050565b600081519050612c5a81613ea2565b92915050565b60008083601f840112612c7657612c75613c80565b5b8235905067ffffffffffffffff811115612c9357612c92613c7b565b5b602083019150836001820283011115612caf57612cae613c85565b5b9250929050565b600082601f830112612ccb57612cca613c80565b5b8135612cdb848260208601612b32565b91505092915050565b600082601f830112612cf957612cf8613c80565b5b8135612d09848260208601612b74565b91505092915050565b600081359050612d2181613eb9565b92915050565b600060208284031215612d3d57612d3c613c94565b5b6000612d4b84828501612bb6565b91505092915050565b60008060408385031215612d6b57612d6a613c94565b5b6000612d7985828601612bb6565b9250506020612d8a85828601612bb6565b9150509250929050565b600080600060608486031215612dad57612dac613c94565b5b6000612dbb86828701612bb6565b9350506020612dcc86828701612bb6565b9250506040612ddd86828701612d12565b9150509250925092565b60008060008060808587031215612e0157612e00613c94565b5b6000612e0f87828801612bb6565b9450506020612e2087828801612bb6565b9350506040612e3187828801612d12565b925050606085013567ffffffffffffffff811115612e5257612e51613c8f565b5b612e5e87828801612cb6565b91505092959194509250565b60008060408385031215612e8157612e80613c94565b5b6000612e8f85828601612bb6565b9250506020612ea085828601612c21565b9150509250929050565b60008060408385031215612ec157612ec0613c94565b5b6000612ecf85828601612bb6565b9250506020612ee085828601612d12565b9150509250929050565b600080600060608486031215612f0357612f02613c94565b5b6000612f1186828701612bb6565b9350506020612f2286828701612d12565b9250506040612f3386828701612d12565b9150509250925092565b60008060208385031215612f5457612f53613c94565b5b600083013567ffffffffffffffff811115612f7257612f71613c8f565b5b612f7e85828601612bcb565b92509250509250929050565b600060208284031215612fa057612f9f613c94565b5b6000612fae84828501612c36565b91505092915050565b600060208284031215612fcd57612fcc613c94565b5b6000612fdb84828501612c4b565b91505092915050565b600080600060608486031215612ffd57612ffc613c94565b5b600084013567ffffffffffffffff81111561301b5761301a613c8f565b5b61302786828701612cb6565b935050602061303886828701612bb6565b925050604061304986828701612d12565b9150509250925092565b60006020828403121561306957613068613c94565b5b600082013567ffffffffffffffff81111561308757613086613c8f565b5b61309384828501612ce4565b91505092915050565b6000602082840312156130b2576130b1613c94565b5b60006130c084828501612d12565b91505092915050565b6000806000604084860312156130e2576130e1613c94565b5b60006130f086828701612d12565b935050602084013567ffffffffffffffff81111561311157613110613c8f565b5b61311d86828701612c60565b92509250509250925092565b6000613135838361346c565b60808301905092915050565b600061314d8383613525565b60208301905092915050565b61316281613a05565b82525050565b61317181613a05565b82525050565b61318861318382613a05565b613b58565b82525050565b60006131998261391a565b6131a38185613960565b93506131ae836138fa565b8060005b838110156131df5781516131c68882613129565b97506131d183613946565b9250506001810190506131b2565b5085935050505092915050565b60006131f782613925565b6132018185613971565b935061320c8361390a565b8060005b8381101561323d5781516132248882613141565b975061322f83613953565b925050600181019050613210565b5085935050505092915050565b61325381613a17565b82525050565b61326281613a17565b82525050565b61327181613a23565b82525050565b61328861328382613a23565b613b6a565b82525050565b600061329982613930565b6132a38185613982565b93506132b3818560208601613ac2565b6132bc81613c99565b840191505092915050565b60006132d28261393b565b6132dc8185613993565b93506132ec818560208601613ac2565b6132f581613c99565b840191505092915050565b600061330b8261393b565b61331581856139a4565b9350613325818560208601613ac2565b80840191505092915050565b600061333e601883613993565b915061334982613cb7565b602082019050919050565b6000613361601183613993565b915061336c82613ce0565b602082019050919050565b6000613384601f83613993565b915061338f82613d09565b602082019050919050565b60006133a7601c836139a4565b91506133b282613d32565b601c82019050919050565b60006133ca602683613993565b91506133d582613d5b565b604082019050919050565b60006133ed600e83613993565b91506133f882613daa565b602082019050919050565b6000613410602283613993565b915061341b82613dd3565b604082019050919050565b6000613433602083613993565b915061343e82613e22565b602082019050919050565b6000613456601383613993565b915061346182613e4b565b602082019050919050565b6080820160008201516134826000850182613159565b506020820151613495602085018261355a565b5060408201516134a8604085018261324a565b5060608201516134bb6060850182613516565b50505050565b6080820160008201516134d76000850182613159565b5060208201516134ea602085018261355a565b5060408201516134fd604085018261324a565b5060608201516135106060850182613516565b50505050565b61351f81613a79565b82525050565b61352e81613a88565b82525050565b61353d81613a88565b82525050565b61355461354f82613a88565b613b86565b82525050565b61356381613a92565b82525050565b61357281613aa6565b82525050565b60006135848287613177565b6014820191506135948286613177565b6014820191506135a48285613543565b6020820191506135b48284613543565b60208201915081905095945050505050565b60006135d28285613300565b91506135de8284613300565b91508190509392505050565b60006135f58261339a565b91506136018284613277565b60208201915081905092915050565b60006020820190506136256000830184613168565b92915050565b60006080820190506136406000830187613168565b61364d6020830186613168565b61365a6040830185613534565b818103606083015261366c818461328e565b905095945050505050565b60006020820190508181036000830152613691818461318e565b905092915050565b600060208201905081810360008301526136b381846131ec565b905092915050565b60006020820190506136d06000830184613259565b92915050565b60006080820190506136eb6000830187613268565b6136f86020830186613569565b6137056040830185613268565b6137126060830184613268565b95945050505050565b6000602082019050818103600083015261373581846132c7565b905092915050565b6000602082019050818103600083015261375681613331565b9050919050565b6000602082019050818103600083015261377681613354565b9050919050565b6000602082019050818103600083015261379681613377565b9050919050565b600060208201905081810360008301526137b6816133bd565b9050919050565b600060208201905081810360008301526137d6816133e0565b9050919050565b600060208201905081810360008301526137f681613403565b9050919050565b6000602082019050818103600083015261381681613426565b9050919050565b6000602082019050818103600083015261383681613449565b9050919050565b600060808201905061385260008301846134c1565b92915050565b600060208201905061386d6000830184613534565b92915050565b600061387d61388e565b90506138898282613b27565b919050565b6000604051905090565b600067ffffffffffffffff8211156138b3576138b2613c4c565b5b6138bc82613c99565b9050602081019050919050565b600067ffffffffffffffff8211156138e4576138e3613c4c565b5b6138ed82613c99565b9050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b60006139ba82613a88565b91506139c583613a88565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156139fa576139f9613b90565b5b828201905092915050565b6000613a1082613a59565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062ffffff82169050919050565b6000819050919050565b600067ffffffffffffffff82169050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b83811015613ae0578082015181840152602081019050613ac5565b83811115613aef576000848401525b50505050565b60006002820490506001821680613b0d57607f821691505b60208210811415613b2157613b20613bee565b5b50919050565b613b3082613c99565b810181811067ffffffffffffffff82111715613b4f57613b4e613c4c565b5b80604052505050565b6000613b6382613b74565b9050919050565b6000819050919050565b6000613b7f82613caa565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b7f696e76616c6964207369676e6174757265000000000000000000000000000000600082015250565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f696e76616c696420616d6f756e74000000000000000000000000000000000000600082015250565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f73616c6573206973206e6f742061637469766500000000000000000000000000600082015250565b613e7d81613a05565b8114613e8857600080fd5b50565b613e9481613a17565b8114613e9f57600080fd5b50565b613eab81613a2d565b8114613eb657600080fd5b50565b613ec281613a88565b8114613ecd57600080fd5b5056fea2646970667358221220ee398dd6f5b84400b913bece98c23fc45508148cd2778f33d2248d215f4c81b364736f6c63430008070033
Deployed Bytecode Sourcemap
85262:2213:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43092:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43994:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50485:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49918:408;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85369:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39745:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54124:2825;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;86785:127;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57045:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85159:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87160:312;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86676:101;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;79863:528;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45387:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40929:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24740:103;;;;;;;;;;;;;:::i;:::-;;86920:107;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83739:900;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87035:117;;;;;;;;;;;;;:::i;:::-;;24092:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86551:117;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44170:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80779:2513;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51043:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57836:407;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;79276:428;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44380:318;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86082:111;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85686:388;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;86335:99;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51434:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86199:128;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24998:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43092:639;43177:4;43516:10;43501:25;;:11;:25;;;;:102;;;;43593:10;43578:25;;:11;:25;;;;43501:102;:179;;;;43670:10;43655:25;;:11;:25;;;;43501:179;43481:199;;43092:639;;;:::o;43994:100::-;44048:13;44081:5;44074:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43994:100;:::o;50485:218::-;50561:7;50586:16;50594:7;50586;:16::i;:::-;50581:64;;50611:34;;;;;;;;;;;;;;50581:64;50665:15;:24;50681:7;50665:24;;;;;;;;;;;:30;;;;;;;;;;;;50658:37;;50485:218;;;:::o;49918:408::-;50007:13;50023:16;50031:7;50023;:16::i;:::-;50007:32;;50079:5;50056:28;;:19;:17;:19::i;:::-;:28;;;50052:175;;50104:44;50121:5;50128:19;:17;:19::i;:::-;50104:16;:44::i;:::-;50099:128;;50176:35;;;;;;;;;;;;;;50099:128;50052:175;50272:2;50239:15;:24;50255:7;50239:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;50310:7;50306:2;50290:28;;50299:5;50290:28;;;;;;;;;;;;49996:330;49918:408;;:::o;85369:39::-;;;;:::o;39745:323::-;39806:7;40034:15;:13;:15::i;:::-;40019:12;;40003:13;;:28;:46;39996:53;;39745:323;:::o;54124:2825::-;54266:27;54296;54315:7;54296:18;:27::i;:::-;54266:57;;54381:4;54340:45;;54356:19;54340:45;;;54336:86;;54394:28;;;;;;;;;;;;;;54336:86;54436:27;54465:23;54492:35;54519:7;54492:26;:35::i;:::-;54435:92;;;;54627:68;54652:15;54669:4;54675:19;:17;:19::i;:::-;54627:24;:68::i;:::-;54622:180;;54715:43;54732:4;54738:19;:17;:19::i;:::-;54715:16;:43::i;:::-;54710:92;;54767:35;;;;;;;;;;;;;;54710:92;54622:180;54833:1;54819:16;;:2;:16;;;54815:52;;;54844:23;;;;;;;;;;;;;;54815:52;54880:43;54902:4;54908:2;54912:7;54921:1;54880:21;:43::i;:::-;55016:15;55013:160;;;55156:1;55135:19;55128:30;55013:160;55553:18;:24;55572:4;55553:24;;;;;;;;;;;;;;;;55551:26;;;;;;;;;;;;55622:18;:22;55641:2;55622:22;;;;;;;;;;;;;;;;55620:24;;;;;;;;;;;55944:146;55981:2;56030:45;56045:4;56051:2;56055:19;56030:14;:45::i;:::-;36144:8;56002:73;55944:18;:146::i;:::-;55915:17;:26;55933:7;55915:26;;;;;;;;;;;:175;;;;56261:1;36144:8;56210:19;:47;:52;56206:627;;;56283:19;56315:1;56305:7;:11;56283:33;;56472:1;56438:17;:30;56456:11;56438:30;;;;;;;;;;;;:35;56434:384;;;56576:13;;56561:11;:28;56557:242;;56756:19;56723:17;:30;56741:11;56723:30;;;;;;;;;;;:52;;;;56557:242;56434:384;56264:569;56206:627;56880:7;56876:2;56861:27;;56870:4;56861:27;;;;;;;;;;;;56899:42;56920:4;56926:2;56930:7;56939:1;56899:20;:42::i;:::-;54255:2694;;;54124:2825;;;:::o;86785:127::-;23978:13;:11;:13::i;:::-;86888:16:::1;86869;;:35;;;;;;;;;;;;;;;;;;86785:127:::0;:::o;57045:193::-;57191:39;57208:4;57214:2;57218:7;57191:39;;;;;;;;;;;;:16;:39::i;:::-;57045:193;;;:::o;85159:94::-;85225:20;85231:7;85240:4;85225:5;:20::i;:::-;85159:94;:::o;87160:312::-;87261:7;87280:19;87337:4;87343:7;87352:20;:29;87373:7;87352:29;;;;;;;;;;;;;;;;87382:6;87312:77;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;87302:88;;;;;;87280:110;;87408:56;87453:10;87408:36;:11;:34;:36::i;:::-;:44;;:56;;;;:::i;:::-;87401:63;;;87160:312;;;;;:::o;86676:101::-;23978:13;:11;:13::i;:::-;86761:8:::1;86750;:19;;;;;;;;;;;;:::i;:::-;;86676:101:::0;:::o;79863:528::-;80007:23;80073:22;80098:8;;:15;;80073:40;;80128:34;80186:14;80165:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;80128:73;;80221:9;80216:125;80237:14;80232:1;:19;80216:125;;80293:32;80313:8;;80322:1;80313:11;;;;;;;:::i;:::-;;;;;;;;80293:19;:32::i;:::-;80277:10;80288:1;80277:13;;;;;;;;:::i;:::-;;;;;;;:48;;;;80253:3;;;;;80216:125;;;;80362:10;80355:17;;;;79863:528;;;;:::o;45387:152::-;45459:7;45502:27;45521:7;45502:18;:27::i;:::-;45479:52;;45387:152;;;:::o;40929:233::-;41001:7;41042:1;41025:19;;:5;:19;;;41021:60;;;41053:28;;;;;;;;;;;;;;41021:60;35088:13;41099:18;:25;41118:5;41099:25;;;;;;;;;;;;;;;;:55;41092:62;;40929:233;;;:::o;24740:103::-;23978:13;:11;:13::i;:::-;24805:30:::1;24832:1;24805:18;:30::i;:::-;24740:103::o:0;86920:107::-;23978:13;:11;:13::i;:::-;87010:9:::1;86993:14;:26;;;;86920:107:::0;:::o;83739:900::-;83817:16;83871:19;83905:25;83945:22;83970:16;83980:5;83970:9;:16::i;:::-;83945:41;;84001:25;84043:14;84029:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84001:57;;84073:31;;:::i;:::-;84124:9;84136:15;:13;:15::i;:::-;84124:27;;84119:472;84168:14;84153:11;:29;84119:472;;84220:15;84233:1;84220:12;:15::i;:::-;84208:27;;84258:9;:16;;;84254:73;;;84299:8;;84254:73;84375:1;84349:28;;:9;:14;;;:28;;;84345:111;;84422:9;:14;;;84402:34;;84345:111;84499:5;84478:26;;:17;:26;;;84474:102;;;84555:1;84529:8;84538:13;;;;;;84529:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;84474:102;84119:472;84184:3;;;;;84119:472;;;;84612:8;84605:15;;;;;;;83739:900;;;:::o;87035:117::-;23978:13;:11;:13::i;:::-;87104:10:::1;87096:24;;:47;87121:21;87096:47;;;;;;;;;;;;;;;;;;;;;;;87088:56;;;::::0;::::1;;87035:117::o:0;24092:87::-;24138:7;24165:6;;;;;;;;;;;24158:13;;24092:87;:::o;86551:117::-;23978:13;:11;:13::i;:::-;86648:12:::1;86633;:27;;;;;;;;;;;;:::i;:::-;;86551:117:::0;:::o;44170:104::-;44226:13;44259:7;44252:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44170:104;:::o;80779:2513::-;80922:16;80989:4;80980:5;:13;80976:45;;81002:19;;;;;;;;;;;;;;80976:45;81036:19;81070:17;81090:14;:12;:14::i;:::-;81070:34;;81190:15;:13;:15::i;:::-;81182:5;:23;81178:87;;;81234:15;:13;:15::i;:::-;81226:23;;81178:87;81341:9;81334:4;:16;81330:73;;;81378:9;81371:16;;81330:73;81417:25;81445:16;81455:5;81445:9;:16::i;:::-;81417:44;;81639:4;81631:5;:12;81627:278;;;81664:19;81693:5;81686:4;:12;81664:34;;81735:17;81721:11;:31;81717:111;;;81797:11;81777:31;;81717:111;81645:198;81627:278;;;81888:1;81868:21;;81627:278;81919:25;81961:17;81947:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81919:60;;82019:1;81998:17;:22;81994:78;;;82048:8;82041:15;;;;;;;;81994:78;82216:31;82250:26;82270:5;82250:19;:26::i;:::-;82216:60;;82291:25;82536:9;:16;;;82531:92;;82593:9;:14;;;82573:34;;82531:92;82642:9;82654:5;82642:17;;82637:478;82666:4;82661:1;:9;;:45;;;;;82689:17;82674:11;:32;;82661:45;82637:478;;;82744:15;82757:1;82744:12;:15::i;:::-;82732:27;;82782:9;:16;;;82778:73;;;82823:8;;82778:73;82899:1;82873:28;;:9;:14;;;:28;;;82869:111;;82946:9;:14;;;82926:34;;82869:111;83023:5;83002:26;;:17;:26;;;82998:102;;;83079:1;83053:8;83062:13;;;;;;83053:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;82998:102;82637:478;82708:3;;;;;82637:478;;;;83217:11;83207:8;83200:29;83265:8;83258:15;;;;;;;;80779:2513;;;;;;:::o;51043:234::-;51190:8;51138:18;:39;51157:19;:17;:19::i;:::-;51138:39;;;;;;;;;;;;;;;:49;51178:8;51138:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;51250:8;51214:55;;51229:19;:17;:19::i;:::-;51214:55;;;51260:8;51214:55;;;;;;:::i;:::-;;;;;;;;51043:234;;:::o;57836:407::-;58011:31;58024:4;58030:2;58034:7;58011:12;:31::i;:::-;58075:1;58057:2;:14;;;:19;58053:183;;58096:56;58127:4;58133:2;58137:7;58146:5;58096:30;:56::i;:::-;58091:145;;58180:40;;;;;;;;;;;;;;58091:145;58053:183;57836:407;;;;:::o;79276:428::-;79360:21;;:::i;:::-;79394:31;;:::i;:::-;79450:15;:13;:15::i;:::-;79440:7;:25;:54;;;;79480:14;:12;:14::i;:::-;79469:7;:25;;79440:54;79436:103;;;79518:9;79511:16;;;;;79436:103;79561:21;79574:7;79561:12;:21::i;:::-;79549:33;;79597:9;:16;;;79593:65;;;79637:9;79630:16;;;;;79593:65;79675:21;79688:7;79675:12;:21::i;:::-;79668:28;;;79276:428;;;;:::o;44380:318::-;44453:13;44484:16;44492:7;44484;:16::i;:::-;44479:59;;44509:29;;;;;;;;;;;;;;44479:59;44551:21;44575:10;:8;:10::i;:::-;44551:34;;44628:1;44609:7;44603:21;:26;;:87;;;;;;;;;;;;;;;;;44656:7;44665:18;44675:7;44665:9;:18::i;:::-;44639:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;44603:87;44596:94;;;44380:318;;;:::o;86082:111::-;86128:4;86170:15;86152:14;;:33;;86145:40;;86082:111;:::o;85686:388::-;85826:16;;;;;;;;;;;85778:64;;:44;85794:9;;85778:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85804:10;85815:6;85778:15;:44::i;:::-;:64;;;85769:96;;;;;;;;;;;;:::i;:::-;;;;;;;;;85884:15;:13;:15::i;:::-;85876:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;85951:1;85942:6;:10;85934:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;86020:6;85984:20;:32;86005:10;85984:32;;;;;;;;;;;;;;;;:42;;;;;;;:::i;:::-;;;;;;;;86037:29;86047:10;86059:6;86037:9;:29::i;:::-;85686:388;;;:::o;86335:99::-;86381:13;86414:12;86407:19;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86335:99;:::o;51434:164::-;51531:4;51555:18;:25;51574:5;51555:25;;;;;;;;;;;;;;;:35;51581:8;51555:35;;;;;;;;;;;;;;;;;;;;;;;;;51548:42;;51434:164;;;;:::o;86199:128::-;86266:4;86290:20;:29;86311:7;86290:29;;;;;;;;;;;;;;;;86283:36;;86199:128;;;:::o;24998:201::-;23978:13;:11;:13::i;:::-;25107:1:::1;25087:22;;:8;:22;;;;25079:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;25163:28;25182:8;25163:18;:28::i;:::-;24998:201:::0;:::o;51856:282::-;51921:4;51977:7;51958:15;:13;:15::i;:::-;:26;;:66;;;;;52011:13;;52001:7;:23;51958:66;:153;;;;;52110:1;35864:8;52062:17;:26;52080:7;52062:26;;;;;;;;;;;;:44;:49;51958:153;51938:173;;51856:282;;;:::o;74164:105::-;74224:7;74251:10;74244:17;;74164:105;:::o;39261:92::-;39317:7;39261:92;:::o;46542:1275::-;46609:7;46629:12;46644:7;46629:22;;46712:4;46693:15;:13;:15::i;:::-;:23;46689:1061;;46746:13;;46739:4;:20;46735:1015;;;46784:14;46801:17;:23;46819:4;46801:23;;;;;;;;;;;;46784:40;;46918:1;35864:8;46890:6;:24;:29;46886:845;;;47555:113;47572:1;47562:6;:11;47555:113;;;47615:17;:25;47633:6;;;;;;;47615:25;;;;;;;;;;;;47606:34;;47555:113;;;47701:6;47694:13;;;;;;46886:845;46761:989;46735:1015;46689:1061;47778:31;;;;;;;;;;;;;;46542:1275;;;;:::o;53019:485::-;53121:27;53150:23;53191:38;53232:15;:24;53248:7;53232:24;;;;;;;;;;;53191:65;;53409:18;53386:41;;53466:19;53460:26;53441:45;;53371:126;53019:485;;;:::o;52247:659::-;52396:11;52561:16;52554:5;52550:28;52541:37;;52721:16;52710:9;52706:32;52693:45;;52871:15;52860:9;52857:30;52849:5;52838:9;52835:20;52832:56;52822:66;;52247:659;;;;;:::o;58905:159::-;;;;;:::o;73473:311::-;73608:7;73628:16;36268:3;73654:19;:41;;73628:68;;36268:3;73722:31;73733:4;73739:2;73743:9;73722:10;:31::i;:::-;73714:40;;:62;;73707:69;;;73473:311;;;;;:::o;48365:450::-;48445:14;48613:16;48606:5;48602:28;48593:37;;48790:5;48776:11;48751:23;48747:41;48744:52;48737:5;48734:63;48724:73;;48365:450;;;;:::o;59729:158::-;;;;;:::o;24257:132::-;24332:12;:10;:12::i;:::-;24321:23;;:7;:5;:7::i;:::-;:23;;;24313:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;24257:132::o;68693:3081::-;68773:27;68803;68822:7;68803:18;:27::i;:::-;68773:57;;68843:12;68874:19;68843:52;;68909:27;68938:23;68965:35;68992:7;68965:26;:35::i;:::-;68908:92;;;;69017:13;69013:316;;;69138:68;69163:15;69180:4;69186:19;:17;:19::i;:::-;69138:24;:68::i;:::-;69133:184;;69230:43;69247:4;69253:19;:17;:19::i;:::-;69230:16;:43::i;:::-;69225:92;;69282:35;;;;;;;;;;;;;;69225:92;69133:184;69013:316;69341:51;69363:4;69377:1;69381:7;69390:1;69341:21;:51::i;:::-;69485:15;69482:160;;;69625:1;69604:19;69597:30;69482:160;70303:1;35353:3;70273:1;:26;;70272:32;70244:18;:24;70263:4;70244:24;;;;;;;;;;;;;;;;:60;;;;;;;;;;;70571:176;70608:4;70679:53;70694:4;70708:1;70712:19;70679:14;:53::i;:::-;36144:8;35864;70632:43;70631:101;70571:18;:176::i;:::-;70542:17;:26;70560:7;70542:26;;;;;;;;;;;:205;;;;70918:1;36144:8;70867:19;:47;:52;70863:627;;;70940:19;70972:1;70962:7;:11;70940:33;;71129:1;71095:17;:30;71113:11;71095:30;;;;;;;;;;;;:35;71091:384;;;71233:13;;71218:11;:28;71214:242;;71413:19;71380:17;:30;71398:11;71380:30;;;;;;;;;;;:52;;;;71214:242;71091:384;70921:569;70863:627;71545:7;71541:1;71518:35;;71527:4;71518:35;;;;;;;;;;;;71564:50;71585:4;71599:1;71603:7;71612:1;71564:20;:50::i;:::-;71741:12;;:14;;;;;;;;;;;;;68762:3012;;;;68693:3081;;:::o;21960:269::-;22029:7;22215:4;22162:58;;;;;;;;:::i;:::-;;;;;;;;;;;;;22152:69;;;;;;22145:76;;21960:269;;;:::o;18270:231::-;18348:7;18369:17;18388:18;18410:27;18421:4;18427:9;18410:10;:27::i;:::-;18368:69;;;;18448:18;18460:5;18448:11;:18::i;:::-;18484:9;18477:16;;;;18270:231;;;;:::o;25359:191::-;25433:16;25452:6;;;;;;;;;;;25433:25;;25478:8;25469:6;;:17;;;;;;;;;;;;;;;;;;25533:8;25502:40;;25523:8;25502:40;;;;;;;;;;;;25422:128;25359:191;:::o;45990:161::-;46058:21;;:::i;:::-;46099:44;46118:17;:24;46136:5;46118:24;;;;;;;;;;;;46099:18;:44::i;:::-;46092:51;;45990:161;;;:::o;39432:103::-;39487:7;39514:13;;39507:20;;39432:103;:::o;60327:716::-;60490:4;60536:2;60511:45;;;60557:19;:17;:19::i;:::-;60578:4;60584:7;60593:5;60511:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;60507:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60811:1;60794:6;:13;:18;60790:235;;;60840:40;;;;;;;;;;;;;;60790:235;60983:6;60977:13;60968:6;60964:2;60960:15;60953:38;60507:529;60680:54;;;60670:64;;;:6;:64;;;;60663:71;;;60327:716;;;;;;:::o;45728:166::-;45798:21;;:::i;:::-;45839:47;45858:27;45877:7;45858:18;:27::i;:::-;45839:18;:47::i;:::-;45832:54;;45728:166;;;:::o;86442:101::-;86494:13;86527:8;86520:15;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86442:101;:::o;74371:1745::-;74436:17;74870:4;74863;74857:11;74853:22;74962:1;74956:4;74949:15;75037:4;75034:1;75030:12;75023:19;;75119:1;75114:3;75107:14;75223:3;75462:5;75444:428;75470:1;75444:428;;;75510:1;75505:3;75501:11;75494:18;;75681:2;75675:4;75671:13;75667:2;75663:22;75658:3;75650:36;75775:2;75769:4;75765:13;75757:21;;75842:4;75832:25;;75850:5;;75832:25;75444:428;;;75448:21;75911:3;75906;75902:13;76026:4;76021:3;76017:14;76010:21;;76091:6;76086:3;76079:19;74475:1634;;;74371:1745;;;:::o;67996:112::-;68073:27;68083:2;68087:8;68073:27;;;;;;;;;;;;:9;:27::i;:::-;67996:112;;:::o;73174:147::-;73311:6;73174:147;;;;;:::o;23308:98::-;23361:7;23388:10;23381:17;;23308:98;:::o;16721:747::-;16802:7;16811:12;16860:2;16840:9;:16;:22;16836:625;;;16879:9;16903;16927:7;17184:4;17173:9;17169:20;17163:27;17158:32;;17234:4;17223:9;17219:20;17213:27;17208:32;;17292:4;17281:9;17277:20;17271:27;17268:1;17263:36;17258:41;;17335:25;17346:4;17352:1;17355;17358;17335:10;:25::i;:::-;17328:32;;;;;;;;;16836:625;17409:1;17413:35;17393:56;;;;16721:747;;;;;;:::o;15114:521::-;15192:20;15183:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;15179:449;;;15229:7;;15179:449;15290:29;15281:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;15277:351;;;15336:34;;;;;;;;;;:::i;:::-;;;;;;;;15277:351;15401:35;15392:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;15388:240;;;15453:41;;;;;;;;;;:::i;:::-;;;;;;;;15388:240;15525:30;15516:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;15512:116;;;15572:44;;;;;;;;;;:::i;:::-;;;;;;;;15512:116;15114:521;;:::o;47916:366::-;47982:31;;:::i;:::-;48059:6;48026:9;:14;;:41;;;;;;;;;;;35747:3;48112:6;:33;;48078:9;:24;;:68;;;;;;;;;;;48204:1;35864:8;48176:6;:24;:29;;48157:9;:16;;:48;;;;;;;;;;;36268:3;48245:6;:28;;48216:9;:19;;:58;;;;;;;;;;;47916:366;;;:::o;67223:689::-;67354:19;67360:2;67364:8;67354:5;:19::i;:::-;67433:1;67415:2;:14;;;:19;67411:483;;67455:11;67469:13;;67455:27;;67501:13;67523:8;67517:3;:14;67501:30;;67550:233;67581:62;67620:1;67624:2;67628:7;;;;;;67637:5;67581:30;:62::i;:::-;67576:167;;67679:40;;;;;;;;;;;;;;67576:167;67778:3;67770:5;:11;67550:233;;67865:3;67848:13;;:20;67844:34;;67870:8;;;67844:34;67436:458;;67411:483;67223:689;;;:::o;19722:1520::-;19853:7;19862:12;20787:66;20782:1;20774:10;;:79;20770:163;;;20886:1;20890:30;20870:51;;;;;;20770:163;21030:14;21047:24;21057:4;21063:1;21066;21069;21047:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21030:41;;21104:1;21086:20;;:6;:20;;;21082:103;;;21139:1;21143:29;21123:50;;;;;;;21082:103;21205:6;21213:20;21197:37;;;;;19722:1520;;;;;;;;:::o;61505:2966::-;61578:20;61601:13;;61578:36;;61641:1;61629:8;:13;61625:44;;;61651:18;;;;;;;;;;;;;;61625:44;61682:61;61712:1;61716:2;61720:12;61734:8;61682:21;:61::i;:::-;62226:1;35226:2;62196:1;:26;;62195:32;62183:8;:45;62157:18;:22;62176:2;62157:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;62505:139;62542:2;62596:33;62619:1;62623:2;62627:1;62596:14;:33::i;:::-;62563:30;62584:8;62563:20;:30::i;:::-;:66;62505:18;:139::i;:::-;62471:17;:31;62489:12;62471:31;;;;;;;;;;;:173;;;;62661:16;62692:11;62721:8;62706:12;:23;62692:37;;63242:16;63238:2;63234:25;63222:37;;63614:12;63574:8;63533:1;63471:25;63412:1;63351;63324:335;63985:1;63971:12;63967:20;63925:346;64026:3;64017:7;64014:16;63925:346;;64244:7;64234:8;64231:1;64204:25;64201:1;64198;64193:59;64079:1;64070:7;64066:15;64055:26;;63925:346;;;63929:77;64316:1;64304:8;:13;64300:45;;;64326:19;;;;;;;;;;;;;;64300:45;64378:3;64362:13;:19;;;;61931:2462;;64403:60;64432:1;64436:2;64440:12;64454:8;64403:20;:60::i;:::-;61567:2904;61505:2966;;:::o;48917:324::-;48987:14;49220:1;49210:8;49207:15;49181:24;49177:46;49167:56;;48917:324;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:410:1:-;84:5;109:65;125:48;166:6;125:48;:::i;:::-;109:65;:::i;:::-;100:74;;197:6;190:5;183:21;235:4;228:5;224:16;273:3;264:6;259:3;255:16;252:25;249:112;;;280:79;;:::i;:::-;249:112;370:41;404:6;399:3;394;370:41;:::i;:::-;90:327;7:410;;;;;:::o;423:412::-;501:5;526:66;542:49;584:6;542:49;:::i;:::-;526:66;:::i;:::-;517:75;;615:6;608:5;601:21;653:4;646:5;642:16;691:3;682:6;677:3;673:16;670:25;667:112;;;698:79;;:::i;:::-;667:112;788:41;822:6;817:3;812;788:41;:::i;:::-;507:328;423:412;;;;;:::o;841:139::-;887:5;925:6;912:20;903:29;;941:33;968:5;941:33;:::i;:::-;841:139;;;;:::o;1003:568::-;1076:8;1086:6;1136:3;1129:4;1121:6;1117:17;1113:27;1103:122;;1144:79;;:::i;:::-;1103:122;1257:6;1244:20;1234:30;;1287:18;1279:6;1276:30;1273:117;;;1309:79;;:::i;:::-;1273:117;1423:4;1415:6;1411:17;1399:29;;1477:3;1469:4;1461:6;1457:17;1447:8;1443:32;1440:41;1437:128;;;1484:79;;:::i;:::-;1437:128;1003:568;;;;;:::o;1577:133::-;1620:5;1658:6;1645:20;1636:29;;1674:30;1698:5;1674:30;:::i;:::-;1577:133;;;;:::o;1716:137::-;1761:5;1799:6;1786:20;1777:29;;1815:32;1841:5;1815:32;:::i;:::-;1716:137;;;;:::o;1859:141::-;1915:5;1946:6;1940:13;1931:22;;1962:32;1988:5;1962:32;:::i;:::-;1859:141;;;;:::o;2019:552::-;2076:8;2086:6;2136:3;2129:4;2121:6;2117:17;2113:27;2103:122;;2144:79;;:::i;:::-;2103:122;2257:6;2244:20;2234:30;;2287:18;2279:6;2276:30;2273:117;;;2309:79;;:::i;:::-;2273:117;2423:4;2415:6;2411:17;2399:29;;2477:3;2469:4;2461:6;2457:17;2447:8;2443:32;2440:41;2437:128;;;2484:79;;:::i;:::-;2437:128;2019:552;;;;;:::o;2590:338::-;2645:5;2694:3;2687:4;2679:6;2675:17;2671:27;2661:122;;2702:79;;:::i;:::-;2661:122;2819:6;2806:20;2844:78;2918:3;2910:6;2903:4;2895:6;2891:17;2844:78;:::i;:::-;2835:87;;2651:277;2590:338;;;;:::o;2948:340::-;3004:5;3053:3;3046:4;3038:6;3034:17;3030:27;3020:122;;3061:79;;:::i;:::-;3020:122;3178:6;3165:20;3203:79;3278:3;3270:6;3263:4;3255:6;3251:17;3203:79;:::i;:::-;3194:88;;3010:278;2948:340;;;;:::o;3294:139::-;3340:5;3378:6;3365:20;3356:29;;3394:33;3421:5;3394:33;:::i;:::-;3294:139;;;;:::o;3439:329::-;3498:6;3547:2;3535:9;3526:7;3522:23;3518:32;3515:119;;;3553:79;;:::i;:::-;3515:119;3673:1;3698:53;3743:7;3734:6;3723:9;3719:22;3698:53;:::i;:::-;3688:63;;3644:117;3439:329;;;;:::o;3774:474::-;3842:6;3850;3899:2;3887:9;3878:7;3874:23;3870:32;3867:119;;;3905:79;;:::i;:::-;3867:119;4025:1;4050:53;4095:7;4086:6;4075:9;4071:22;4050:53;:::i;:::-;4040:63;;3996:117;4152:2;4178:53;4223:7;4214:6;4203:9;4199:22;4178:53;:::i;:::-;4168:63;;4123:118;3774:474;;;;;:::o;4254:619::-;4331:6;4339;4347;4396:2;4384:9;4375:7;4371:23;4367:32;4364:119;;;4402:79;;:::i;:::-;4364:119;4522:1;4547:53;4592:7;4583:6;4572:9;4568:22;4547:53;:::i;:::-;4537:63;;4493:117;4649:2;4675:53;4720:7;4711:6;4700:9;4696:22;4675:53;:::i;:::-;4665:63;;4620:118;4777:2;4803:53;4848:7;4839:6;4828:9;4824:22;4803:53;:::i;:::-;4793:63;;4748:118;4254:619;;;;;:::o;4879:943::-;4974:6;4982;4990;4998;5047:3;5035:9;5026:7;5022:23;5018:33;5015:120;;;5054:79;;:::i;:::-;5015:120;5174:1;5199:53;5244:7;5235:6;5224:9;5220:22;5199:53;:::i;:::-;5189:63;;5145:117;5301:2;5327:53;5372:7;5363:6;5352:9;5348:22;5327:53;:::i;:::-;5317:63;;5272:118;5429:2;5455:53;5500:7;5491:6;5480:9;5476:22;5455:53;:::i;:::-;5445:63;;5400:118;5585:2;5574:9;5570:18;5557:32;5616:18;5608:6;5605:30;5602:117;;;5638:79;;:::i;:::-;5602:117;5743:62;5797:7;5788:6;5777:9;5773:22;5743:62;:::i;:::-;5733:72;;5528:287;4879:943;;;;;;;:::o;5828:468::-;5893:6;5901;5950:2;5938:9;5929:7;5925:23;5921:32;5918:119;;;5956:79;;:::i;:::-;5918:119;6076:1;6101:53;6146:7;6137:6;6126:9;6122:22;6101:53;:::i;:::-;6091:63;;6047:117;6203:2;6229:50;6271:7;6262:6;6251:9;6247:22;6229:50;:::i;:::-;6219:60;;6174:115;5828:468;;;;;:::o;6302:474::-;6370:6;6378;6427:2;6415:9;6406:7;6402:23;6398:32;6395:119;;;6433:79;;:::i;:::-;6395:119;6553:1;6578:53;6623:7;6614:6;6603:9;6599:22;6578:53;:::i;:::-;6568:63;;6524:117;6680:2;6706:53;6751:7;6742:6;6731:9;6727:22;6706:53;:::i;:::-;6696:63;;6651:118;6302:474;;;;;:::o;6782:619::-;6859:6;6867;6875;6924:2;6912:9;6903:7;6899:23;6895:32;6892:119;;;6930:79;;:::i;:::-;6892:119;7050:1;7075:53;7120:7;7111:6;7100:9;7096:22;7075:53;:::i;:::-;7065:63;;7021:117;7177:2;7203:53;7248:7;7239:6;7228:9;7224:22;7203:53;:::i;:::-;7193:63;;7148:118;7305:2;7331:53;7376:7;7367:6;7356:9;7352:22;7331:53;:::i;:::-;7321:63;;7276:118;6782:619;;;;;:::o;7407:559::-;7493:6;7501;7550:2;7538:9;7529:7;7525:23;7521:32;7518:119;;;7556:79;;:::i;:::-;7518:119;7704:1;7693:9;7689:17;7676:31;7734:18;7726:6;7723:30;7720:117;;;7756:79;;:::i;:::-;7720:117;7869:80;7941:7;7932:6;7921:9;7917:22;7869:80;:::i;:::-;7851:98;;;;7647:312;7407:559;;;;;:::o;7972:327::-;8030:6;8079:2;8067:9;8058:7;8054:23;8050:32;8047:119;;;8085:79;;:::i;:::-;8047:119;8205:1;8230:52;8274:7;8265:6;8254:9;8250:22;8230:52;:::i;:::-;8220:62;;8176:116;7972:327;;;;:::o;8305:349::-;8374:6;8423:2;8411:9;8402:7;8398:23;8394:32;8391:119;;;8429:79;;:::i;:::-;8391:119;8549:1;8574:63;8629:7;8620:6;8609:9;8605:22;8574:63;:::i;:::-;8564:73;;8520:127;8305:349;;;;:::o;8660:797::-;8746:6;8754;8762;8811:2;8799:9;8790:7;8786:23;8782:32;8779:119;;;8817:79;;:::i;:::-;8779:119;8965:1;8954:9;8950:17;8937:31;8995:18;8987:6;8984:30;8981:117;;;9017:79;;:::i;:::-;8981:117;9122:62;9176:7;9167:6;9156:9;9152:22;9122:62;:::i;:::-;9112:72;;8908:286;9233:2;9259:53;9304:7;9295:6;9284:9;9280:22;9259:53;:::i;:::-;9249:63;;9204:118;9361:2;9387:53;9432:7;9423:6;9412:9;9408:22;9387:53;:::i;:::-;9377:63;;9332:118;8660:797;;;;;:::o;9463:509::-;9532:6;9581:2;9569:9;9560:7;9556:23;9552:32;9549:119;;;9587:79;;:::i;:::-;9549:119;9735:1;9724:9;9720:17;9707:31;9765:18;9757:6;9754:30;9751:117;;;9787:79;;:::i;:::-;9751:117;9892:63;9947:7;9938:6;9927:9;9923:22;9892:63;:::i;:::-;9882:73;;9678:287;9463:509;;;;:::o;9978:329::-;10037:6;10086:2;10074:9;10065:7;10061:23;10057:32;10054:119;;;10092:79;;:::i;:::-;10054:119;10212:1;10237:53;10282:7;10273:6;10262:9;10258:22;10237:53;:::i;:::-;10227:63;;10183:117;9978:329;;;;:::o;10313:672::-;10392:6;10400;10408;10457:2;10445:9;10436:7;10432:23;10428:32;10425:119;;;10463:79;;:::i;:::-;10425:119;10583:1;10608:53;10653:7;10644:6;10633:9;10629:22;10608:53;:::i;:::-;10598:63;;10554:117;10738:2;10727:9;10723:18;10710:32;10769:18;10761:6;10758:30;10755:117;;;10791:79;;:::i;:::-;10755:117;10904:64;10960:7;10951:6;10940:9;10936:22;10904:64;:::i;:::-;10886:82;;;;10681:297;10313:672;;;;;:::o;10991:307::-;11124:10;11145:110;11251:3;11243:6;11145:110;:::i;:::-;11287:4;11282:3;11278:14;11264:28;;10991:307;;;;:::o;11304:179::-;11373:10;11394:46;11436:3;11428:6;11394:46;:::i;:::-;11472:4;11467:3;11463:14;11449:28;;11304:179;;;;:::o;11489:108::-;11566:24;11584:5;11566:24;:::i;:::-;11561:3;11554:37;11489:108;;:::o;11603:118::-;11690:24;11708:5;11690:24;:::i;:::-;11685:3;11678:37;11603:118;;:::o;11727:157::-;11832:45;11852:24;11870:5;11852:24;:::i;:::-;11832:45;:::i;:::-;11827:3;11820:58;11727:157;;:::o;11966:988::-;12149:3;12178:86;12258:5;12178:86;:::i;:::-;12280:118;12391:6;12386:3;12280:118;:::i;:::-;12273:125;;12422:88;12504:5;12422:88;:::i;:::-;12533:7;12564:1;12549:380;12574:6;12571:1;12568:13;12549:380;;;12650:6;12644:13;12677:127;12800:3;12785:13;12677:127;:::i;:::-;12670:134;;12827:92;12912:6;12827:92;:::i;:::-;12817:102;;12609:320;12596:1;12593;12589:9;12584:14;;12549:380;;;12553:14;12945:3;12938:10;;12154:800;;;11966:988;;;;:::o;12990:732::-;13109:3;13138:54;13186:5;13138:54;:::i;:::-;13208:86;13287:6;13282:3;13208:86;:::i;:::-;13201:93;;13318:56;13368:5;13318:56;:::i;:::-;13397:7;13428:1;13413:284;13438:6;13435:1;13432:13;13413:284;;;13514:6;13508:13;13541:63;13600:3;13585:13;13541:63;:::i;:::-;13534:70;;13627:60;13680:6;13627:60;:::i;:::-;13617:70;;13473:224;13460:1;13457;13453:9;13448:14;;13413:284;;;13417:14;13713:3;13706:10;;13114:608;;;12990:732;;;;:::o;13728:99::-;13799:21;13814:5;13799:21;:::i;:::-;13794:3;13787:34;13728:99;;:::o;13833:109::-;13914:21;13929:5;13914:21;:::i;:::-;13909:3;13902:34;13833:109;;:::o;13948:118::-;14035:24;14053:5;14035:24;:::i;:::-;14030:3;14023:37;13948:118;;:::o;14072:157::-;14177:45;14197:24;14215:5;14197:24;:::i;:::-;14177:45;:::i;:::-;14172:3;14165:58;14072:157;;:::o;14235:360::-;14321:3;14349:38;14381:5;14349:38;:::i;:::-;14403:70;14466:6;14461:3;14403:70;:::i;:::-;14396:77;;14482:52;14527:6;14522:3;14515:4;14508:5;14504:16;14482:52;:::i;:::-;14559:29;14581:6;14559:29;:::i;:::-;14554:3;14550:39;14543:46;;14325:270;14235:360;;;;:::o;14601:364::-;14689:3;14717:39;14750:5;14717:39;:::i;:::-;14772:71;14836:6;14831:3;14772:71;:::i;:::-;14765:78;;14852:52;14897:6;14892:3;14885:4;14878:5;14874:16;14852:52;:::i;:::-;14929:29;14951:6;14929:29;:::i;:::-;14924:3;14920:39;14913:46;;14693:272;14601:364;;;;:::o;14971:377::-;15077:3;15105:39;15138:5;15105:39;:::i;:::-;15160:89;15242:6;15237:3;15160:89;:::i;:::-;15153:96;;15258:52;15303:6;15298:3;15291:4;15284:5;15280:16;15258:52;:::i;:::-;15335:6;15330:3;15326:16;15319:23;;15081:267;14971:377;;;;:::o;15354:366::-;15496:3;15517:67;15581:2;15576:3;15517:67;:::i;:::-;15510:74;;15593:93;15682:3;15593:93;:::i;:::-;15711:2;15706:3;15702:12;15695:19;;15354:366;;;:::o;15726:::-;15868:3;15889:67;15953:2;15948:3;15889:67;:::i;:::-;15882:74;;15965:93;16054:3;15965:93;:::i;:::-;16083:2;16078:3;16074:12;16067:19;;15726:366;;;:::o;16098:::-;16240:3;16261:67;16325:2;16320:3;16261:67;:::i;:::-;16254:74;;16337:93;16426:3;16337:93;:::i;:::-;16455:2;16450:3;16446:12;16439:19;;16098:366;;;:::o;16470:402::-;16630:3;16651:85;16733:2;16728:3;16651:85;:::i;:::-;16644:92;;16745:93;16834:3;16745:93;:::i;:::-;16863:2;16858:3;16854:12;16847:19;;16470:402;;;:::o;16878:366::-;17020:3;17041:67;17105:2;17100:3;17041:67;:::i;:::-;17034:74;;17117:93;17206:3;17117:93;:::i;:::-;17235:2;17230:3;17226:12;17219:19;;16878:366;;;:::o;17250:::-;17392:3;17413:67;17477:2;17472:3;17413:67;:::i;:::-;17406:74;;17489:93;17578:3;17489:93;:::i;:::-;17607:2;17602:3;17598:12;17591:19;;17250:366;;;:::o;17622:::-;17764:3;17785:67;17849:2;17844:3;17785:67;:::i;:::-;17778:74;;17861:93;17950:3;17861:93;:::i;:::-;17979:2;17974:3;17970:12;17963:19;;17622:366;;;:::o;17994:::-;18136:3;18157:67;18221:2;18216:3;18157:67;:::i;:::-;18150:74;;18233:93;18322:3;18233:93;:::i;:::-;18351:2;18346:3;18342:12;18335:19;;17994:366;;;:::o;18366:::-;18508:3;18529:67;18593:2;18588:3;18529:67;:::i;:::-;18522:74;;18605:93;18694:3;18605:93;:::i;:::-;18723:2;18718:3;18714:12;18707:19;;18366:366;;;:::o;18810:866::-;18961:4;18956:3;18952:14;19048:4;19041:5;19037:16;19031:23;19067:63;19124:4;19119:3;19115:14;19101:12;19067:63;:::i;:::-;18976:164;19232:4;19225:5;19221:16;19215:23;19251:61;19306:4;19301:3;19297:14;19283:12;19251:61;:::i;:::-;19150:172;19406:4;19399:5;19395:16;19389:23;19425:57;19476:4;19471:3;19467:14;19453:12;19425:57;:::i;:::-;19332:160;19579:4;19572:5;19568:16;19562:23;19598:61;19653:4;19648:3;19644:14;19630:12;19598:61;:::i;:::-;19502:167;18930:746;18810:866;;:::o;19754:876::-;19915:4;19910:3;19906:14;20002:4;19995:5;19991:16;19985:23;20021:63;20078:4;20073:3;20069:14;20055:12;20021:63;:::i;:::-;19930:164;20186:4;20179:5;20175:16;20169:23;20205:61;20260:4;20255:3;20251:14;20237:12;20205:61;:::i;:::-;20104:172;20360:4;20353:5;20349:16;20343:23;20379:57;20430:4;20425:3;20421:14;20407:12;20379:57;:::i;:::-;20286:160;20533:4;20526:5;20522:16;20516:23;20552:61;20607:4;20602:3;20598:14;20584:12;20552:61;:::i;:::-;20456:167;19884:746;19754:876;;:::o;20636:105::-;20711:23;20728:5;20711:23;:::i;:::-;20706:3;20699:36;20636:105;;:::o;20747:108::-;20824:24;20842:5;20824:24;:::i;:::-;20819:3;20812:37;20747:108;;:::o;20861:118::-;20948:24;20966:5;20948:24;:::i;:::-;20943:3;20936:37;20861:118;;:::o;20985:157::-;21090:45;21110:24;21128:5;21110:24;:::i;:::-;21090:45;:::i;:::-;21085:3;21078:58;20985:157;;:::o;21148:105::-;21223:23;21240:5;21223:23;:::i;:::-;21218:3;21211:36;21148:105;;:::o;21259:112::-;21342:22;21358:5;21342:22;:::i;:::-;21337:3;21330:35;21259:112;;:::o;21377:679::-;21573:3;21588:75;21659:3;21650:6;21588:75;:::i;:::-;21688:2;21683:3;21679:12;21672:19;;21701:75;21772:3;21763:6;21701:75;:::i;:::-;21801:2;21796:3;21792:12;21785:19;;21814:75;21885:3;21876:6;21814:75;:::i;:::-;21914:2;21909:3;21905:12;21898:19;;21927:75;21998:3;21989:6;21927:75;:::i;:::-;22027:2;22022:3;22018:12;22011:19;;22047:3;22040:10;;21377:679;;;;;;;:::o;22062:435::-;22242:3;22264:95;22355:3;22346:6;22264:95;:::i;:::-;22257:102;;22376:95;22467:3;22458:6;22376:95;:::i;:::-;22369:102;;22488:3;22481:10;;22062:435;;;;;:::o;22503:522::-;22716:3;22738:148;22882:3;22738:148;:::i;:::-;22731:155;;22896:75;22967:3;22958:6;22896:75;:::i;:::-;22996:2;22991:3;22987:12;22980:19;;23016:3;23009:10;;22503:522;;;;:::o;23031:222::-;23124:4;23162:2;23151:9;23147:18;23139:26;;23175:71;23243:1;23232:9;23228:17;23219:6;23175:71;:::i;:::-;23031:222;;;;:::o;23259:640::-;23454:4;23492:3;23481:9;23477:19;23469:27;;23506:71;23574:1;23563:9;23559:17;23550:6;23506:71;:::i;:::-;23587:72;23655:2;23644:9;23640:18;23631:6;23587:72;:::i;:::-;23669;23737:2;23726:9;23722:18;23713:6;23669:72;:::i;:::-;23788:9;23782:4;23778:20;23773:2;23762:9;23758:18;23751:48;23816:76;23887:4;23878:6;23816:76;:::i;:::-;23808:84;;23259:640;;;;;;;:::o;23905:501::-;24112:4;24150:2;24139:9;24135:18;24127:26;;24199:9;24193:4;24189:20;24185:1;24174:9;24170:17;24163:47;24227:172;24394:4;24385:6;24227:172;:::i;:::-;24219:180;;23905:501;;;;:::o;24412:373::-;24555:4;24593:2;24582:9;24578:18;24570:26;;24642:9;24636:4;24632:20;24628:1;24617:9;24613:17;24606:47;24670:108;24773:4;24764:6;24670:108;:::i;:::-;24662:116;;24412:373;;;;:::o;24791:210::-;24878:4;24916:2;24905:9;24901:18;24893:26;;24929:65;24991:1;24980:9;24976:17;24967:6;24929:65;:::i;:::-;24791:210;;;;:::o;25007:545::-;25180:4;25218:3;25207:9;25203:19;25195:27;;25232:71;25300:1;25289:9;25285:17;25276:6;25232:71;:::i;:::-;25313:68;25377:2;25366:9;25362:18;25353:6;25313:68;:::i;:::-;25391:72;25459:2;25448:9;25444:18;25435:6;25391:72;:::i;:::-;25473;25541:2;25530:9;25526:18;25517:6;25473:72;:::i;:::-;25007:545;;;;;;;:::o;25558:313::-;25671:4;25709:2;25698:9;25694:18;25686:26;;25758:9;25752:4;25748:20;25744:1;25733:9;25729:17;25722:47;25786:78;25859:4;25850:6;25786:78;:::i;:::-;25778:86;;25558:313;;;;:::o;25877:419::-;26043:4;26081:2;26070:9;26066:18;26058:26;;26130:9;26124:4;26120:20;26116:1;26105:9;26101:17;26094:47;26158:131;26284:4;26158:131;:::i;:::-;26150:139;;25877:419;;;:::o;26302:::-;26468:4;26506:2;26495:9;26491:18;26483:26;;26555:9;26549:4;26545:20;26541:1;26530:9;26526:17;26519:47;26583:131;26709:4;26583:131;:::i;:::-;26575:139;;26302:419;;;:::o;26727:::-;26893:4;26931:2;26920:9;26916:18;26908:26;;26980:9;26974:4;26970:20;26966:1;26955:9;26951:17;26944:47;27008:131;27134:4;27008:131;:::i;:::-;27000:139;;26727:419;;;:::o;27152:::-;27318:4;27356:2;27345:9;27341:18;27333:26;;27405:9;27399:4;27395:20;27391:1;27380:9;27376:17;27369:47;27433:131;27559:4;27433:131;:::i;:::-;27425:139;;27152:419;;;:::o;27577:::-;27743:4;27781:2;27770:9;27766:18;27758:26;;27830:9;27824:4;27820:20;27816:1;27805:9;27801:17;27794:47;27858:131;27984:4;27858:131;:::i;:::-;27850:139;;27577:419;;;:::o;28002:::-;28168:4;28206:2;28195:9;28191:18;28183:26;;28255:9;28249:4;28245:20;28241:1;28230:9;28226:17;28219:47;28283:131;28409:4;28283:131;:::i;:::-;28275:139;;28002:419;;;:::o;28427:::-;28593:4;28631:2;28620:9;28616:18;28608:26;;28680:9;28674:4;28670:20;28666:1;28655:9;28651:17;28644:47;28708:131;28834:4;28708:131;:::i;:::-;28700:139;;28427:419;;;:::o;28852:::-;29018:4;29056:2;29045:9;29041:18;29033:26;;29105:9;29099:4;29095:20;29091:1;29080:9;29076:17;29069:47;29133:131;29259:4;29133:131;:::i;:::-;29125:139;;28852:419;;;:::o;29277:351::-;29434:4;29472:3;29461:9;29457:19;29449:27;;29486:135;29618:1;29607:9;29603:17;29594:6;29486:135;:::i;:::-;29277:351;;;;:::o;29634:222::-;29727:4;29765:2;29754:9;29750:18;29742:26;;29778:71;29846:1;29835:9;29831:17;29822:6;29778:71;:::i;:::-;29634:222;;;;:::o;29862:129::-;29896:6;29923:20;;:::i;:::-;29913:30;;29952:33;29980:4;29972:6;29952:33;:::i;:::-;29862:129;;;:::o;29997:75::-;30030:6;30063:2;30057:9;30047:19;;29997:75;:::o;30078:307::-;30139:4;30229:18;30221:6;30218:30;30215:56;;;30251:18;;:::i;:::-;30215:56;30289:29;30311:6;30289:29;:::i;:::-;30281:37;;30373:4;30367;30363:15;30355:23;;30078:307;;;:::o;30391:308::-;30453:4;30543:18;30535:6;30532:30;30529:56;;;30565:18;;:::i;:::-;30529:56;30603:29;30625:6;30603:29;:::i;:::-;30595:37;;30687:4;30681;30677:15;30669:23;;30391:308;;;:::o;30705:164::-;30804:4;30827:3;30819:11;;30857:4;30852:3;30848:14;30840:22;;30705:164;;;:::o;30875:132::-;30942:4;30965:3;30957:11;;30995:4;30990:3;30986:14;30978:22;;30875:132;;;:::o;31013:146::-;31112:6;31146:5;31140:12;31130:22;;31013:146;;;:::o;31165:114::-;31232:6;31266:5;31260:12;31250:22;;31165:114;;;:::o;31285:98::-;31336:6;31370:5;31364:12;31354:22;;31285:98;;;:::o;31389:99::-;31441:6;31475:5;31469:12;31459:22;;31389:99;;;:::o;31494:145::-;31596:4;31628;31623:3;31619:14;31611:22;;31494:145;;;:::o;31645:113::-;31715:4;31747;31742:3;31738:14;31730:22;;31645:113;;;:::o;31764:216::-;31895:11;31929:6;31924:3;31917:19;31969:4;31964:3;31960:14;31945:29;;31764:216;;;;:::o;31986:184::-;32085:11;32119:6;32114:3;32107:19;32159:4;32154:3;32150:14;32135:29;;31986:184;;;;:::o;32176:168::-;32259:11;32293:6;32288:3;32281:19;32333:4;32328:3;32324:14;32309:29;;32176:168;;;;:::o;32350:169::-;32434:11;32468:6;32463:3;32456:19;32508:4;32503:3;32499:14;32484:29;;32350:169;;;;:::o;32525:148::-;32627:11;32664:3;32649:18;;32525:148;;;;:::o;32679:305::-;32719:3;32738:20;32756:1;32738:20;:::i;:::-;32733:25;;32772:20;32790:1;32772:20;:::i;:::-;32767:25;;32926:1;32858:66;32854:74;32851:1;32848:81;32845:107;;;32932:18;;:::i;:::-;32845:107;32976:1;32973;32969:9;32962:16;;32679:305;;;;:::o;32990:96::-;33027:7;33056:24;33074:5;33056:24;:::i;:::-;33045:35;;32990:96;;;:::o;33092:90::-;33126:7;33169:5;33162:13;33155:21;33144:32;;33092:90;;;:::o;33188:77::-;33225:7;33254:5;33243:16;;33188:77;;;:::o;33271:149::-;33307:7;33347:66;33340:5;33336:78;33325:89;;33271:149;;;:::o;33426:126::-;33463:7;33503:42;33496:5;33492:54;33481:65;;33426:126;;;:::o;33558:91::-;33594:7;33634:8;33627:5;33623:20;33612:31;;33558:91;;;:::o;33655:77::-;33692:7;33721:5;33710:16;;33655:77;;;:::o;33738:101::-;33774:7;33814:18;33807:5;33803:30;33792:41;;33738:101;;;:::o;33845:86::-;33880:7;33920:4;33913:5;33909:16;33898:27;;33845:86;;;:::o;33937:154::-;34021:6;34016:3;34011;33998:30;34083:1;34074:6;34069:3;34065:16;34058:27;33937:154;;;:::o;34097:307::-;34165:1;34175:113;34189:6;34186:1;34183:13;34175:113;;;34274:1;34269:3;34265:11;34259:18;34255:1;34250:3;34246:11;34239:39;34211:2;34208:1;34204:10;34199:15;;34175:113;;;34306:6;34303:1;34300:13;34297:101;;;34386:1;34377:6;34372:3;34368:16;34361:27;34297:101;34146:258;34097:307;;;:::o;34410:320::-;34454:6;34491:1;34485:4;34481:12;34471:22;;34538:1;34532:4;34528:12;34559:18;34549:81;;34615:4;34607:6;34603:17;34593:27;;34549:81;34677:2;34669:6;34666:14;34646:18;34643:38;34640:84;;;34696:18;;:::i;:::-;34640:84;34461:269;34410:320;;;:::o;34736:281::-;34819:27;34841:4;34819:27;:::i;:::-;34811:6;34807:40;34949:6;34937:10;34934:22;34913:18;34901:10;34898:34;34895:62;34892:88;;;34960:18;;:::i;:::-;34892:88;35000:10;34996:2;34989:22;34779:238;34736:281;;:::o;35023:100::-;35062:7;35091:26;35111:5;35091:26;:::i;:::-;35080:37;;35023:100;;;:::o;35129:79::-;35168:7;35197:5;35186:16;;35129:79;;;:::o;35214:94::-;35253:7;35282:20;35296:5;35282:20;:::i;:::-;35271:31;;35214:94;;;:::o;35314:79::-;35353:7;35382:5;35371:16;;35314:79;;;:::o;35399:180::-;35447:77;35444:1;35437:88;35544:4;35541:1;35534:15;35568:4;35565:1;35558:15;35585:180;35633:77;35630:1;35623:88;35730:4;35727:1;35720:15;35754:4;35751:1;35744:15;35771:180;35819:77;35816:1;35809:88;35916:4;35913:1;35906:15;35940:4;35937:1;35930:15;35957:180;36005:77;36002:1;35995:88;36102:4;36099:1;36092:15;36126:4;36123:1;36116:15;36143:180;36191:77;36188:1;36181:88;36288:4;36285:1;36278:15;36312:4;36309:1;36302:15;36329:117;36438:1;36435;36428:12;36452:117;36561:1;36558;36551:12;36575:117;36684:1;36681;36674:12;36698:117;36807:1;36804;36797:12;36821:117;36930:1;36927;36920:12;36944:117;37053:1;37050;37043:12;37067:102;37108:6;37159:2;37155:7;37150:2;37143:5;37139:14;37135:28;37125:38;;37067:102;;;:::o;37175:94::-;37208:8;37256:5;37252:2;37248:14;37227:35;;37175:94;;;:::o;37275:174::-;37415:26;37411:1;37403:6;37399:14;37392:50;37275:174;:::o;37455:167::-;37595:19;37591:1;37583:6;37579:14;37572:43;37455:167;:::o;37628:181::-;37768:33;37764:1;37756:6;37752:14;37745:57;37628:181;:::o;37815:214::-;37955:66;37951:1;37943:6;37939:14;37932:90;37815:214;:::o;38035:225::-;38175:34;38171:1;38163:6;38159:14;38152:58;38244:8;38239:2;38231:6;38227:15;38220:33;38035:225;:::o;38266:164::-;38406:16;38402:1;38394:6;38390:14;38383:40;38266:164;:::o;38436:221::-;38576:34;38572:1;38564:6;38560:14;38553:58;38645:4;38640:2;38632:6;38628:15;38621:29;38436:221;:::o;38663:182::-;38803:34;38799:1;38791:6;38787:14;38780:58;38663:182;:::o;38851:169::-;38991:21;38987:1;38979:6;38975:14;38968:45;38851:169;:::o;39026:122::-;39099:24;39117:5;39099:24;:::i;:::-;39092:5;39089:35;39079:63;;39138:1;39135;39128:12;39079:63;39026:122;:::o;39154:116::-;39224:21;39239:5;39224:21;:::i;:::-;39217:5;39214:32;39204:60;;39260:1;39257;39250:12;39204:60;39154:116;:::o;39276:120::-;39348:23;39365:5;39348:23;:::i;:::-;39341:5;39338:34;39328:62;;39386:1;39383;39376:12;39328:62;39276:120;:::o;39402:122::-;39475:24;39493:5;39475:24;:::i;:::-;39468:5;39465:35;39455:63;;39514:1;39511;39504:12;39455:63;39402:122;:::o
Swarm Source
ipfs://ee398dd6f5b84400b913bece98c23fc45508148cd2778f33d2248d215f4c81b3
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.