Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 77 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Approval For... | 21354626 | 21 days ago | IN | 0 ETH | 0.0004008 | ||||
Set Approval For... | 21354625 | 21 days ago | IN | 0 ETH | 0.00059283 | ||||
Safe Transfer Fr... | 21238111 | 37 days ago | IN | 0 ETH | 0.00153789 | ||||
Set Approval For... | 20406855 | 153 days ago | IN | 0 ETH | 0.00017166 | ||||
Safe Transfer Fr... | 20254332 | 174 days ago | IN | 0 ETH | 0.00008057 | ||||
Set Approval For... | 20249980 | 175 days ago | IN | 0 ETH | 0.00009681 | ||||
Safe Transfer Fr... | 20249924 | 175 days ago | IN | 0 ETH | 0.00011077 | ||||
Safe Transfer Fr... | 20211795 | 180 days ago | IN | 0 ETH | 0.00053633 | ||||
Set Approval For... | 19534483 | 275 days ago | IN | 0 ETH | 0.00272021 | ||||
Safe Transfer Fr... | 19534175 | 275 days ago | IN | 0 ETH | 0.00272404 | ||||
Set Approval For... | 19236758 | 317 days ago | IN | 0 ETH | 0.00169707 | ||||
Transfer From | 19157758 | 328 days ago | IN | 0 ETH | 0.00096806 | ||||
Set Approval For... | 19150093 | 329 days ago | IN | 0 ETH | 0.00090062 | ||||
Set Approval For... | 18965262 | 355 days ago | IN | 0 ETH | 0.0017257 | ||||
Set Approval For... | 18936383 | 359 days ago | IN | 0 ETH | 0.0013217 | ||||
Set Approval For... | 18911702 | 362 days ago | IN | 0 ETH | 0.00063728 | ||||
Withdraw | 18890951 | 365 days ago | IN | 0 ETH | 0.00064535 | ||||
Set Approval For... | 18887039 | 366 days ago | IN | 0 ETH | 0.00118481 | ||||
Set Sale Status | 18885470 | 366 days ago | IN | 0 ETH | 0.00104709 | ||||
Public Mint | 18885449 | 366 days ago | IN | 0.014 ETH | 0.00095316 | ||||
Public Mint | 18885448 | 366 days ago | IN | 0.014 ETH | 0.00090338 | ||||
Public Mint | 18885346 | 366 days ago | IN | 0.014 ETH | 0.00327316 | ||||
Public Mint | 18885278 | 366 days ago | IN | 0.014 ETH | 0.00312508 | ||||
Safe Transfer Fr... | 18884131 | 366 days ago | IN | 0 ETH | 0.00330618 | ||||
Public Mint | 18882612 | 367 days ago | IN | 0.014 ETH | 0.00289308 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
18890951 | 365 days ago | 0.504 ETH |
Loading...
Loading
Contract Name:
Snowball_Warming
Compiler Version
v0.8.22+commit.4fc1097e
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-12-29 */ // SPDX-License-Identifier: MIT /** *Submitted for verification at Etherscan.io on 2023-11-29 */ // File: @openzeppelin/contracts/utils/math/SignedMath.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } } // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Muldiv operation overflow. */ error MathOverflowedMulDiv(); enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an overflow flag. */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the 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 towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. return a / b; } // (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 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (denominator <= prod1) { revert MathOverflowedMulDiv(); } /////////////////////////////////////////////// // 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. uint256 twos = denominator & (0 - denominator); 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 (unsignedRoundsUp(rounding) && 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 * towards zero. * * 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 + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * 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 + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * 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 + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol) pragma solidity ^0.8.20; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @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), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { uint256 localValue = value; 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] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal * representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } } // File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.20; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS } /** * @dev The signature derives the `address(0)`. */ error ECDSAInvalidSignature(); /** * @dev The signature has an invalid length. */ error ECDSAInvalidSignatureLength(uint256 length); /** * @dev The signature has an S value that is in the upper half order. */ error ECDSAInvalidSignatureS(bytes32 s); /** * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not * return address(0) without also returning an error description. Errors are documented using an enum (error type) * and a bytes32 providing additional information about the error. * * If no error is returned, then the address can be used for verification purposes. * * The `ecrecover` EVM precompile 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 {MessageHashUtils-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] */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) { 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, bytes32(signature.length)); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM precompile 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 {MessageHashUtils-toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature); _throwError(error, errorArg); 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] */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) { unchecked { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); // We do not check for an overflow here since the shift operation results in 0 or 1. 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. */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs); _throwError(error, errorArg); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError, bytes32) { // 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, s); } // 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, bytes32(0)); } return (signer, RecoverError.NoError, bytes32(0)); } /** * @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, bytes32 errorArg) = tryRecover(hash, v, r, s); _throwError(error, errorArg); return recovered; } /** * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided. */ function _throwError(RecoverError error, bytes32 errorArg) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert ECDSAInvalidSignature(); } else if (error == RecoverError.InvalidSignatureLength) { revert ECDSAInvalidSignatureLength(uint256(errorArg)); } else if (error == RecoverError.InvalidSignatureS) { revert ECDSAInvalidSignatureS(errorArg); } } } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/interfaces/IERC2981.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.20; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) external view returns (address receiver, uint256 royaltyAmount); } // File: @openzeppelin/contracts/token/common/ERC2981.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/common/ERC2981.sol) pragma solidity ^0.8.20; /** * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the * fee is specified in basis points by default. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. */ abstract contract ERC2981 is IERC2981, ERC165 { struct RoyaltyInfo { address receiver; uint96 royaltyFraction; } RoyaltyInfo private _defaultRoyaltyInfo; mapping(uint256 tokenId => RoyaltyInfo) private _tokenRoyaltyInfo; /** * @dev The default royalty set is invalid (eg. (numerator / denominator) >= 1). */ error ERC2981InvalidDefaultRoyalty(uint256 numerator, uint256 denominator); /** * @dev The default royalty receiver is invalid. */ error ERC2981InvalidDefaultRoyaltyReceiver(address receiver); /** * @dev The royalty set for an specific `tokenId` is invalid (eg. (numerator / denominator) >= 1). */ error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator); /** * @dev The royalty receiver for `tokenId` is invalid. */ error ERC2981InvalidTokenRoyaltyReceiver(uint256 tokenId, address receiver); /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } /** * @inheritdoc IERC2981 */ function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual returns (address, uint256) { RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId]; if (royalty.receiver == address(0)) { royalty = _defaultRoyaltyInfo; } uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator(); return (royalty.receiver, royaltyAmount); } /** * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an * override. */ function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /** * @dev Sets the royalty information that all ids in this contract will default to. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { uint256 denominator = _feeDenominator(); if (feeNumerator > denominator) { // Royalty fee will exceed the sale price revert ERC2981InvalidDefaultRoyalty(feeNumerator, denominator); } if (receiver == address(0)) { revert ERC2981InvalidDefaultRoyaltyReceiver(address(0)); } _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Removes default royalty information. */ function _deleteDefaultRoyalty() internal virtual { delete _defaultRoyaltyInfo; } /** * @dev Sets the royalty information for a specific token id, overriding the global default. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual { uint256 denominator = _feeDenominator(); if (feeNumerator > denominator) { // Royalty fee will exceed the sale price revert ERC2981InvalidTokenRoyalty(tokenId, feeNumerator, denominator); } if (receiver == address(0)) { revert ERC2981InvalidTokenRoyaltyReceiver(tokenId, address(0)); } _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Resets royalty information for the token id back to the global default. */ function _resetTokenRoyalty(uint256 tokenId) internal virtual { delete _tokenRoyaltyInfo[tokenId]; } } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.18; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @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 { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: meules.sol pragma solidity ^0.8.0; /** * @dev Interface of ERC721A. */ 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 ); } /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ 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 1; } /** * @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) } } } /// @notice Optimized and flexible operator filterer to abide to OpenSea's /// mandatory on-chain royalty enforcement in order for new collections to /// receive royalties. /// For more information, see: /// See: https://github.com/ProjectOpenSea/operator-filter-registry abstract contract OperatorFilterer { /// @dev The default OpenSea operator blocklist subscription. address internal constant _DEFAULT_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6; /// @dev The OpenSea operator filter registry. address internal constant _OPERATOR_FILTER_REGISTRY = 0x000000000000AAeB6D7670E522A718067333cd4E; /// @dev Registers the current contract to OpenSea's operator filter, /// and subscribe to the default OpenSea operator blocklist. /// Note: Will not revert nor update existing settings for repeated registration. function _registerForOperatorFiltering() internal virtual { _registerForOperatorFiltering(_DEFAULT_SUBSCRIPTION, true); } /// @dev Registers the current contract to OpenSea's operator filter. /// Note: Will not revert nor update existing settings for repeated registration. function _registerForOperatorFiltering( address subscriptionOrRegistrantToCopy, bool subscribe ) internal virtual { /// @solidity memory-safe-assembly assembly { let functionSelector := 0x7d3e3dbe // `registerAndSubscribe(address,address)`. // Clean the upper 96 bits of `subscriptionOrRegistrantToCopy` in case they are dirty. subscriptionOrRegistrantToCopy := shr( 96, shl(96, subscriptionOrRegistrantToCopy) ) // prettier-ignore for {} iszero(subscribe) {} { if iszero(subscriptionOrRegistrantToCopy) { functionSelector := 0x4420e486 // `register(address)`. break } functionSelector := 0xa0af2903 // `registerAndCopyEntries(address,address)`. break } // Store the function selector. mstore(0x00, shl(224, functionSelector)) // Store the `address(this)`. mstore(0x04, address()) // Store the `subscriptionOrRegistrantToCopy`. mstore(0x24, subscriptionOrRegistrantToCopy) // Register into the registry. pop( call( gas(), _OPERATOR_FILTER_REGISTRY, 0, 0x00, 0x44, 0x00, 0x00 ) ) // Restore the part of the free memory pointer that was overwritten, // which is guaranteed to be zero, because of Solidity's memory size limits. mstore(0x24, 0) } } /// @dev Modifier to guard a function and revert if `from` is a blocked operator. /// Can be turned on / off via `enabled`. /// For gas efficiency, you can use tight variable packing to efficiently read / write /// the boolean value for `enabled`. modifier onlyAllowedOperator(address from, bool enabled) virtual { /// @solidity memory-safe-assembly assembly { // This code prioritizes runtime gas costs on a chain with the registry. // As such, we will not use `extcodesize`, but rather abuse the behavior // of `staticcall` returning 1 when called on an empty / missing contract, // to avoid reverting when a chain does not have the registry. if enabled { // Check if `from` is not equal to `msg.sender`, // discarding the upper 96 bits of `from` in case they are dirty. if iszero(eq(shr(96, shl(96, from)), caller())) { // Store the function selector of `isOperatorAllowed(address,address)`, // shifted left by 6 bytes, which is enough for 8tb of memory. // We waste 6-3 = 3 bytes to save on 6 runtime gas (PUSH1 0x224 SHL). mstore(0x00, 0xc6171134001122334455) // Store the `address(this)`. mstore(0x1a, address()) // Store the `msg.sender`. mstore(0x3a, caller()) // `isOperatorAllowed` always returns true if it does not revert. if iszero( staticcall( gas(), _OPERATOR_FILTER_REGISTRY, 0x16, 0x44, 0x00, 0x00 ) ) { // Bubble up the revert if the staticcall reverts. returndatacopy(0x00, 0x00, returndatasize()) revert(0x00, returndatasize()) } // We'll skip checking if `from` is inside the blacklist. // Even though that can block transferring out of wrapper contracts, // we don't want tokens to be stuck. // Restore the part of the free memory pointer that was overwritten, // which is guaranteed to be zero, if less than 8tb of memory is used. mstore(0x3a, 0) } } } _; } /// @dev Modifier to guard a function from approving a blocked operator. /// Can be turned on / off via `enabled`. /// For efficiency, you can use tight variable packing to efficiently read / write /// the boolean value for `enabled`. modifier onlyAllowedOperatorApproval(address operator, bool enabled) virtual { /// @solidity memory-safe-assembly assembly { // For more information on the optimization techniques used, // see the comments in `onlyAllowedOperator`. if enabled { // Store the function selector of `isOperatorAllowed(address,address)`, mstore(0x00, 0xc6171134001122334455) // Store the `address(this)`. mstore(0x1a, address()) // Store the `operator`, discarding the upper 96 bits in case they are dirty. mstore(0x3a, shr(96, shl(96, operator))) // `isOperatorAllowed` always returns true if it does not revert. if iszero( staticcall( gas(), _OPERATOR_FILTER_REGISTRY, 0x16, 0x44, 0x00, 0x00 ) ) { // Bubble up the revert if the staticcall reverts. returndatacopy(0x00, 0x00, returndatasize()) revert(0x00, returndatasize()) } // Restore the part of the free memory pointer that was overwritten. mstore(0x3a, 0) } } _; } } error AlreadyReservedTokens(); error CallerNotOffsetter(); error FunctionLocked(); error InsufficientValue(); error InsufficientMints(); error InsufficientSupply(); error InvalidSignature(); error NoContractMinting(); error ProvenanceHashAlreadySet(); error ProvenanceHashNotSet(); error TokenOffsetAlreadySet(); error TokenOffsetNotSet(); error WithdrawFailed(); interface Offsetable { function setOffset(uint256 randomness) external; } contract Snowball_Warming is ERC721A, ERC2981, OperatorFilterer, Ownable { event PUBLICMINT(address receiver, uint256 quantity, bool isUk); using ECDSA for bytes32; string private _baseTokenURI; string public baseExtension = ".json"; uint256 public constant RESERVED = 5; uint256 public SEC_RESERVED = 30; uint256 public mintPrice = 0.014 ether; uint256 public mintingTime = 2 days; uint256 private startTime = 0; string public provenanceHash; bool public operatorFilteringEnabled; mapping(bytes4 => bool) public functionLocked; bool public publicSaleStatus = false; mapping(address => bool) public isUk; constructor( address _royaltyReceiver, uint96 _royaltyFraction, address initialOwner ) ERC721A(unicode"Snowball Warming", unicode"Snowball Warming") Ownable(initialOwner){ _registerForOperatorFiltering(); operatorFilteringEnabled = true; _setDefaultRoyalty(_royaltyReceiver, _royaltyFraction); } /** * @notice Modifier applied to functions that will be disabled when they're no longer needed */ modifier lockable() { if (functionLocked[msg.sig]) revert FunctionLocked(); _; } /** * @inheritdoc ERC721A */ function supportsInterface(bytes4 interfaceId) public view override(ERC721A, ERC2981) returns (bool) { return ERC721A.supportsInterface(interfaceId) || ERC2981.supportsInterface(interfaceId); } /** * @notice Override ERC721A _baseURI function to use base URI pattern */ function _baseURI() internal view virtual override returns (string memory) { return _baseTokenURI; } function setBaseExtension(string memory _newBaseExtension) public onlyOwner { baseExtension = _newBaseExtension; } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require( _exists(tokenId), "ERC721Metadata: URI query for nonexistent token" ); string memory currentBaseURI = _baseURI(); return bytes(currentBaseURI).length > 0 ? string( abi.encodePacked( currentBaseURI, Strings.toString(tokenId), baseExtension ) ) : ""; } /** * @notice Return the number of tokens an address has minted * @param account Address to return the number of tokens minted for */ function numberMinted(address account) external view returns (uint256) { return _numberMinted(account); } /** * @notice Lock a function so that it can no longer be called * @dev WARNING: THIS CANNOT BE UNDONE * @param id Function signature */ function lockFunction(bytes4 id) external onlyOwner { functionLocked[id] = true; } /** * @notice Set the state of the OpenSea operator filter * @param value Flag indicating if the operator filter should be applied to transfers and approvals */ function setOperatorFilteringEnabled(bool value) external lockable onlyOwner { operatorFilteringEnabled = value; } /** * @notice Set new royalties settings for the collection * @param receiver Address to receive royalties * @param royaltyFraction Royalty fee respective to fee denominator (10_000) */ function setRoyalties(address receiver, uint96 royaltyFraction) external onlyOwner { _setDefaultRoyalty(receiver, royaltyFraction); } /** * @notice Set token metadata base URI * @param _newBaseURI New base URI */ function setBaseURI(string calldata _newBaseURI) external lockable onlyOwner { _baseTokenURI = _newBaseURI; } /** * @notice Set provenance hash for the collection * @param _provenanceHash New hash of the metadata */ function setProvenanceHash(string calldata _provenanceHash) external lockable onlyOwner { if (bytes(provenanceHash).length != 0) revert ProvenanceHashAlreadySet(); provenanceHash = _provenanceHash; } /** * @notice Mint `RESERVED` amount of tokens to an address * @param to Address to send the reserved tokens */ function reserve(address to) external lockable onlyOwner { if (_totalMinted() >= RESERVED) revert AlreadyReservedTokens(); _mint(to, RESERVED); } function secondaryReserve(address to, uint256 quantity) external lockable onlyOwner { _mint(to, quantity); } function publicMint( address to, uint256 quantity, bool _isUk ) external payable { require(publicSaleStatus == true, "Minting is not yet open."); require(block.timestamp <= (startTime + mintingTime), "Time is over now"); uint256 totalCost = quantity * mintPrice; require(msg.value >= totalCost, "Ether sent is not correct."); _mint(to, quantity); isUk[to] = _isUk; if (msg.value > totalCost) { payable(msg.sender).transfer(msg.value - totalCost); } emit PUBLICMINT(to, quantity, _isUk); } function setSaleStatus(bool _saleStatus) external onlyOwner { publicSaleStatus = _saleStatus; startTime = block.timestamp; } function mintTimeSetter(uint256 _time) external onlyOwner{ mintingTime = _time; } function setPrice(uint256 _price) external onlyOwner{ mintPrice = _price; } /** * @notice Withdraw all ETH sent to the contract */ function withdraw() external onlyOwner { (bool success, ) = payable(msg.sender).call{ value: address(this).balance }(""); if (!success) revert WithdrawFailed(); } /** * @notice Override to enforce OpenSea's operator filter requirement to receive collection royalties * @inheritdoc ERC721A */ function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator, operatorFilteringEnabled) { super.setApprovalForAll(operator, approved); } /** * @notice Override to enforce OpenSea's operator filter requirement to receive collection royalties * @inheritdoc ERC721A */ function approve(address operator, uint256 tokenId) public payable override onlyAllowedOperatorApproval(operator, operatorFilteringEnabled) { super.approve(operator, tokenId); } /** * @notice Override to enforce OpenSea's operator filter requirement to receive collection royalties * @inheritdoc ERC721A */ function transferFrom( address from, address to, uint256 tokenId ) public payable override onlyAllowedOperator(from, operatorFilteringEnabled) { super.transferFrom(from, to, tokenId); } /** * @notice Override to enforce OpenSea's operator filter requirement to receive collection royalties * @inheritdoc ERC721A */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable override onlyAllowedOperator(from, operatorFilteringEnabled) { super.safeTransferFrom(from, to, tokenId); } /** * @notice Override to enforce OpenSea's operator filter requirement to receive collection royalties * @inheritdoc ERC721A */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public payable override onlyAllowedOperator(from, operatorFilteringEnabled) { super.safeTransferFrom(from, to, tokenId, data); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_royaltyReceiver","type":"address"},{"internalType":"uint96","name":"_royaltyFraction","type":"uint96"},{"internalType":"address","name":"initialOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyReservedTokens","type":"error"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidDefaultRoyalty","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidTokenRoyalty","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidTokenRoyaltyReceiver","type":"error"},{"inputs":[],"name":"FunctionLocked","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"ProvenanceHashAlreadySet","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"},{"inputs":[],"name":"WithdrawFailed","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":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isUk","type":"bool"}],"name":"PUBLICMINT","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":[],"name":"RESERVED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEC_RESERVED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","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":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"name":"functionLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[{"internalType":"address","name":"","type":"address"}],"name":"isUk","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"id","type":"bytes4"}],"name":"lockFunction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_time","type":"uint256"}],"name":"mintTimeSetter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintingTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorFilteringEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"provenanceHash","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bool","name":"_isUk","type":"bool"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"publicSaleStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"reserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"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":"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":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"secondaryReserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseExtension","type":"string"}],"name":"setBaseExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"setOperatorFilteringEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_provenanceHash","type":"string"}],"name":"setProvenanceHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"royaltyFraction","type":"uint96"}],"name":"setRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_saleStatus","type":"bool"}],"name":"setSaleStatus","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":[],"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":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526040518060400160405280600581526020017f2e6a736f6e000000000000000000000000000000000000000000000000000000815250600c90816200004a91906200078b565b50601e600d556631bced02db0000600e556202a300600f555f6010555f60145f6101000a81548160ff0219169083151502179055503480156200008b575f80fd5b5060405162004a0938038062004a098339818101604052810190620000b191906200091a565b806040518060400160405280601081526020017f536e6f7762616c6c205761726d696e67000000000000000000000000000000008152506040518060400160405280601081526020017f536e6f7762616c6c205761726d696e670000000000000000000000000000000081525081600290816200012f91906200078b565b5080600390816200014191906200078b565b50620001526200022360201b60201c565b5f8190555050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620001cc575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401620001c3919062000984565b60405180910390fd5b620001dd816200022b60201b60201c565b50620001ee620002ee60201b60201c565b600160125f6101000a81548160ff0219169083151502179055506200021a83836200031760201b60201c565b50505062000a13565b5f6001905090565b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b62000315733cc6cdda760b79bafa08df41ecfa224f810dceb66001620004c060201b60201c565b565b5f620003286200051e60201b60201c565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff161115620003905781816040517f6f483d0900000000000000000000000000000000000000000000000000000000815260040162000387929190620009e8565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160362000403575f6040517fb6d9900a000000000000000000000000000000000000000000000000000000008152600401620003fa919062000984565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff1681525060085f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b637d3e3dbe8260601b60601c925081620004ef5782620004e757634420e4869050620004ef565b63a0af290390505b8060e01b5f5230600452826024525f8060445f806daaeb6d7670e522a718067333cd4e5af1505f602452505050565b5f612710905090565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620005a357607f821691505b602082108103620005b957620005b86200055e565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026200061d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620005e0565b620006298683620005e0565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f620006736200066d620006678462000641565b6200064a565b62000641565b9050919050565b5f819050919050565b6200068e8362000653565b620006a66200069d826200067a565b848454620005ec565b825550505050565b5f90565b620006bc620006ae565b620006c981848462000683565b505050565b5b81811015620006f057620006e45f82620006b2565b600181019050620006cf565b5050565b601f8211156200073f576200070981620005bf565b6200071484620005d1565b8101602085101562000724578190505b6200073c6200073385620005d1565b830182620006ce565b50505b505050565b5f82821c905092915050565b5f620007615f198460080262000744565b1980831691505092915050565b5f6200077b838362000750565b9150826002028217905092915050565b620007968262000527565b67ffffffffffffffff811115620007b257620007b162000531565b5b620007be82546200058b565b620007cb828285620006f4565b5f60209050601f83116001811462000801575f8415620007ec578287015190505b620007f885826200076e565b86555062000867565b601f1984166200081186620005bf565b5f5b828110156200083a5784890151825560018201915060208501945060208101905062000813565b868310156200085a578489015162000856601f89168262000750565b8355505b6001600288020188555050505b505050505050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200089e8262000873565b9050919050565b620008b08162000892565b8114620008bb575f80fd5b50565b5f81519050620008ce81620008a5565b92915050565b5f6bffffffffffffffffffffffff82169050919050565b620008f681620008d4565b811462000901575f80fd5b50565b5f815190506200091481620008eb565b92915050565b5f805f606084860312156200093457620009336200086f565b5b5f6200094386828701620008be565b9350506020620009568682870162000904565b92505060406200096986828701620008be565b9150509250925092565b6200097e8162000892565b82525050565b5f602082019050620009995f83018462000973565b92915050565b5f620009bf620009b9620009b384620008d4565b6200064a565b62000641565b9050919050565b620009d1816200099f565b82525050565b620009e28162000641565b82525050565b5f604082019050620009fd5f830185620009c6565b62000a0c6020830184620009d7565b9392505050565b613fe88062000a215f395ff3fe608060405260043610610250575f3560e01c80638da5cb5b11610138578063c21b471b116100b5578063da3ef23f11610079578063da3ef23f1461084b578063dc33e68114610873578063e75179a4146108af578063e985e9c5146108d7578063f2fde38b14610913578063fb796e6c1461093b57610250565b8063c21b471b1461076b578063c668286214610793578063c6ab67a3146107bd578063c87b56dd146107e7578063d897833e1461082357610250565b8063b629f192116100fc578063b629f19214610685578063b6c693e5146106c1578063b7c0b8e8146106eb578063b88d4fde14610713578063bbadfe761461072f57610250565b80638da5cb5b146105b757806391b7f5ed146105e157806395d89b4114610609578063a22cb46514610633578063aa592f251461065b57610250565b80633ccfd60b116101d15780636352211e116101955780636352211e146104af5780636817c76c146104eb57806370a0823114610515578063715018a61461055157806374d0101d146105675780638a7162281461058f57610250565b80633ccfd60b1461040f578063402c38561461042557806342842e0e1461044157806355f804b31461045d578063601e5e771461048557610250565b80631096952311610218578063109695231461033c57806318160ddd1461036457806323b872dd1461038e5780632a55205a146103aa57806334531828146103e757610250565b806301ffc9a71461025457806306fdde0314610290578063081812fc146102ba578063095ea7b3146102f65780630d5a5a7714610312575b5f80fd5b34801561025f575f80fd5b5061027a60048036038101906102759190612e82565b610965565b6040516102879190612ec7565b60405180910390f35b34801561029b575f80fd5b506102a4610986565b6040516102b19190612f6a565b60405180910390f35b3480156102c5575f80fd5b506102e060048036038101906102db9190612fbd565b610a16565b6040516102ed9190613027565b60405180910390f35b610310600480360381019061030b919061306a565b610a90565b005b34801561031d575f80fd5b50610326610af9565b60405161033391906130b7565b60405180910390f35b348015610347575f80fd5b50610362600480360381019061035d9190613131565b610aff565b005b34801561036f575f80fd5b50610378610c1a565b60405161038591906130b7565b60405180910390f35b6103a860048036038101906103a3919061317c565b610c2f565b005b3480156103b5575f80fd5b506103d060048036038101906103cb91906131cc565b610ca2565b6040516103de92919061320a565b60405180910390f35b3480156103f2575f80fd5b5061040d60048036038101906104089190612e82565b610e7e565b005b34801561041a575f80fd5b50610423610ef0565b005b61043f600480360381019061043a919061325b565b610f9a565b005b61045b6004803603810190610456919061317c565b61118c565b005b348015610468575f80fd5b50610483600480360381019061047e9190613131565b6111ff565b005b348015610490575f80fd5b506104996112d3565b6040516104a691906130b7565b60405180910390f35b3480156104ba575f80fd5b506104d560048036038101906104d09190612fbd565b6112d9565b6040516104e29190613027565b60405180910390f35b3480156104f6575f80fd5b506104ff6112ea565b60405161050c91906130b7565b60405180910390f35b348015610520575f80fd5b5061053b600480360381019061053691906132ab565b6112f0565b60405161054891906130b7565b60405180910390f35b34801561055c575f80fd5b506105656113a5565b005b348015610572575f80fd5b5061058d6004803603810190610588919061306a565b6113b8565b005b34801561059a575f80fd5b506105b560048036038101906105b09190612fbd565b611484565b005b3480156105c2575f80fd5b506105cb611496565b6040516105d89190613027565b60405180910390f35b3480156105ec575f80fd5b5061060760048036038101906106029190612fbd565b6114be565b005b348015610614575f80fd5b5061061d6114d0565b60405161062a9190612f6a565b60405180910390f35b34801561063e575f80fd5b50610659600480360381019061065491906132d6565b611560565b005b348015610666575f80fd5b5061066f6115c9565b60405161067c91906130b7565b60405180910390f35b348015610690575f80fd5b506106ab60048036038101906106a691906132ab565b6115ce565b6040516106b89190612ec7565b60405180910390f35b3480156106cc575f80fd5b506106d56115eb565b6040516106e29190612ec7565b60405180910390f35b3480156106f6575f80fd5b50610711600480360381019061070c9190613314565b6115fd565b005b61072d60048036038101906107289190613467565b6116d7565b005b34801561073a575f80fd5b5061075560048036038101906107509190612e82565b61174c565b6040516107629190612ec7565b60405180910390f35b348015610776575f80fd5b50610791600480360381019061078c9190613528565b611769565b005b34801561079e575f80fd5b506107a761177f565b6040516107b49190612f6a565b60405180910390f35b3480156107c8575f80fd5b506107d161180b565b6040516107de9190612f6a565b60405180910390f35b3480156107f2575f80fd5b5061080d60048036038101906108089190612fbd565b611897565b60405161081a9190612f6a565b60405180910390f35b34801561082e575f80fd5b5061084960048036038101906108449190613314565b61193e565b005b348015610856575f80fd5b50610871600480360381019061086c9190613604565b611969565b005b34801561087e575f80fd5b50610899600480360381019061089491906132ab565b611984565b6040516108a691906130b7565b60405180910390f35b3480156108ba575f80fd5b506108d560048036038101906108d091906132ab565b611995565b005b3480156108e2575f80fd5b506108fd60048036038101906108f8919061364b565b611aa2565b60405161090a9190612ec7565b60405180910390f35b34801561091e575f80fd5b50610939600480360381019061093491906132ab565b611b30565b005b348015610946575f80fd5b5061094f611bb4565b60405161095c9190612ec7565b60405180910390f35b5f61096f82611bc6565b8061097f575061097e82611c57565b5b9050919050565b606060028054610995906136b6565b80601f01602080910402602001604051908101604052809291908181526020018280546109c1906136b6565b8015610a0c5780601f106109e357610100808354040283529160200191610a0c565b820191905f5260205f20905b8154815290600101906020018083116109ef57829003601f168201915b5050505050905090565b5f610a2082611cd0565b610a56576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8160125f9054906101000a900460ff168015610ae95769c61711340011223344555f5230601a528160601b60601c603a525f80604460166daaeb6d7670e522a718067333cd4e5afa610ae4573d5f803e3d5ffd5b5f603a525b610af38484611d2a565b50505050565b600f5481565b60135f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff1615610bb5576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bbd611e69565b5f60118054610bcb906136b6565b905014610c04576040517f19e24c1100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818160119182610c1592919061388d565b505050565b5f610c23611ef0565b6001545f540303905090565b8260125f9054906101000a900460ff168015610c9057338260601b60601c14610c8f5769c61711340011223344555f5230601a5233603a525f80604460166daaeb6d7670e522a718067333cd4e5afa610c8a573d5f803e3d5ffd5b5f603a525b5b610c9b858585611ef8565b5050505050565b5f805f60095f8681526020019081526020015f206040518060400160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505f73ffffffffffffffffffffffffffffffffffffffff16815f015173ffffffffffffffffffffffffffffffffffffffff1603610e2b5760086040518060400160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b5f610e34612206565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610e609190613987565b610e6a91906139f5565b9050815f0151819350935050509250929050565b610e86611e69565b600160135f837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b610ef8611e69565b5f3373ffffffffffffffffffffffffffffffffffffffff1647604051610f1d90613a52565b5f6040518083038185875af1925050503d805f8114610f57576040519150601f19603f3d011682016040523d82523d5f602084013e610f5c565b606091505b5050905080610f97576040517f750b219c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b6001151560145f9054906101000a900460ff16151514610fef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe690613ab0565b60405180910390fd5b600f54601054610fff9190613ace565b421115611041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103890613b4b565b60405180910390fd5b5f600e54836110509190613987565b905080341015611095576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108c90613bb3565b60405180910390fd5b61109f848461220f565b8160155f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508034111561114b573373ffffffffffffffffffffffffffffffffffffffff166108fc82346111219190613bd1565b90811502906040515f60405180830381858888f19350505050158015611149573d5f803e3d5ffd5b505b7f1bb382e9d53b459c87b27472552ef310651dfbc65ef02e78380dd3780a42714984848460405161117e93929190613c04565b60405180910390a150505050565b8260125f9054906101000a900460ff1680156111ed57338260601b60601c146111ec5769c61711340011223344555f5230601a5233603a525f80604460166daaeb6d7670e522a718067333cd4e5afa6111e7573d5f803e3d5ffd5b5f603a525b5b6111f88585856123b8565b5050505050565b60135f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff16156112b5576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112bd611e69565b8181600b91826112ce92919061388d565b505050565b600d5481565b5f6112e3826123d7565b9050919050565b600e5481565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611356576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b6113ad611e69565b6113b65f61249a565b565b60135f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff161561146e576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611476611e69565b611480828261220f565b5050565b61148c611e69565b80600f8190555050565b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6114c6611e69565b80600e8190555050565b6060600380546114df906136b6565b80601f016020809104026020016040519081016040528092919081815260200182805461150b906136b6565b80156115565780601f1061152d57610100808354040283529160200191611556565b820191905f5260205f20905b81548152906001019060200180831161153957829003601f168201915b5050505050905090565b8160125f9054906101000a900460ff1680156115b95769c61711340011223344555f5230601a528160601b60601c603a525f80604460166daaeb6d7670e522a718067333cd4e5afa6115b4573d5f803e3d5ffd5b5f603a525b6115c3848461255d565b50505050565b600581565b6015602052805f5260405f205f915054906101000a900460ff1681565b60145f9054906101000a900460ff1681565b60135f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff16156116b3576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116bb611e69565b8060125f6101000a81548160ff02191690831515021790555050565b8360125f9054906101000a900460ff16801561173857338260601b60601c146117375769c61711340011223344555f5230601a5233603a525f80604460166daaeb6d7670e522a718067333cd4e5afa611732573d5f803e3d5ffd5b5f603a525b5b61174486868686612663565b505050505050565b6013602052805f5260405f205f915054906101000a900460ff1681565b611771611e69565b61177b82826126d5565b5050565b600c805461178c906136b6565b80601f01602080910402602001604051908101604052809291908181526020018280546117b8906136b6565b80156118035780601f106117da57610100808354040283529160200191611803565b820191905f5260205f20905b8154815290600101906020018083116117e657829003601f168201915b505050505081565b60118054611818906136b6565b80601f0160208091040260200160405190810160405280929190818152602001828054611844906136b6565b801561188f5780601f106118665761010080835404028352916020019161188f565b820191905f5260205f20905b81548152906001019060200180831161187257829003601f168201915b505050505081565b60606118a282611cd0565b6118e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118d890613ca9565b60405180910390fd5b5f6118ea612870565b90505f8151116119085760405180602001604052805f815250611936565b8061191284612900565b600c60405160200161192693929190613d81565b6040516020818303038152906040525b915050919050565b611946611e69565b8060145f6101000a81548160ff0219169083151502179055504260108190555050565b611971611e69565b80600c90816119809190613db1565b5050565b5f61198e826129ca565b9050919050565b60135f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff1615611a4b576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611a53611e69565b6005611a5d612a1e565b10611a94576040517f1f0f14ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611a9f81600561220f565b50565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b611b38611e69565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ba8575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401611b9f9190613027565b60405180910390fd5b611bb18161249a565b50565b60125f9054906101000a900460ff1681565b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611c2057506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611c505750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b5f7f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611cc95750611cc882612a2f565b5b9050919050565b5f81611cda611ef0565b11158015611ce857505f5482105b8015611d2357505f7c010000000000000000000000000000000000000000000000000000000060045f8581526020019081526020015f205416145b9050919050565b5f611d34826112d9565b90508073ffffffffffffffffffffffffffffffffffffffff16611d55612a98565b73ffffffffffffffffffffffffffffffffffffffff1614611db857611d8181611d7c612a98565b611aa2565b611db7576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b8260065f8481526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b611e71612a9f565b73ffffffffffffffffffffffffffffffffffffffff16611e8f611496565b73ffffffffffffffffffffffffffffffffffffffff1614611eee57611eb2612a9f565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611ee59190613027565b60405180910390fd5b565b5f6001905090565b5f611f02826123d7565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611f69576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80611f7484612aa6565b91509150611f8a8187611f85612a98565b612ac9565b611fd657611f9f86611f9a612a98565b611aa2565b611fd5576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361203b576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120488686866001612b0c565b8015612052575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f81546001019190508190555061211a856120f6888887612b12565b7c020000000000000000000000000000000000000000000000000000000017612b39565b60045f8681526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000841603612196575f6001850190505f60045f8381526020019081526020015f205403612194575f548114612193578360045f8381526020019081526020015f20819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46121fe8686866001612b63565b505050505050565b5f612710905090565b5f805490505f820361224d576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122595f848385612b0c565b600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055506122cb836122bc5f865f612b12565b6122c585612b69565b17612b39565b60045f8381526020019081526020015f20819055505f80838301905073ffffffffffffffffffffffffffffffffffffffff8516915082825f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4600183015b8181146123655780835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a460018101905061232c565b505f820361239f576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805f8190555050506123b35f848385612b63565b505050565b6123d283838360405180602001604052805f8152506116d7565b505050565b5f80829050806123e5611ef0565b11612463575f54811015612462575f60045f8381526020019081526020015f205490505f7c0100000000000000000000000000000000000000000000000000000000821603612460575b5f81036124565760045f836001900393508381526020019081526020015f2054905061242f565b8092505050612495565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8060075f612569612a98565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612612612a98565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516126579190612ec7565b60405180910390a35050565b61266e848484610c2f565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146126cf5761269884848484612b78565b6126ce576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b5f6126de612206565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff1611156127435781816040517f6f483d0900000000000000000000000000000000000000000000000000000000815260040161273a929190613eb0565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036127b3575f6040517fb6d9900a0000000000000000000000000000000000000000000000000000000081526004016127aa9190613027565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff1681525060085f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b6060600b805461287f906136b6565b80601f01602080910402602001604051908101604052809291908181526020018280546128ab906136b6565b80156128f65780601f106128cd576101008083540402835291602001916128f6565b820191905f5260205f20905b8154815290600101906020018083116128d957829003601f168201915b5050505050905090565b60605f600161290e84612cc3565b0190505f8167ffffffffffffffff81111561292c5761292b613343565b5b6040519080825280601f01601f19166020018201604052801561295e5781602001600182028036833780820191505090505b5090505f82602001820190505b6001156129bf578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816129b4576129b36139c8565b5b0494505f850361296b575b819350505050919050565b5f67ffffffffffffffff604060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054901c169050919050565b5f612a27611ef0565b5f5403905090565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f33905090565b5f33905090565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b5f8060e883901c905060e8612b28868684612e14565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b5f6001821460e11b9050919050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612b9d612a98565b8786866040518563ffffffff1660e01b8152600401612bbf9493929190613f29565b6020604051808303815f875af1925050508015612bfa57506040513d601f19601f82011682018060405250810190612bf79190613f87565b60015b612c70573d805f8114612c28576040519150601f19603f3d011682016040523d82523d5f602084013e612c2d565b606091505b505f815103612c68576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612d1f577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612d1557612d146139c8565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612d5c576d04ee2d6d415b85acef81000000008381612d5257612d516139c8565b5b0492506020810190505b662386f26fc100008310612d8b57662386f26fc100008381612d8157612d806139c8565b5b0492506010810190505b6305f5e1008310612db4576305f5e1008381612daa57612da96139c8565b5b0492506008810190505b6127108310612dd9576127108381612dcf57612dce6139c8565b5b0492506004810190505b60648310612dfc5760648381612df257612df16139c8565b5b0492506002810190505b600a8310612e0b576001810190505b80915050919050565b5f9392505050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612e6181612e2d565b8114612e6b575f80fd5b50565b5f81359050612e7c81612e58565b92915050565b5f60208284031215612e9757612e96612e25565b5b5f612ea484828501612e6e565b91505092915050565b5f8115159050919050565b612ec181612ead565b82525050565b5f602082019050612eda5f830184612eb8565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015612f17578082015181840152602081019050612efc565b5f8484015250505050565b5f601f19601f8301169050919050565b5f612f3c82612ee0565b612f468185612eea565b9350612f56818560208601612efa565b612f5f81612f22565b840191505092915050565b5f6020820190508181035f830152612f828184612f32565b905092915050565b5f819050919050565b612f9c81612f8a565b8114612fa6575f80fd5b50565b5f81359050612fb781612f93565b92915050565b5f60208284031215612fd257612fd1612e25565b5b5f612fdf84828501612fa9565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61301182612fe8565b9050919050565b61302181613007565b82525050565b5f60208201905061303a5f830184613018565b92915050565b61304981613007565b8114613053575f80fd5b50565b5f8135905061306481613040565b92915050565b5f80604083850312156130805761307f612e25565b5b5f61308d85828601613056565b925050602061309e85828601612fa9565b9150509250929050565b6130b181612f8a565b82525050565b5f6020820190506130ca5f8301846130a8565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f8401126130f1576130f06130d0565b5b8235905067ffffffffffffffff81111561310e5761310d6130d4565b5b60208301915083600182028301111561312a576131296130d8565b5b9250929050565b5f806020838503121561314757613146612e25565b5b5f83013567ffffffffffffffff81111561316457613163612e29565b5b613170858286016130dc565b92509250509250929050565b5f805f6060848603121561319357613192612e25565b5b5f6131a086828701613056565b93505060206131b186828701613056565b92505060406131c286828701612fa9565b9150509250925092565b5f80604083850312156131e2576131e1612e25565b5b5f6131ef85828601612fa9565b925050602061320085828601612fa9565b9150509250929050565b5f60408201905061321d5f830185613018565b61322a60208301846130a8565b9392505050565b61323a81612ead565b8114613244575f80fd5b50565b5f8135905061325581613231565b92915050565b5f805f6060848603121561327257613271612e25565b5b5f61327f86828701613056565b935050602061329086828701612fa9565b92505060406132a186828701613247565b9150509250925092565b5f602082840312156132c0576132bf612e25565b5b5f6132cd84828501613056565b91505092915050565b5f80604083850312156132ec576132eb612e25565b5b5f6132f985828601613056565b925050602061330a85828601613247565b9150509250929050565b5f6020828403121561332957613328612e25565b5b5f61333684828501613247565b91505092915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61337982612f22565b810181811067ffffffffffffffff8211171561339857613397613343565b5b80604052505050565b5f6133aa612e1c565b90506133b68282613370565b919050565b5f67ffffffffffffffff8211156133d5576133d4613343565b5b6133de82612f22565b9050602081019050919050565b828183375f83830152505050565b5f61340b613406846133bb565b6133a1565b9050828152602081018484840111156134275761342661333f565b5b6134328482856133eb565b509392505050565b5f82601f83011261344e5761344d6130d0565b5b813561345e8482602086016133f9565b91505092915050565b5f805f806080858703121561347f5761347e612e25565b5b5f61348c87828801613056565b945050602061349d87828801613056565b93505060406134ae87828801612fa9565b925050606085013567ffffffffffffffff8111156134cf576134ce612e29565b5b6134db8782880161343a565b91505092959194509250565b5f6bffffffffffffffffffffffff82169050919050565b613507816134e7565b8114613511575f80fd5b50565b5f81359050613522816134fe565b92915050565b5f806040838503121561353e5761353d612e25565b5b5f61354b85828601613056565b925050602061355c85828601613514565b9150509250929050565b5f67ffffffffffffffff8211156135805761357f613343565b5b61358982612f22565b9050602081019050919050565b5f6135a86135a384613566565b6133a1565b9050828152602081018484840111156135c4576135c361333f565b5b6135cf8482856133eb565b509392505050565b5f82601f8301126135eb576135ea6130d0565b5b81356135fb848260208601613596565b91505092915050565b5f6020828403121561361957613618612e25565b5b5f82013567ffffffffffffffff81111561363657613635612e29565b5b613642848285016135d7565b91505092915050565b5f806040838503121561366157613660612e25565b5b5f61366e85828601613056565b925050602061367f85828601613056565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806136cd57607f821691505b6020821081036136e0576136df613689565b5b50919050565b5f82905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261374c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613711565b6137568683613711565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61379161378c61378784612f8a565b61376e565b612f8a565b9050919050565b5f819050919050565b6137aa83613777565b6137be6137b682613798565b84845461371d565b825550505050565b5f90565b6137d26137c6565b6137dd8184846137a1565b505050565b5b81811015613800576137f55f826137ca565b6001810190506137e3565b5050565b601f82111561384557613816816136f0565b61381f84613702565b8101602085101561382e578190505b61384261383a85613702565b8301826137e2565b50505b505050565b5f82821c905092915050565b5f6138655f198460080261384a565b1980831691505092915050565b5f61387d8383613856565b9150826002028217905092915050565b61389783836136e6565b67ffffffffffffffff8111156138b0576138af613343565b5b6138ba82546136b6565b6138c5828285613804565b5f601f8311600181146138f2575f84156138e0578287013590505b6138ea8582613872565b865550613951565b601f198416613900866136f0565b5f5b8281101561392757848901358255600182019150602085019450602081019050613902565b868310156139445784890135613940601f891682613856565b8355505b6001600288020188555050505b50505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61399182612f8a565b915061399c83612f8a565b92508282026139aa81612f8a565b915082820484148315176139c1576139c061395a565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6139ff82612f8a565b9150613a0a83612f8a565b925082613a1a57613a196139c8565b5b828204905092915050565b5f81905092915050565b50565b5f613a3d5f83613a25565b9150613a4882613a2f565b5f82019050919050565b5f613a5c82613a32565b9150819050919050565b7f4d696e74696e67206973206e6f7420796574206f70656e2e00000000000000005f82015250565b5f613a9a601883612eea565b9150613aa582613a66565b602082019050919050565b5f6020820190508181035f830152613ac781613a8e565b9050919050565b5f613ad882612f8a565b9150613ae383612f8a565b9250828201905080821115613afb57613afa61395a565b5b92915050565b7f54696d65206973206f766572206e6f77000000000000000000000000000000005f82015250565b5f613b35601083612eea565b9150613b4082613b01565b602082019050919050565b5f6020820190508181035f830152613b6281613b29565b9050919050565b7f45746865722073656e74206973206e6f7420636f72726563742e0000000000005f82015250565b5f613b9d601a83612eea565b9150613ba882613b69565b602082019050919050565b5f6020820190508181035f830152613bca81613b91565b9050919050565b5f613bdb82612f8a565b9150613be683612f8a565b9250828203905081811115613bfe57613bfd61395a565b5b92915050565b5f606082019050613c175f830186613018565b613c2460208301856130a8565b613c316040830184612eb8565b949350505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f5f8201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b5f613c93602f83612eea565b9150613c9e82613c39565b604082019050919050565b5f6020820190508181035f830152613cc081613c87565b9050919050565b5f81905092915050565b5f613cdb82612ee0565b613ce58185613cc7565b9350613cf5818560208601612efa565b80840191505092915050565b5f8154613d0d816136b6565b613d178186613cc7565b9450600182165f8114613d315760018114613d4657613d78565b60ff1983168652811515820286019350613d78565b613d4f856136f0565b5f5b83811015613d7057815481890152600182019150602081019050613d51565b838801955050505b50505092915050565b5f613d8c8286613cd1565b9150613d988285613cd1565b9150613da48284613d01565b9150819050949350505050565b613dba82612ee0565b67ffffffffffffffff811115613dd357613dd2613343565b5b613ddd82546136b6565b613de8828285613804565b5f60209050601f831160018114613e19575f8415613e07578287015190505b613e118582613872565b865550613e78565b601f198416613e27866136f0565b5f5b82811015613e4e57848901518255600182019150602085019450602081019050613e29565b86831015613e6b5784890151613e67601f891682613856565b8355505b6001600288020188555050505b505050505050565b5f613e9a613e95613e90846134e7565b61376e565b612f8a565b9050919050565b613eaa81613e80565b82525050565b5f604082019050613ec35f830185613ea1565b613ed060208301846130a8565b9392505050565b5f81519050919050565b5f82825260208201905092915050565b5f613efb82613ed7565b613f058185613ee1565b9350613f15818560208601612efa565b613f1e81612f22565b840191505092915050565b5f608082019050613f3c5f830187613018565b613f496020830186613018565b613f5660408301856130a8565b8181036060830152613f688184613ef1565b905095945050505050565b5f81519050613f8181612e58565b92915050565b5f60208284031215613f9c57613f9b612e25565b5b5f613fa984828501613f73565b9150509291505056fea2646970667358221220e4eeb855fde223fcbf7d48c9ca912f1cc2eaf5521b01ee295d2e07e848c3f5fd64736f6c6343000816003300000000000000000000000047b757af6da640aaf89589edbe485981a046f31300000000000000000000000000000000000000000000000000000000000001f400000000000000000000000059de7273191e6bf1907d614e94ecfbe8e5fb7318
Deployed Bytecode
0x608060405260043610610250575f3560e01c80638da5cb5b11610138578063c21b471b116100b5578063da3ef23f11610079578063da3ef23f1461084b578063dc33e68114610873578063e75179a4146108af578063e985e9c5146108d7578063f2fde38b14610913578063fb796e6c1461093b57610250565b8063c21b471b1461076b578063c668286214610793578063c6ab67a3146107bd578063c87b56dd146107e7578063d897833e1461082357610250565b8063b629f192116100fc578063b629f19214610685578063b6c693e5146106c1578063b7c0b8e8146106eb578063b88d4fde14610713578063bbadfe761461072f57610250565b80638da5cb5b146105b757806391b7f5ed146105e157806395d89b4114610609578063a22cb46514610633578063aa592f251461065b57610250565b80633ccfd60b116101d15780636352211e116101955780636352211e146104af5780636817c76c146104eb57806370a0823114610515578063715018a61461055157806374d0101d146105675780638a7162281461058f57610250565b80633ccfd60b1461040f578063402c38561461042557806342842e0e1461044157806355f804b31461045d578063601e5e771461048557610250565b80631096952311610218578063109695231461033c57806318160ddd1461036457806323b872dd1461038e5780632a55205a146103aa57806334531828146103e757610250565b806301ffc9a71461025457806306fdde0314610290578063081812fc146102ba578063095ea7b3146102f65780630d5a5a7714610312575b5f80fd5b34801561025f575f80fd5b5061027a60048036038101906102759190612e82565b610965565b6040516102879190612ec7565b60405180910390f35b34801561029b575f80fd5b506102a4610986565b6040516102b19190612f6a565b60405180910390f35b3480156102c5575f80fd5b506102e060048036038101906102db9190612fbd565b610a16565b6040516102ed9190613027565b60405180910390f35b610310600480360381019061030b919061306a565b610a90565b005b34801561031d575f80fd5b50610326610af9565b60405161033391906130b7565b60405180910390f35b348015610347575f80fd5b50610362600480360381019061035d9190613131565b610aff565b005b34801561036f575f80fd5b50610378610c1a565b60405161038591906130b7565b60405180910390f35b6103a860048036038101906103a3919061317c565b610c2f565b005b3480156103b5575f80fd5b506103d060048036038101906103cb91906131cc565b610ca2565b6040516103de92919061320a565b60405180910390f35b3480156103f2575f80fd5b5061040d60048036038101906104089190612e82565b610e7e565b005b34801561041a575f80fd5b50610423610ef0565b005b61043f600480360381019061043a919061325b565b610f9a565b005b61045b6004803603810190610456919061317c565b61118c565b005b348015610468575f80fd5b50610483600480360381019061047e9190613131565b6111ff565b005b348015610490575f80fd5b506104996112d3565b6040516104a691906130b7565b60405180910390f35b3480156104ba575f80fd5b506104d560048036038101906104d09190612fbd565b6112d9565b6040516104e29190613027565b60405180910390f35b3480156104f6575f80fd5b506104ff6112ea565b60405161050c91906130b7565b60405180910390f35b348015610520575f80fd5b5061053b600480360381019061053691906132ab565b6112f0565b60405161054891906130b7565b60405180910390f35b34801561055c575f80fd5b506105656113a5565b005b348015610572575f80fd5b5061058d6004803603810190610588919061306a565b6113b8565b005b34801561059a575f80fd5b506105b560048036038101906105b09190612fbd565b611484565b005b3480156105c2575f80fd5b506105cb611496565b6040516105d89190613027565b60405180910390f35b3480156105ec575f80fd5b5061060760048036038101906106029190612fbd565b6114be565b005b348015610614575f80fd5b5061061d6114d0565b60405161062a9190612f6a565b60405180910390f35b34801561063e575f80fd5b50610659600480360381019061065491906132d6565b611560565b005b348015610666575f80fd5b5061066f6115c9565b60405161067c91906130b7565b60405180910390f35b348015610690575f80fd5b506106ab60048036038101906106a691906132ab565b6115ce565b6040516106b89190612ec7565b60405180910390f35b3480156106cc575f80fd5b506106d56115eb565b6040516106e29190612ec7565b60405180910390f35b3480156106f6575f80fd5b50610711600480360381019061070c9190613314565b6115fd565b005b61072d60048036038101906107289190613467565b6116d7565b005b34801561073a575f80fd5b5061075560048036038101906107509190612e82565b61174c565b6040516107629190612ec7565b60405180910390f35b348015610776575f80fd5b50610791600480360381019061078c9190613528565b611769565b005b34801561079e575f80fd5b506107a761177f565b6040516107b49190612f6a565b60405180910390f35b3480156107c8575f80fd5b506107d161180b565b6040516107de9190612f6a565b60405180910390f35b3480156107f2575f80fd5b5061080d60048036038101906108089190612fbd565b611897565b60405161081a9190612f6a565b60405180910390f35b34801561082e575f80fd5b5061084960048036038101906108449190613314565b61193e565b005b348015610856575f80fd5b50610871600480360381019061086c9190613604565b611969565b005b34801561087e575f80fd5b50610899600480360381019061089491906132ab565b611984565b6040516108a691906130b7565b60405180910390f35b3480156108ba575f80fd5b506108d560048036038101906108d091906132ab565b611995565b005b3480156108e2575f80fd5b506108fd60048036038101906108f8919061364b565b611aa2565b60405161090a9190612ec7565b60405180910390f35b34801561091e575f80fd5b50610939600480360381019061093491906132ab565b611b30565b005b348015610946575f80fd5b5061094f611bb4565b60405161095c9190612ec7565b60405180910390f35b5f61096f82611bc6565b8061097f575061097e82611c57565b5b9050919050565b606060028054610995906136b6565b80601f01602080910402602001604051908101604052809291908181526020018280546109c1906136b6565b8015610a0c5780601f106109e357610100808354040283529160200191610a0c565b820191905f5260205f20905b8154815290600101906020018083116109ef57829003601f168201915b5050505050905090565b5f610a2082611cd0565b610a56576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8160125f9054906101000a900460ff168015610ae95769c61711340011223344555f5230601a528160601b60601c603a525f80604460166daaeb6d7670e522a718067333cd4e5afa610ae4573d5f803e3d5ffd5b5f603a525b610af38484611d2a565b50505050565b600f5481565b60135f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff1615610bb5576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bbd611e69565b5f60118054610bcb906136b6565b905014610c04576040517f19e24c1100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818160119182610c1592919061388d565b505050565b5f610c23611ef0565b6001545f540303905090565b8260125f9054906101000a900460ff168015610c9057338260601b60601c14610c8f5769c61711340011223344555f5230601a5233603a525f80604460166daaeb6d7670e522a718067333cd4e5afa610c8a573d5f803e3d5ffd5b5f603a525b5b610c9b858585611ef8565b5050505050565b5f805f60095f8681526020019081526020015f206040518060400160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505f73ffffffffffffffffffffffffffffffffffffffff16815f015173ffffffffffffffffffffffffffffffffffffffff1603610e2b5760086040518060400160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b5f610e34612206565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610e609190613987565b610e6a91906139f5565b9050815f0151819350935050509250929050565b610e86611e69565b600160135f837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b610ef8611e69565b5f3373ffffffffffffffffffffffffffffffffffffffff1647604051610f1d90613a52565b5f6040518083038185875af1925050503d805f8114610f57576040519150601f19603f3d011682016040523d82523d5f602084013e610f5c565b606091505b5050905080610f97576040517f750b219c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b6001151560145f9054906101000a900460ff16151514610fef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe690613ab0565b60405180910390fd5b600f54601054610fff9190613ace565b421115611041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103890613b4b565b60405180910390fd5b5f600e54836110509190613987565b905080341015611095576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108c90613bb3565b60405180910390fd5b61109f848461220f565b8160155f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508034111561114b573373ffffffffffffffffffffffffffffffffffffffff166108fc82346111219190613bd1565b90811502906040515f60405180830381858888f19350505050158015611149573d5f803e3d5ffd5b505b7f1bb382e9d53b459c87b27472552ef310651dfbc65ef02e78380dd3780a42714984848460405161117e93929190613c04565b60405180910390a150505050565b8260125f9054906101000a900460ff1680156111ed57338260601b60601c146111ec5769c61711340011223344555f5230601a5233603a525f80604460166daaeb6d7670e522a718067333cd4e5afa6111e7573d5f803e3d5ffd5b5f603a525b5b6111f88585856123b8565b5050505050565b60135f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff16156112b5576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112bd611e69565b8181600b91826112ce92919061388d565b505050565b600d5481565b5f6112e3826123d7565b9050919050565b600e5481565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611356576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b6113ad611e69565b6113b65f61249a565b565b60135f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff161561146e576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611476611e69565b611480828261220f565b5050565b61148c611e69565b80600f8190555050565b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6114c6611e69565b80600e8190555050565b6060600380546114df906136b6565b80601f016020809104026020016040519081016040528092919081815260200182805461150b906136b6565b80156115565780601f1061152d57610100808354040283529160200191611556565b820191905f5260205f20905b81548152906001019060200180831161153957829003601f168201915b5050505050905090565b8160125f9054906101000a900460ff1680156115b95769c61711340011223344555f5230601a528160601b60601c603a525f80604460166daaeb6d7670e522a718067333cd4e5afa6115b4573d5f803e3d5ffd5b5f603a525b6115c3848461255d565b50505050565b600581565b6015602052805f5260405f205f915054906101000a900460ff1681565b60145f9054906101000a900460ff1681565b60135f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff16156116b3576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116bb611e69565b8060125f6101000a81548160ff02191690831515021790555050565b8360125f9054906101000a900460ff16801561173857338260601b60601c146117375769c61711340011223344555f5230601a5233603a525f80604460166daaeb6d7670e522a718067333cd4e5afa611732573d5f803e3d5ffd5b5f603a525b5b61174486868686612663565b505050505050565b6013602052805f5260405f205f915054906101000a900460ff1681565b611771611e69565b61177b82826126d5565b5050565b600c805461178c906136b6565b80601f01602080910402602001604051908101604052809291908181526020018280546117b8906136b6565b80156118035780601f106117da57610100808354040283529160200191611803565b820191905f5260205f20905b8154815290600101906020018083116117e657829003601f168201915b505050505081565b60118054611818906136b6565b80601f0160208091040260200160405190810160405280929190818152602001828054611844906136b6565b801561188f5780601f106118665761010080835404028352916020019161188f565b820191905f5260205f20905b81548152906001019060200180831161187257829003601f168201915b505050505081565b60606118a282611cd0565b6118e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118d890613ca9565b60405180910390fd5b5f6118ea612870565b90505f8151116119085760405180602001604052805f815250611936565b8061191284612900565b600c60405160200161192693929190613d81565b6040516020818303038152906040525b915050919050565b611946611e69565b8060145f6101000a81548160ff0219169083151502179055504260108190555050565b611971611e69565b80600c90816119809190613db1565b5050565b5f61198e826129ca565b9050919050565b60135f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff1615611a4b576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611a53611e69565b6005611a5d612a1e565b10611a94576040517f1f0f14ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611a9f81600561220f565b50565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b611b38611e69565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ba8575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401611b9f9190613027565b60405180910390fd5b611bb18161249a565b50565b60125f9054906101000a900460ff1681565b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611c2057506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611c505750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b5f7f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611cc95750611cc882612a2f565b5b9050919050565b5f81611cda611ef0565b11158015611ce857505f5482105b8015611d2357505f7c010000000000000000000000000000000000000000000000000000000060045f8581526020019081526020015f205416145b9050919050565b5f611d34826112d9565b90508073ffffffffffffffffffffffffffffffffffffffff16611d55612a98565b73ffffffffffffffffffffffffffffffffffffffff1614611db857611d8181611d7c612a98565b611aa2565b611db7576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b8260065f8481526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b611e71612a9f565b73ffffffffffffffffffffffffffffffffffffffff16611e8f611496565b73ffffffffffffffffffffffffffffffffffffffff1614611eee57611eb2612a9f565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611ee59190613027565b60405180910390fd5b565b5f6001905090565b5f611f02826123d7565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611f69576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80611f7484612aa6565b91509150611f8a8187611f85612a98565b612ac9565b611fd657611f9f86611f9a612a98565b611aa2565b611fd5576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361203b576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120488686866001612b0c565b8015612052575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f81546001019190508190555061211a856120f6888887612b12565b7c020000000000000000000000000000000000000000000000000000000017612b39565b60045f8681526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000841603612196575f6001850190505f60045f8381526020019081526020015f205403612194575f548114612193578360045f8381526020019081526020015f20819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46121fe8686866001612b63565b505050505050565b5f612710905090565b5f805490505f820361224d576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122595f848385612b0c565b600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055506122cb836122bc5f865f612b12565b6122c585612b69565b17612b39565b60045f8381526020019081526020015f20819055505f80838301905073ffffffffffffffffffffffffffffffffffffffff8516915082825f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4600183015b8181146123655780835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a460018101905061232c565b505f820361239f576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805f8190555050506123b35f848385612b63565b505050565b6123d283838360405180602001604052805f8152506116d7565b505050565b5f80829050806123e5611ef0565b11612463575f54811015612462575f60045f8381526020019081526020015f205490505f7c0100000000000000000000000000000000000000000000000000000000821603612460575b5f81036124565760045f836001900393508381526020019081526020015f2054905061242f565b8092505050612495565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8060075f612569612a98565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612612612a98565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516126579190612ec7565b60405180910390a35050565b61266e848484610c2f565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146126cf5761269884848484612b78565b6126ce576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b5f6126de612206565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff1611156127435781816040517f6f483d0900000000000000000000000000000000000000000000000000000000815260040161273a929190613eb0565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036127b3575f6040517fb6d9900a0000000000000000000000000000000000000000000000000000000081526004016127aa9190613027565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff1681525060085f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b6060600b805461287f906136b6565b80601f01602080910402602001604051908101604052809291908181526020018280546128ab906136b6565b80156128f65780601f106128cd576101008083540402835291602001916128f6565b820191905f5260205f20905b8154815290600101906020018083116128d957829003601f168201915b5050505050905090565b60605f600161290e84612cc3565b0190505f8167ffffffffffffffff81111561292c5761292b613343565b5b6040519080825280601f01601f19166020018201604052801561295e5781602001600182028036833780820191505090505b5090505f82602001820190505b6001156129bf578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816129b4576129b36139c8565b5b0494505f850361296b575b819350505050919050565b5f67ffffffffffffffff604060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054901c169050919050565b5f612a27611ef0565b5f5403905090565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f33905090565b5f33905090565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b5f8060e883901c905060e8612b28868684612e14565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b5f6001821460e11b9050919050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612b9d612a98565b8786866040518563ffffffff1660e01b8152600401612bbf9493929190613f29565b6020604051808303815f875af1925050508015612bfa57506040513d601f19601f82011682018060405250810190612bf79190613f87565b60015b612c70573d805f8114612c28576040519150601f19603f3d011682016040523d82523d5f602084013e612c2d565b606091505b505f815103612c68576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612d1f577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612d1557612d146139c8565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612d5c576d04ee2d6d415b85acef81000000008381612d5257612d516139c8565b5b0492506020810190505b662386f26fc100008310612d8b57662386f26fc100008381612d8157612d806139c8565b5b0492506010810190505b6305f5e1008310612db4576305f5e1008381612daa57612da96139c8565b5b0492506008810190505b6127108310612dd9576127108381612dcf57612dce6139c8565b5b0492506004810190505b60648310612dfc5760648381612df257612df16139c8565b5b0492506002810190505b600a8310612e0b576001810190505b80915050919050565b5f9392505050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612e6181612e2d565b8114612e6b575f80fd5b50565b5f81359050612e7c81612e58565b92915050565b5f60208284031215612e9757612e96612e25565b5b5f612ea484828501612e6e565b91505092915050565b5f8115159050919050565b612ec181612ead565b82525050565b5f602082019050612eda5f830184612eb8565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015612f17578082015181840152602081019050612efc565b5f8484015250505050565b5f601f19601f8301169050919050565b5f612f3c82612ee0565b612f468185612eea565b9350612f56818560208601612efa565b612f5f81612f22565b840191505092915050565b5f6020820190508181035f830152612f828184612f32565b905092915050565b5f819050919050565b612f9c81612f8a565b8114612fa6575f80fd5b50565b5f81359050612fb781612f93565b92915050565b5f60208284031215612fd257612fd1612e25565b5b5f612fdf84828501612fa9565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61301182612fe8565b9050919050565b61302181613007565b82525050565b5f60208201905061303a5f830184613018565b92915050565b61304981613007565b8114613053575f80fd5b50565b5f8135905061306481613040565b92915050565b5f80604083850312156130805761307f612e25565b5b5f61308d85828601613056565b925050602061309e85828601612fa9565b9150509250929050565b6130b181612f8a565b82525050565b5f6020820190506130ca5f8301846130a8565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f8401126130f1576130f06130d0565b5b8235905067ffffffffffffffff81111561310e5761310d6130d4565b5b60208301915083600182028301111561312a576131296130d8565b5b9250929050565b5f806020838503121561314757613146612e25565b5b5f83013567ffffffffffffffff81111561316457613163612e29565b5b613170858286016130dc565b92509250509250929050565b5f805f6060848603121561319357613192612e25565b5b5f6131a086828701613056565b93505060206131b186828701613056565b92505060406131c286828701612fa9565b9150509250925092565b5f80604083850312156131e2576131e1612e25565b5b5f6131ef85828601612fa9565b925050602061320085828601612fa9565b9150509250929050565b5f60408201905061321d5f830185613018565b61322a60208301846130a8565b9392505050565b61323a81612ead565b8114613244575f80fd5b50565b5f8135905061325581613231565b92915050565b5f805f6060848603121561327257613271612e25565b5b5f61327f86828701613056565b935050602061329086828701612fa9565b92505060406132a186828701613247565b9150509250925092565b5f602082840312156132c0576132bf612e25565b5b5f6132cd84828501613056565b91505092915050565b5f80604083850312156132ec576132eb612e25565b5b5f6132f985828601613056565b925050602061330a85828601613247565b9150509250929050565b5f6020828403121561332957613328612e25565b5b5f61333684828501613247565b91505092915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61337982612f22565b810181811067ffffffffffffffff8211171561339857613397613343565b5b80604052505050565b5f6133aa612e1c565b90506133b68282613370565b919050565b5f67ffffffffffffffff8211156133d5576133d4613343565b5b6133de82612f22565b9050602081019050919050565b828183375f83830152505050565b5f61340b613406846133bb565b6133a1565b9050828152602081018484840111156134275761342661333f565b5b6134328482856133eb565b509392505050565b5f82601f83011261344e5761344d6130d0565b5b813561345e8482602086016133f9565b91505092915050565b5f805f806080858703121561347f5761347e612e25565b5b5f61348c87828801613056565b945050602061349d87828801613056565b93505060406134ae87828801612fa9565b925050606085013567ffffffffffffffff8111156134cf576134ce612e29565b5b6134db8782880161343a565b91505092959194509250565b5f6bffffffffffffffffffffffff82169050919050565b613507816134e7565b8114613511575f80fd5b50565b5f81359050613522816134fe565b92915050565b5f806040838503121561353e5761353d612e25565b5b5f61354b85828601613056565b925050602061355c85828601613514565b9150509250929050565b5f67ffffffffffffffff8211156135805761357f613343565b5b61358982612f22565b9050602081019050919050565b5f6135a86135a384613566565b6133a1565b9050828152602081018484840111156135c4576135c361333f565b5b6135cf8482856133eb565b509392505050565b5f82601f8301126135eb576135ea6130d0565b5b81356135fb848260208601613596565b91505092915050565b5f6020828403121561361957613618612e25565b5b5f82013567ffffffffffffffff81111561363657613635612e29565b5b613642848285016135d7565b91505092915050565b5f806040838503121561366157613660612e25565b5b5f61366e85828601613056565b925050602061367f85828601613056565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806136cd57607f821691505b6020821081036136e0576136df613689565b5b50919050565b5f82905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261374c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613711565b6137568683613711565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61379161378c61378784612f8a565b61376e565b612f8a565b9050919050565b5f819050919050565b6137aa83613777565b6137be6137b682613798565b84845461371d565b825550505050565b5f90565b6137d26137c6565b6137dd8184846137a1565b505050565b5b81811015613800576137f55f826137ca565b6001810190506137e3565b5050565b601f82111561384557613816816136f0565b61381f84613702565b8101602085101561382e578190505b61384261383a85613702565b8301826137e2565b50505b505050565b5f82821c905092915050565b5f6138655f198460080261384a565b1980831691505092915050565b5f61387d8383613856565b9150826002028217905092915050565b61389783836136e6565b67ffffffffffffffff8111156138b0576138af613343565b5b6138ba82546136b6565b6138c5828285613804565b5f601f8311600181146138f2575f84156138e0578287013590505b6138ea8582613872565b865550613951565b601f198416613900866136f0565b5f5b8281101561392757848901358255600182019150602085019450602081019050613902565b868310156139445784890135613940601f891682613856565b8355505b6001600288020188555050505b50505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61399182612f8a565b915061399c83612f8a565b92508282026139aa81612f8a565b915082820484148315176139c1576139c061395a565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6139ff82612f8a565b9150613a0a83612f8a565b925082613a1a57613a196139c8565b5b828204905092915050565b5f81905092915050565b50565b5f613a3d5f83613a25565b9150613a4882613a2f565b5f82019050919050565b5f613a5c82613a32565b9150819050919050565b7f4d696e74696e67206973206e6f7420796574206f70656e2e00000000000000005f82015250565b5f613a9a601883612eea565b9150613aa582613a66565b602082019050919050565b5f6020820190508181035f830152613ac781613a8e565b9050919050565b5f613ad882612f8a565b9150613ae383612f8a565b9250828201905080821115613afb57613afa61395a565b5b92915050565b7f54696d65206973206f766572206e6f77000000000000000000000000000000005f82015250565b5f613b35601083612eea565b9150613b4082613b01565b602082019050919050565b5f6020820190508181035f830152613b6281613b29565b9050919050565b7f45746865722073656e74206973206e6f7420636f72726563742e0000000000005f82015250565b5f613b9d601a83612eea565b9150613ba882613b69565b602082019050919050565b5f6020820190508181035f830152613bca81613b91565b9050919050565b5f613bdb82612f8a565b9150613be683612f8a565b9250828203905081811115613bfe57613bfd61395a565b5b92915050565b5f606082019050613c175f830186613018565b613c2460208301856130a8565b613c316040830184612eb8565b949350505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f5f8201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b5f613c93602f83612eea565b9150613c9e82613c39565b604082019050919050565b5f6020820190508181035f830152613cc081613c87565b9050919050565b5f81905092915050565b5f613cdb82612ee0565b613ce58185613cc7565b9350613cf5818560208601612efa565b80840191505092915050565b5f8154613d0d816136b6565b613d178186613cc7565b9450600182165f8114613d315760018114613d4657613d78565b60ff1983168652811515820286019350613d78565b613d4f856136f0565b5f5b83811015613d7057815481890152600182019150602081019050613d51565b838801955050505b50505092915050565b5f613d8c8286613cd1565b9150613d988285613cd1565b9150613da48284613d01565b9150819050949350505050565b613dba82612ee0565b67ffffffffffffffff811115613dd357613dd2613343565b5b613ddd82546136b6565b613de8828285613804565b5f60209050601f831160018114613e19575f8415613e07578287015190505b613e118582613872565b865550613e78565b601f198416613e27866136f0565b5f5b82811015613e4e57848901518255600182019150602085019450602081019050613e29565b86831015613e6b5784890151613e67601f891682613856565b8355505b6001600288020188555050505b505050505050565b5f613e9a613e95613e90846134e7565b61376e565b612f8a565b9050919050565b613eaa81613e80565b82525050565b5f604082019050613ec35f830185613ea1565b613ed060208301846130a8565b9392505050565b5f81519050919050565b5f82825260208201905092915050565b5f613efb82613ed7565b613f058185613ee1565b9350613f15818560208601612efa565b613f1e81612f22565b840191505092915050565b5f608082019050613f3c5f830187613018565b613f496020830186613018565b613f5660408301856130a8565b8181036060830152613f688184613ef1565b905095945050505050565b5f81519050613f8181612e58565b92915050565b5f60208284031215613f9c57613f9b612e25565b5b5f613fa984828501613f73565b9150509291505056fea2646970667358221220e4eeb855fde223fcbf7d48c9ca912f1cc2eaf5521b01ee295d2e07e848c3f5fd64736f6c63430008160033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000047b757af6da640aaf89589edbe485981a046f31300000000000000000000000000000000000000000000000000000000000001f400000000000000000000000059de7273191e6bf1907d614e94ecfbe8e5fb7318
-----Decoded View---------------
Arg [0] : _royaltyReceiver (address): 0x47B757Af6da640aaf89589EdBe485981a046F313
Arg [1] : _royaltyFraction (uint96): 500
Arg [2] : initialOwner (address): 0x59dE7273191E6bf1907d614e94eCFbe8e5FB7318
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000047b757af6da640aaf89589edbe485981a046f313
Arg [1] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [2] : 00000000000000000000000059de7273191e6bf1907d614e94ecfbe8e5fb7318
Deployed Bytecode Sourcemap
101072:8521:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102422:274;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59564:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66502:268;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;108012:232;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101470:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105428:269;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55137:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;108404:272;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;33154:429;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;104185:96;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;107251:207;;;;;;;;;;;;;:::i;:::-;;106183:621;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;108836:280;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;105136:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101384:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61054:202;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101425:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56321:283;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39242:103;;;;;;;;;;;;;:::i;:::-;;106016:157;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;106977:95;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;38567:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;107080:89;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;59740:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;107618:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101341:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101721;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101678;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104473:160;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;109276:314;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101626:45;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104856:170;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101297:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101548:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103078:649;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;106814:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;102919:151;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103892:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105840:168;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67533:214;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39500:220;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101583:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102422:274;102553:4;102595:38;102621:11;102595:25;:38::i;:::-;:93;;;;102650:38;102676:11;102650:25;:38::i;:::-;102595:93;102575:113;;102422:274;;;:::o;59564:100::-;59618:13;59651:5;59644:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59564:100;:::o;66502:268::-;66623:7;66653:16;66661:7;66653;:16::i;:::-;66648:64;;66678:34;;;;;;;;;;;;;;66648:64;66732:15;:24;66748:7;66732:24;;;;;;;;;;;:30;;;;;;;;;;;;66725:37;;66502:268;;;:::o;108012:232::-;108152:8;108162:24;;;;;;;;;;;99436:7;99433:1138;;;99565:22;99559:4;99552:36;99666:9;99660:4;99653:23;99818:8;99814:2;99810:17;99806:2;99802:26;99796:4;99789:40;100178:4;100147;100116;100085;100033:25;100001:5;99964:241;99932:503;;100347:16;100341:4;100335;100320:44;100399:16;100393:4;100386:30;99932:503;100554:1;100548:4;100541:15;99433:1138;108204:32:::1;108218:8;108228:7;108204:13;:32::i;:::-;108012:232:::0;;;;:::o;101470:35::-;;;;:::o;105428:269::-;102292:14;:23;102307:7;;;;102292:23;;;;;;;;;;;;;;;;;;;;;;;;;;;102288:52;;;102324:16;;;;;;;;;;;;;;102288:52;38453:13:::1;:11;:13::i;:::-;105595:1:::2;105569:14;105563:28;;;;;:::i;:::-;;;:33;105559:85;;105618:26;;;;;;;;;;;;;;105559:85;105674:15;;105657:14;:32;;;;;;;:::i;:::-;;105428:269:::0;;:::o;55137:323::-;55198:7;55426:15;:13;:15::i;:::-;55411:12;;55395:13;;:28;:46;55388:53;;55137:323;:::o;108404:272::-;108583:4;108589:24;;;;;;;;;;;96951:7;96948:1892;;;97164:8;97156:4;97152:2;97148:13;97144:2;97140:22;97137:36;97127:1698;;97479:22;97473:4;97466:36;97588:9;97582:4;97575:23;97681:8;97675:4;97668:22;98075:4;98040;98005;97970;97914:25;97878:5;97837:269;97801:555;;98260:16;98254:4;98248;98233:44;98316:16;98310:4;98303:30;97801:555;98804:1;98798:4;98791:15;97127:1698;96948:1892;108631:37:::1;108650:4;108656:2;108660:7;108631:18;:37::i;:::-;108404:272:::0;;;;;:::o;33154:429::-;33240:7;33249;33269:26;33298:17;:26;33316:7;33298:26;;;;;;;;;;;33269:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33369:1;33341:30;;:7;:16;;;:30;;;33337:92;;33398:19;33388:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33337:92;33441:21;33505:17;:15;:17::i;:::-;33465:57;;33478:7;:23;;;33466:35;;:9;:35;;;;:::i;:::-;33465:57;;;;:::i;:::-;33441:81;;33543:7;:16;;;33561:13;33535:40;;;;;;33154:429;;;;;:::o;104185:96::-;38453:13;:11;:13::i;:::-;104269:4:::1;104248:14;:18;104263:2;104248:18;;;;;;;;;;;;;;;;;;:25;;;;;;;;;;;;;;;;;;104185:96:::0;:::o;107251:207::-;38453:13;:11;:13::i;:::-;107302:12:::1;107328:10;107320:24;;107366:21;107320:82;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107301:101;;;107418:7;107413:37;;107434:16;;;;;;;;;;;;;;107413:37;107290:168;107251:207::o:0;106183:621::-;106335:4;106315:24;;:16;;;;;;;;;;;:24;;;106307:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;106419:11;;106407:9;;:23;;;;:::i;:::-;106387:15;:44;;106379:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;106463:17;106494:9;;106483:8;:20;;;;:::i;:::-;106463:40;;106535:9;106522;:22;;106514:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;106586:19;106592:2;106596:8;106586:5;:19::i;:::-;106627:5;106616:4;:8;106621:2;106616:8;;;;;;;;;;;;;;;;:16;;;;;;;;;;;;;;;;;;106659:9;106647;:21;106643:105;;;106693:10;106685:28;;:51;106726:9;106714;:21;;;;:::i;:::-;106685:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;106643:105;106765:31;106776:2;106780:8;106790:5;106765:31;;;;;;;;:::i;:::-;;;;;;;;106296:508;106183:621;;;:::o;108836:280::-;109019:4;109025:24;;;;;;;;;;;96951:7;96948:1892;;;97164:8;97156:4;97152:2;97148:13;97144:2;97140:22;97137:36;97127:1698;;97479:22;97473:4;97466:36;97588:9;97582:4;97575:23;97681:8;97675:4;97668:22;98075:4;98040;98005;97970;97914:25;97878:5;97837:269;97801:555;;98260:16;98254:4;98248;98233:44;98316:16;98310:4;98303:30;97801:555;98804:1;98798:4;98791:15;97127:1698;96948:1892;109067:41:::1;109090:4;109096:2;109100:7;109067:22;:41::i;:::-;108836:280:::0;;;;;:::o;105136:155::-;102292:14;:23;102307:7;;;;102292:23;;;;;;;;;;;;;;;;;;;;;;;;;;;102288:52;;;102324:16;;;;;;;;;;;;;;102288:52;38453:13:::1;:11;:13::i;:::-;105272:11:::2;;105256:13;:27;;;;;;;:::i;:::-;;105136:155:::0;;:::o;101384:32::-;;;;:::o;61054:202::-;61171:7;61219:27;61238:7;61219:18;:27::i;:::-;61196:52;;61054:202;;;:::o;101425:38::-;;;;:::o;56321:283::-;56438:7;56484:1;56467:19;;:5;:19;;;56463:60;;56495:28;;;;;;;;;;;;;;56463:60;50480:13;56541:18;:25;56560:5;56541:25;;;;;;;;;;;;;;;;:55;56534:62;;56321:283;;;:::o;39242:103::-;38453:13;:11;:13::i;:::-;39307:30:::1;39334:1;39307:18;:30::i;:::-;39242:103::o:0;106016:157::-;102292:14;:23;102307:7;;;;102292:23;;;;;;;;;;;;;;;;;;;;;;;;;;;102288:52;;;102324:16;;;;;;;;;;;;;;102288:52;38453:13:::1;:11;:13::i;:::-;106146:19:::2;106152:2;106156:8;106146:5;:19::i;:::-;106016:157:::0;;:::o;106977:95::-;38453:13;:11;:13::i;:::-;107059:5:::1;107045:11;:19;;;;106977:95:::0;:::o;38567:87::-;38613:7;38640:6;;;;;;;;;;;38633:13;;38567:87;:::o;107080:89::-;38453:13;:11;:13::i;:::-;107155:6:::1;107143:9;:18;;;;107080:89:::0;:::o;59740:104::-;59796:13;59829:7;59822:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59740:104;:::o;107618:234::-;107749:8;107759:24;;;;;;;;;;;99436:7;99433:1138;;;99565:22;99559:4;99552:36;99666:9;99660:4;99653:23;99818:8;99814:2;99810:17;99806:2;99802:26;99796:4;99789:40;100178:4;100147;100116;100085;100033:25;100001:5;99964:241;99932:503;;100347:16;100341:4;100335;100320:44;100399:16;100393:4;100386:30;99932:503;100554:1;100548:4;100541:15;99433:1138;107801:43:::1;107825:8;107835;107801:23;:43::i;:::-;107618:234:::0;;;;:::o;101341:36::-;101376:1;101341:36;:::o;101721:::-;;;;;;;;;;;;;;;;;;;;;;:::o;101678:::-;;;;;;;;;;;;;:::o;104473:160::-;102292:14;:23;102307:7;;;;102292:23;;;;;;;;;;;;;;;;;;;;;;;;;;;102288:52;;;102324:16;;;;;;;;;;;;;;102288:52;38453:13:::1;:11;:13::i;:::-;104620:5:::2;104593:24;;:32;;;;;;;;;;;;;;;;;;104473:160:::0;:::o;109276:314::-;109487:4;109493:24;;;;;;;;;;;96951:7;96948:1892;;;97164:8;97156:4;97152:2;97148:13;97144:2;97140:22;97137:36;97127:1698;;97479:22;97473:4;97466:36;97588:9;97582:4;97575:23;97681:8;97675:4;97668:22;98075:4;98040;98005;97970;97914:25;97878:5;97837:269;97801:555;;98260:16;98254:4;98248;98233:44;98316:16;98310:4;98303:30;97801:555;98804:1;98798:4;98791:15;97127:1698;96948:1892;109535:47:::1;109558:4;109564:2;109568:7;109577:4;109535:22;:47::i;:::-;109276:314:::0;;;;;;:::o;101626:45::-;;;;;;;;;;;;;;;;;;;;;;:::o;104856:170::-;38453:13;:11;:13::i;:::-;104973:45:::1;104992:8;105002:15;104973:18;:45::i;:::-;104856:170:::0;;:::o;101297:37::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;101548:28::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;103078:649::-;103196:13;103249:16;103257:7;103249;:16::i;:::-;103227:113;;;;;;;;;;;;:::i;:::-;;;;;;;;;103353:28;103384:10;:8;:10::i;:::-;103353:41;;103456:1;103431:14;103425:28;:32;:294;;;;;;;;;;;;;;;;;103549:14;103590:25;103607:7;103590:16;:25::i;:::-;103642:13;103506:172;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;103425:294;103405:314;;;103078:649;;;:::o;106814:155::-;38453:13;:11;:13::i;:::-;106908:11:::1;106889:16;;:30;;;;;;;;;;;;;;;;;;106946:15;106934:9;:27;;;;106814:155:::0;:::o;102919:151::-;38453:13;:11;:13::i;:::-;103045:17:::1;103029:13;:33;;;;;;:::i;:::-;;102919:151:::0;:::o;103892:119::-;103954:7;103981:22;103995:7;103981:13;:22::i;:::-;103974:29;;103892:119;;;:::o;105840:168::-;102292:14;:23;102307:7;;;;102292:23;;;;;;;;;;;;;;;;;;;;;;;;;;;102288:52;;;102324:16;;;;;;;;;;;;;;102288:52;38453:13:::1;:11;:13::i;:::-;101376:1:::2;105912:14;:12;:14::i;:::-;:26;105908:62;;105947:23;;;;;;;;;;;;;;105908:62;105981:19;105987:2;101376:1;105981:5;:19::i;:::-;105840:168:::0;:::o;67533:214::-;67675:4;67704:18;:25;67723:5;67704:25;;;;;;;;;;;;;;;:35;67730:8;67704:35;;;;;;;;;;;;;;;;;;;;;;;;;67697:42;;67533:214;;;;:::o;39500:220::-;38453:13;:11;:13::i;:::-;39605:1:::1;39585:22;;:8;:22;;::::0;39581:93:::1;;39659:1;39631:31;;;;;;;;;;;:::i;:::-;;;;;;;;39581:93;39684:28;39703:8;39684:18;:28::i;:::-;39500:220:::0;:::o;101583:36::-;;;;;;;;;;;;;:::o;58612:689::-;58742:4;59086:10;59071:25;;:11;:25;;;;:102;;;;59163:10;59148:25;;:11;:25;;;;59071:102;:179;;;;59240:10;59225:25;;:11;:25;;;;59071:179;59051:199;;58612:689;;;:::o;32884:215::-;32986:4;33025:26;33010:41;;;:11;:41;;;;:81;;;;33055:36;33079:11;33055:23;:36::i;:::-;33010:81;33003:88;;32884:215;;;:::o;68005:282::-;68070:4;68126:7;68107:15;:13;:15::i;:::-;:26;;:66;;;;;68160:13;;68150:7;:23;68107:66;:153;;;;;68259:1;51256:8;68211:17;:26;68229:7;68211:26;;;;;;;;;;;;:44;:49;68107:153;68087:173;;68005:282;;;:::o;65894:449::-;66024:13;66040:16;66048:7;66040;:16::i;:::-;66024:32;;66096:5;66073:28;;:19;:17;:19::i;:::-;:28;;;66069:175;;66121:44;66138:5;66145:19;:17;:19::i;:::-;66121:16;:44::i;:::-;66116:128;;66193:35;;;;;;;;;;;;;;66116:128;66069:175;66289:2;66256:15;:24;66272:7;66256:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;66327:7;66323:2;66307:28;;66316:5;66307:28;;;;;;;;;;;;66013:330;65894:449;;:::o;38732:166::-;38803:12;:10;:12::i;:::-;38792:23;;:7;:5;:7::i;:::-;:23;;;38788:103;;38866:12;:10;:12::i;:::-;38839:40;;;;;;;;;;;:::i;:::-;;;;;;;;38788:103;38732:166::o;54653:92::-;54709:7;54736:1;54729:8;;54653:92;:::o;70273:3003::-;70415:27;70445;70464:7;70445:18;:27::i;:::-;70415:57;;70530:4;70489:45;;70505:19;70489:45;;;70485:99;;70556:28;;;;;;;;;;;;;;70485:99;70612:27;70654:23;70691:35;70718:7;70691:26;:35::i;:::-;70597:129;;;;70840:134;70883:15;70917:4;70940:19;:17;:19::i;:::-;70840:24;:134::i;:::-;70821:287;;71004:43;71021:4;71027:19;:17;:19::i;:::-;71004:16;:43::i;:::-;70999:109;;71073:35;;;;;;;;;;;;;;70999:109;70821:287;71139:1;71125:16;;:2;:16;;;71121:52;;71150:23;;;;;;;;;;;;;;71121:52;71186:43;71208:4;71214:2;71218:7;71227:1;71186:21;:43::i;:::-;71322:15;71319:160;;;71462:1;71441:19;71434:30;71319:160;71859:18;:24;71878:4;71859:24;;;;;;;;;;;;;;;;71857:26;;;;;;;;;;;;71928:18;:22;71947:2;71928:22;;;;;;;;;;;;;;;;71926:24;;;;;;;;;;;72250:167;72287:2;72357:45;72372:4;72378:2;72382:19;72357:14;:45::i;:::-;51536:8;72308:94;72250:18;:167::i;:::-;72221:17;:26;72239:7;72221:26;;;;;;;;;;;:196;;;;72588:1;51536:8;72537:19;:47;:52;72533:627;;72610:19;72642:1;72632:7;:11;72610:33;;72799:1;72765:17;:30;72783:11;72765:30;;;;;;;;;;;;:35;72761:384;;72903:13;;72888:11;:28;72884:242;;73083:19;73050:17;:30;73068:11;73050:30;;;;;;;;;;;:52;;;;72884:242;72761:384;72591:569;72533:627;73207:7;73203:2;73188:27;;73197:4;73188:27;;;;;;;;;;;;73226:42;73247:4;73253:2;73257:7;73266:1;73226:20;:42::i;:::-;70404:2872;;;70273:3003;;;:::o;33865:97::-;33923:6;33949:5;33942:12;;33865:97;:::o;77947:3021::-;78020:20;78043:13;;78020:36;;78083:1;78071:8;:13;78067:44;;78093:18;;;;;;;;;;;;;;78067:44;78124:61;78154:1;78158:2;78162:12;78176:8;78124:21;:61::i;:::-;78702:1;50618:2;78672:1;:26;;78671:32;78642:8;:62;78599:18;:22;78618:2;78599:22;;;;;;;;;;;;;;;;:105;;;;;;;;;;;78981:160;79018:2;79093:33;79116:1;79120:2;79124:1;79093:14;:33::i;:::-;79039:30;79060:8;79039:20;:30::i;:::-;:87;78981:18;:160::i;:::-;78947:17;:31;78965:12;78947:31;;;;;;;;;;;:194;;;;79158:16;79189:11;79218:8;79203:12;:23;79189:37;;79739:16;79735:2;79731:25;79719:37;;80111:12;80071:8;80030:1;79968:25;79909:1;79848;79821:335;80482:1;80468:12;80464:20;80422:346;80523:3;80514:7;80511:16;80422:346;;80741:7;80731:8;80728:1;80701:25;80698:1;80695;80690:59;80576:1;80567:7;80563:15;80552:26;;80422:346;;;80426:77;80813:1;80801:8;:13;80797:45;;80823:19;;;;;;;;;;;;;;80797:45;80875:3;80859:13;:19;;;;78373:2517;;80900:60;80929:1;80933:2;80937:12;80951:8;80900:20;:60::i;:::-;78009:2959;77947:3021;;:::o;73372:193::-;73518:39;73535:4;73541:2;73545:7;73518:39;;;;;;;;;;;;:16;:39::i;:::-;73372:193;;;:::o;62341:1307::-;62435:7;62460:12;62475:7;62460:22;;62543:4;62524:15;:13;:15::i;:::-;:23;62520:1061;;62577:13;;62570:4;:20;62566:1015;;;62615:14;62632:17;:23;62650:4;62632:23;;;;;;;;;;;;62615:40;;62749:1;51256:8;62721:6;:24;:29;62717:845;;63386:113;63403:1;63393:6;:11;63386:113;;63446:17;:25;63464:6;;;;;;;63446:25;;;;;;;;;;;;63437:34;;63386:113;;;63532:6;63525:13;;;;;;62717:845;62592:989;62566:1015;62520:1061;63609:31;;;;;;;;;;;;;;62341:1307;;;;:::o;39880:191::-;39954:16;39973:6;;;;;;;;;;;39954:25;;39999:8;39990:6;;:17;;;;;;;;;;;;;;;;;;40054:8;40023:40;;40044:8;40023:40;;;;;;;;;;;;39943:128;39880:191;:::o;67110:266::-;67289:8;67237:18;:39;67256:19;:17;:19::i;:::-;67237:39;;;;;;;;;;;;;;;:49;67277:8;67237:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;67349:8;67313:55;;67328:19;:17;:19::i;:::-;67313:55;;;67359:8;67313:55;;;;;;:::i;:::-;;;;;;;;67110:266;;:::o;74163:407::-;74338:31;74351:4;74357:2;74361:7;74338:12;:31::i;:::-;74402:1;74384:2;:14;;;:19;74380:183;;74423:56;74454:4;74460:2;74464:7;74473:5;74423:30;:56::i;:::-;74418:145;;74507:40;;;;;;;;;;;;;;74418:145;74380:183;74163:407;;;;:::o;34233:518::-;34328:19;34350:17;:15;:17::i;:::-;34328:39;;;;34397:11;34382:12;:26;;;34378:176;;;34516:12;34530:11;34487:55;;;;;;;;;;;;:::i;:::-;;;;;;;;34378:176;34588:1;34568:22;;:8;:22;;;34564:110;;34659:1;34614:48;;;;;;;;;;;:::i;:::-;;;;;;;;34564:110;34708:35;;;;;;;;34720:8;34708:35;;;;;;34730:12;34708:35;;;;;34686:19;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34317:434;34233:518;;:::o;102797:114::-;102857:13;102890;102883:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102797:114;:::o;17601:718::-;17657:13;17708:14;17745:1;17725:17;17736:5;17725:10;:17::i;:::-;:21;17708:38;;17761:20;17795:6;17784:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17761:41;;17817:11;17946:6;17942:2;17938:15;17930:6;17926:28;17919:35;;17983:290;17990:4;17983:290;;;18015:5;;;;;;;;18157:10;18152:2;18145:5;18141:14;18136:32;18131:3;18123:46;18215:2;18206:11;;;;;;:::i;:::-;;;;;18249:1;18240:5;:10;17983:290;18236:21;17983:290;18294:6;18287:13;;;;;17601:718;;;:::o;56686:204::-;56747:7;50480:13;50618:2;56788:18;:25;56807:5;56788:25;;;;;;;;;;;;;;;;:50;;56787:95;56767:115;;56686:204;;;:::o;55558:296::-;55613:7;55820:15;:13;:15::i;:::-;55804:13;;:31;55797:38;;55558:296;:::o;29791:148::-;29867:4;29906:25;29891:40;;;:11;:40;;;;29884:47;;29791:148;;;:::o;91222:105::-;91282:7;91309:10;91302:17;;91222:105;:::o;36683:98::-;36736:7;36763:10;36756:17;;36683:98;:::o;69168:485::-;69270:27;69299:23;69340:38;69381:15;:24;69397:7;69381:24;;;;;;;;;;;69340:65;;69558:18;69535:41;;69615:19;69609:26;69590:45;;69520:126;69168:485;;;:::o;68396:659::-;68545:11;68710:16;68703:5;68699:28;68690:37;;68870:16;68859:9;68855:32;68842:45;;69020:15;69009:9;69006:30;68998:5;68987:9;68984:20;68981:56;68971:66;;68396:659;;;;;:::o;75232:159::-;;;;;:::o;90531:311::-;90666:7;90686:16;51660:3;90712:19;:41;;90686:68;;51660:3;90780:31;90791:4;90797:2;90801:9;90780:10;:31::i;:::-;90772:40;;:62;;90765:69;;;90531:311;;;;;:::o;64228:531::-;64335:14;64508:16;64501:5;64497:28;64488:37;;64720:5;64706:11;64681:23;64677:41;64674:52;64650:5;64629:112;64619:122;;64228:531;;;;:::o;76056:158::-;;;;;:::o;64861:356::-;64958:14;65196:1;65186:8;65183:15;65157:24;65153:46;65143:56;;64861:356;;;:::o;76654:831::-;76817:4;76876:2;76851:45;;;76915:19;:17;:19::i;:::-;76953:4;76976:7;77002:5;76851:171;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;76834:644;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77253:1;77236:6;:13;:18;77232:235;;77282:40;;;;;;;;;;;;;;77232:235;77425:6;77419:13;77410:6;77406:2;77402:15;77395:38;76834:644;77122:54;;;77095:81;;;:6;:81;;;;77071:105;;;76654:831;;;;;;:::o;14005:948::-;14058:7;14078:14;14095:1;14078:18;;14145:8;14136:5;:17;14132:106;;14183:8;14174:17;;;;;;:::i;:::-;;;;;14220:2;14210:12;;;;14132:106;14265:8;14256:5;:17;14252:106;;14303:8;14294:17;;;;;;:::i;:::-;;;;;14340:2;14330:12;;;;14252:106;14385:8;14376:5;:17;14372:106;;14423:8;14414:17;;;;;;:::i;:::-;;;;;14460:2;14450:12;;;;14372:106;14505:7;14496:5;:16;14492:103;;14542:7;14533:16;;;;;;:::i;:::-;;;;;14578:1;14568:11;;;;14492:103;14622:7;14613:5;:16;14609:103;;14659:7;14650:16;;;;;;:::i;:::-;;;;;14695:1;14685:11;;;;14609:103;14739:7;14730:5;:16;14726:103;;14776:7;14767:16;;;;;;:::i;:::-;;;;;14812:1;14802:11;;;;14726:103;14856:7;14847:5;:16;14843:68;;14894:1;14884:11;;;;14843:68;14939:6;14932:13;;;14005:948;;;:::o;90232:147::-;90369:6;90232:147;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:118::-;4977:24;4995:5;4977:24;:::i;:::-;4972:3;4965:37;4890:118;;:::o;5014:222::-;5107:4;5145:2;5134:9;5130:18;5122:26;;5158:71;5226:1;5215:9;5211:17;5202:6;5158:71;:::i;:::-;5014:222;;;;:::o;5242:117::-;5351:1;5348;5341:12;5365:117;5474:1;5471;5464:12;5488:117;5597:1;5594;5587:12;5625:553;5683:8;5693:6;5743:3;5736:4;5728:6;5724:17;5720:27;5710:122;;5751:79;;:::i;:::-;5710:122;5864:6;5851:20;5841:30;;5894:18;5886:6;5883:30;5880:117;;;5916:79;;:::i;:::-;5880:117;6030:4;6022:6;6018:17;6006:29;;6084:3;6076:4;6068:6;6064:17;6054:8;6050:32;6047:41;6044:128;;;6091:79;;:::i;:::-;6044:128;5625:553;;;;;:::o;6184:529::-;6255:6;6263;6312:2;6300:9;6291:7;6287:23;6283:32;6280:119;;;6318:79;;:::i;:::-;6280:119;6466:1;6455:9;6451:17;6438:31;6496:18;6488:6;6485:30;6482:117;;;6518:79;;:::i;:::-;6482:117;6631:65;6688:7;6679:6;6668:9;6664:22;6631:65;:::i;:::-;6613:83;;;;6409:297;6184:529;;;;;:::o;6719:619::-;6796:6;6804;6812;6861:2;6849:9;6840:7;6836:23;6832:32;6829:119;;;6867:79;;:::i;:::-;6829:119;6987:1;7012:53;7057:7;7048:6;7037:9;7033:22;7012:53;:::i;:::-;7002:63;;6958:117;7114:2;7140:53;7185:7;7176:6;7165:9;7161:22;7140:53;:::i;:::-;7130:63;;7085:118;7242:2;7268:53;7313:7;7304:6;7293:9;7289:22;7268:53;:::i;:::-;7258:63;;7213:118;6719:619;;;;;:::o;7344:474::-;7412:6;7420;7469:2;7457:9;7448:7;7444:23;7440:32;7437:119;;;7475:79;;:::i;:::-;7437:119;7595:1;7620:53;7665:7;7656:6;7645:9;7641:22;7620:53;:::i;:::-;7610:63;;7566:117;7722:2;7748:53;7793:7;7784:6;7773:9;7769:22;7748:53;:::i;:::-;7738:63;;7693:118;7344:474;;;;;:::o;7824:332::-;7945:4;7983:2;7972:9;7968:18;7960:26;;7996:71;8064:1;8053:9;8049:17;8040:6;7996:71;:::i;:::-;8077:72;8145:2;8134:9;8130:18;8121:6;8077:72;:::i;:::-;7824:332;;;;;:::o;8162:116::-;8232:21;8247:5;8232:21;:::i;:::-;8225:5;8222:32;8212:60;;8268:1;8265;8258:12;8212:60;8162:116;:::o;8284:133::-;8327:5;8365:6;8352:20;8343:29;;8381:30;8405:5;8381:30;:::i;:::-;8284:133;;;;:::o;8423:613::-;8497:6;8505;8513;8562:2;8550:9;8541:7;8537:23;8533:32;8530:119;;;8568:79;;:::i;:::-;8530:119;8688:1;8713:53;8758:7;8749:6;8738:9;8734:22;8713:53;:::i;:::-;8703:63;;8659:117;8815:2;8841:53;8886:7;8877:6;8866:9;8862:22;8841:53;:::i;:::-;8831:63;;8786:118;8943:2;8969:50;9011:7;9002:6;8991:9;8987:22;8969:50;:::i;:::-;8959:60;;8914:115;8423:613;;;;;:::o;9042:329::-;9101:6;9150:2;9138:9;9129:7;9125:23;9121:32;9118:119;;;9156:79;;:::i;:::-;9118:119;9276:1;9301:53;9346:7;9337:6;9326:9;9322:22;9301:53;:::i;:::-;9291:63;;9247:117;9042:329;;;;:::o;9377:468::-;9442:6;9450;9499:2;9487:9;9478:7;9474:23;9470:32;9467:119;;;9505:79;;:::i;:::-;9467:119;9625:1;9650:53;9695:7;9686:6;9675:9;9671:22;9650:53;:::i;:::-;9640:63;;9596:117;9752:2;9778:50;9820:7;9811:6;9800:9;9796:22;9778:50;:::i;:::-;9768:60;;9723:115;9377:468;;;;;:::o;9851:323::-;9907:6;9956:2;9944:9;9935:7;9931:23;9927:32;9924:119;;;9962:79;;:::i;:::-;9924:119;10082:1;10107:50;10149:7;10140:6;10129:9;10125:22;10107:50;:::i;:::-;10097:60;;10053:114;9851:323;;;;:::o;10180:117::-;10289:1;10286;10279:12;10303:180;10351:77;10348:1;10341:88;10448:4;10445:1;10438:15;10472:4;10469:1;10462:15;10489:281;10572:27;10594:4;10572:27;:::i;:::-;10564:6;10560:40;10702:6;10690:10;10687:22;10666:18;10654:10;10651:34;10648:62;10645:88;;;10713:18;;:::i;:::-;10645:88;10753:10;10749:2;10742:22;10532:238;10489:281;;:::o;10776:129::-;10810:6;10837:20;;:::i;:::-;10827:30;;10866:33;10894:4;10886:6;10866:33;:::i;:::-;10776:129;;;:::o;10911:307::-;10972:4;11062:18;11054:6;11051:30;11048:56;;;11084:18;;:::i;:::-;11048:56;11122:29;11144:6;11122:29;:::i;:::-;11114:37;;11206:4;11200;11196:15;11188:23;;10911:307;;;:::o;11224:146::-;11321:6;11316:3;11311;11298:30;11362:1;11353:6;11348:3;11344:16;11337:27;11224:146;;;:::o;11376:423::-;11453:5;11478:65;11494:48;11535:6;11494:48;:::i;:::-;11478:65;:::i;:::-;11469:74;;11566:6;11559:5;11552:21;11604:4;11597:5;11593:16;11642:3;11633:6;11628:3;11624:16;11621:25;11618:112;;;11649:79;;:::i;:::-;11618:112;11739:54;11786:6;11781:3;11776;11739:54;:::i;:::-;11459:340;11376:423;;;;;:::o;11818:338::-;11873:5;11922:3;11915:4;11907:6;11903:17;11899:27;11889:122;;11930:79;;:::i;:::-;11889:122;12047:6;12034:20;12072:78;12146:3;12138:6;12131:4;12123:6;12119:17;12072:78;:::i;:::-;12063:87;;11879:277;11818:338;;;;:::o;12162:943::-;12257:6;12265;12273;12281;12330:3;12318:9;12309:7;12305:23;12301:33;12298:120;;;12337:79;;:::i;:::-;12298:120;12457:1;12482:53;12527:7;12518:6;12507:9;12503:22;12482:53;:::i;:::-;12472:63;;12428:117;12584:2;12610:53;12655:7;12646:6;12635:9;12631:22;12610:53;:::i;:::-;12600:63;;12555:118;12712:2;12738:53;12783:7;12774:6;12763:9;12759:22;12738:53;:::i;:::-;12728:63;;12683:118;12868:2;12857:9;12853:18;12840:32;12899:18;12891:6;12888:30;12885:117;;;12921:79;;:::i;:::-;12885:117;13026:62;13080:7;13071:6;13060:9;13056:22;13026:62;:::i;:::-;13016:72;;12811:287;12162:943;;;;;;;:::o;13111:109::-;13147:7;13187:26;13180:5;13176:38;13165:49;;13111:109;;;:::o;13226:120::-;13298:23;13315:5;13298:23;:::i;:::-;13291:5;13288:34;13278:62;;13336:1;13333;13326:12;13278:62;13226:120;:::o;13352:137::-;13397:5;13435:6;13422:20;13413:29;;13451:32;13477:5;13451:32;:::i;:::-;13352:137;;;;:::o;13495:472::-;13562:6;13570;13619:2;13607:9;13598:7;13594:23;13590:32;13587:119;;;13625:79;;:::i;:::-;13587:119;13745:1;13770:53;13815:7;13806:6;13795:9;13791:22;13770:53;:::i;:::-;13760:63;;13716:117;13872:2;13898:52;13942:7;13933:6;13922:9;13918:22;13898:52;:::i;:::-;13888:62;;13843:117;13495:472;;;;;:::o;13973:308::-;14035:4;14125:18;14117:6;14114:30;14111:56;;;14147:18;;:::i;:::-;14111:56;14185:29;14207:6;14185:29;:::i;:::-;14177:37;;14269:4;14263;14259:15;14251:23;;13973:308;;;:::o;14287:425::-;14365:5;14390:66;14406:49;14448:6;14406:49;:::i;:::-;14390:66;:::i;:::-;14381:75;;14479:6;14472:5;14465:21;14517:4;14510:5;14506:16;14555:3;14546:6;14541:3;14537:16;14534:25;14531:112;;;14562:79;;:::i;:::-;14531:112;14652:54;14699:6;14694:3;14689;14652:54;:::i;:::-;14371:341;14287:425;;;;;:::o;14732:340::-;14788:5;14837:3;14830:4;14822:6;14818:17;14814:27;14804:122;;14845:79;;:::i;:::-;14804:122;14962:6;14949:20;14987:79;15062:3;15054:6;15047:4;15039:6;15035:17;14987:79;:::i;:::-;14978:88;;14794:278;14732:340;;;;:::o;15078:509::-;15147:6;15196:2;15184:9;15175:7;15171:23;15167:32;15164:119;;;15202:79;;:::i;:::-;15164:119;15350:1;15339:9;15335:17;15322:31;15380:18;15372:6;15369:30;15366:117;;;15402:79;;:::i;:::-;15366:117;15507:63;15562:7;15553:6;15542:9;15538:22;15507:63;:::i;:::-;15497:73;;15293:287;15078:509;;;;:::o;15593:474::-;15661:6;15669;15718:2;15706:9;15697:7;15693:23;15689:32;15686:119;;;15724:79;;:::i;:::-;15686:119;15844:1;15869:53;15914:7;15905:6;15894:9;15890:22;15869:53;:::i;:::-;15859:63;;15815:117;15971:2;15997:53;16042:7;16033:6;16022:9;16018:22;15997:53;:::i;:::-;15987:63;;15942:118;15593:474;;;;;:::o;16073:180::-;16121:77;16118:1;16111:88;16218:4;16215:1;16208:15;16242:4;16239:1;16232:15;16259:320;16303:6;16340:1;16334:4;16330:12;16320:22;;16387:1;16381:4;16377:12;16408:18;16398:81;;16464:4;16456:6;16452:17;16442:27;;16398:81;16526:2;16518:6;16515:14;16495:18;16492:38;16489:84;;16545:18;;:::i;:::-;16489:84;16310:269;16259:320;;;:::o;16585:97::-;16644:6;16672:3;16662:13;;16585:97;;;;:::o;16688:141::-;16737:4;16760:3;16752:11;;16783:3;16780:1;16773:14;16817:4;16814:1;16804:18;16796:26;;16688:141;;;:::o;16835:93::-;16872:6;16919:2;16914;16907:5;16903:14;16899:23;16889:33;;16835:93;;;:::o;16934:107::-;16978:8;17028:5;17022:4;17018:16;16997:37;;16934:107;;;;:::o;17047:393::-;17116:6;17166:1;17154:10;17150:18;17189:97;17219:66;17208:9;17189:97;:::i;:::-;17307:39;17337:8;17326:9;17307:39;:::i;:::-;17295:51;;17379:4;17375:9;17368:5;17364:21;17355:30;;17428:4;17418:8;17414:19;17407:5;17404:30;17394:40;;17123:317;;17047:393;;;;;:::o;17446:60::-;17474:3;17495:5;17488:12;;17446:60;;;:::o;17512:142::-;17562:9;17595:53;17613:34;17622:24;17640:5;17622:24;:::i;:::-;17613:34;:::i;:::-;17595:53;:::i;:::-;17582:66;;17512:142;;;:::o;17660:75::-;17703:3;17724:5;17717:12;;17660:75;;;:::o;17741:269::-;17851:39;17882:7;17851:39;:::i;:::-;17912:91;17961:41;17985:16;17961:41;:::i;:::-;17953:6;17946:4;17940:11;17912:91;:::i;:::-;17906:4;17899:105;17817:193;17741:269;;;:::o;18016:73::-;18061:3;18016:73;:::o;18095:189::-;18172:32;;:::i;:::-;18213:65;18271:6;18263;18257:4;18213:65;:::i;:::-;18148:136;18095:189;;:::o;18290:186::-;18350:120;18367:3;18360:5;18357:14;18350:120;;;18421:39;18458:1;18451:5;18421:39;:::i;:::-;18394:1;18387:5;18383:13;18374:22;;18350:120;;;18290:186;;:::o;18482:543::-;18583:2;18578:3;18575:11;18572:446;;;18617:38;18649:5;18617:38;:::i;:::-;18701:29;18719:10;18701:29;:::i;:::-;18691:8;18687:44;18884:2;18872:10;18869:18;18866:49;;;18905:8;18890:23;;18866:49;18928:80;18984:22;19002:3;18984:22;:::i;:::-;18974:8;18970:37;18957:11;18928:80;:::i;:::-;18587:431;;18572:446;18482:543;;;:::o;19031:117::-;19085:8;19135:5;19129:4;19125:16;19104:37;;19031:117;;;;:::o;19154:169::-;19198:6;19231:51;19279:1;19275:6;19267:5;19264:1;19260:13;19231:51;:::i;:::-;19227:56;19312:4;19306;19302:15;19292:25;;19205:118;19154:169;;;;:::o;19328:295::-;19404:4;19550:29;19575:3;19569:4;19550:29;:::i;:::-;19542:37;;19612:3;19609:1;19605:11;19599:4;19596:21;19588:29;;19328:295;;;;:::o;19628:1403::-;19752:44;19792:3;19787;19752:44;:::i;:::-;19861:18;19853:6;19850:30;19847:56;;;19883:18;;:::i;:::-;19847:56;19927:38;19959:4;19953:11;19927:38;:::i;:::-;20012:67;20072:6;20064;20058:4;20012:67;:::i;:::-;20106:1;20135:2;20127:6;20124:14;20152:1;20147:632;;;;20823:1;20840:6;20837:84;;;20896:9;20891:3;20887:19;20874:33;20865:42;;20837:84;20947:67;21007:6;21000:5;20947:67;:::i;:::-;20941:4;20934:81;20796:229;20117:908;;20147:632;20199:4;20195:9;20187:6;20183:22;20233:37;20265:4;20233:37;:::i;:::-;20292:1;20306:215;20320:7;20317:1;20314:14;20306:215;;;20406:9;20401:3;20397:19;20384:33;20376:6;20369:49;20457:1;20449:6;20445:14;20435:24;;20504:2;20493:9;20489:18;20476:31;;20343:4;20340:1;20336:12;20331:17;;20306:215;;;20549:6;20540:7;20537:19;20534:186;;;20614:9;20609:3;20605:19;20592:33;20657:48;20699:4;20691:6;20687:17;20676:9;20657:48;:::i;:::-;20649:6;20642:64;20557:163;20534:186;20766:1;20762;20754:6;20750:14;20746:22;20740:4;20733:36;20154:625;;;20117:908;;19727:1304;;;19628:1403;;;:::o;21037:180::-;21085:77;21082:1;21075:88;21182:4;21179:1;21172:15;21206:4;21203:1;21196:15;21223:410;21263:7;21286:20;21304:1;21286:20;:::i;:::-;21281:25;;21320:20;21338:1;21320:20;:::i;:::-;21315:25;;21375:1;21372;21368:9;21397:30;21415:11;21397:30;:::i;:::-;21386:41;;21576:1;21567:7;21563:15;21560:1;21557:22;21537:1;21530:9;21510:83;21487:139;;21606:18;;:::i;:::-;21487:139;21271:362;21223:410;;;;:::o;21639:180::-;21687:77;21684:1;21677:88;21784:4;21781:1;21774:15;21808:4;21805:1;21798:15;21825:185;21865:1;21882:20;21900:1;21882:20;:::i;:::-;21877:25;;21916:20;21934:1;21916:20;:::i;:::-;21911:25;;21955:1;21945:35;;21960:18;;:::i;:::-;21945:35;22002:1;21999;21995:9;21990:14;;21825:185;;;;:::o;22016:147::-;22117:11;22154:3;22139:18;;22016:147;;;;:::o;22169:114::-;;:::o;22289:398::-;22448:3;22469:83;22550:1;22545:3;22469:83;:::i;:::-;22462:90;;22561:93;22650:3;22561:93;:::i;:::-;22679:1;22674:3;22670:11;22663:18;;22289:398;;;:::o;22693:379::-;22877:3;22899:147;23042:3;22899:147;:::i;:::-;22892:154;;23063:3;23056:10;;22693:379;;;:::o;23078:174::-;23218:26;23214:1;23206:6;23202:14;23195:50;23078:174;:::o;23258:366::-;23400:3;23421:67;23485:2;23480:3;23421:67;:::i;:::-;23414:74;;23497:93;23586:3;23497:93;:::i;:::-;23615:2;23610:3;23606:12;23599:19;;23258:366;;;:::o;23630:419::-;23796:4;23834:2;23823:9;23819:18;23811:26;;23883:9;23877:4;23873:20;23869:1;23858:9;23854:17;23847:47;23911:131;24037:4;23911:131;:::i;:::-;23903:139;;23630:419;;;:::o;24055:191::-;24095:3;24114:20;24132:1;24114:20;:::i;:::-;24109:25;;24148:20;24166:1;24148:20;:::i;:::-;24143:25;;24191:1;24188;24184:9;24177:16;;24212:3;24209:1;24206:10;24203:36;;;24219:18;;:::i;:::-;24203:36;24055:191;;;;:::o;24252:166::-;24392:18;24388:1;24380:6;24376:14;24369:42;24252:166;:::o;24424:366::-;24566:3;24587:67;24651:2;24646:3;24587:67;:::i;:::-;24580:74;;24663:93;24752:3;24663:93;:::i;:::-;24781:2;24776:3;24772:12;24765:19;;24424:366;;;:::o;24796:419::-;24962:4;25000:2;24989:9;24985:18;24977:26;;25049:9;25043:4;25039:20;25035:1;25024:9;25020:17;25013:47;25077:131;25203:4;25077:131;:::i;:::-;25069:139;;24796:419;;;:::o;25221:176::-;25361:28;25357:1;25349:6;25345:14;25338:52;25221:176;:::o;25403:366::-;25545:3;25566:67;25630:2;25625:3;25566:67;:::i;:::-;25559:74;;25642:93;25731:3;25642:93;:::i;:::-;25760:2;25755:3;25751:12;25744:19;;25403:366;;;:::o;25775:419::-;25941:4;25979:2;25968:9;25964:18;25956:26;;26028:9;26022:4;26018:20;26014:1;26003:9;25999:17;25992:47;26056:131;26182:4;26056:131;:::i;:::-;26048:139;;25775:419;;;:::o;26200:194::-;26240:4;26260:20;26278:1;26260:20;:::i;:::-;26255:25;;26294:20;26312:1;26294:20;:::i;:::-;26289:25;;26338:1;26335;26331:9;26323:17;;26362:1;26356:4;26353:11;26350:37;;;26367:18;;:::i;:::-;26350:37;26200:194;;;;:::o;26400:430::-;26543:4;26581:2;26570:9;26566:18;26558:26;;26594:71;26662:1;26651:9;26647:17;26638:6;26594:71;:::i;:::-;26675:72;26743:2;26732:9;26728:18;26719:6;26675:72;:::i;:::-;26757:66;26819:2;26808:9;26804:18;26795:6;26757:66;:::i;:::-;26400:430;;;;;;:::o;26836:234::-;26976:34;26972:1;26964:6;26960:14;26953:58;27045:17;27040:2;27032:6;27028:15;27021:42;26836:234;:::o;27076:366::-;27218:3;27239:67;27303:2;27298:3;27239:67;:::i;:::-;27232:74;;27315:93;27404:3;27315:93;:::i;:::-;27433:2;27428:3;27424:12;27417:19;;27076:366;;;:::o;27448:419::-;27614:4;27652:2;27641:9;27637:18;27629:26;;27701:9;27695:4;27691:20;27687:1;27676:9;27672:17;27665:47;27729:131;27855:4;27729:131;:::i;:::-;27721:139;;27448:419;;;:::o;27873:148::-;27975:11;28012:3;27997:18;;27873:148;;;;:::o;28027:390::-;28133:3;28161:39;28194:5;28161:39;:::i;:::-;28216:89;28298:6;28293:3;28216:89;:::i;:::-;28209:96;;28314:65;28372:6;28367:3;28360:4;28353:5;28349:16;28314:65;:::i;:::-;28404:6;28399:3;28395:16;28388:23;;28137:280;28027:390;;;;:::o;28447:874::-;28550:3;28587:5;28581:12;28616:36;28642:9;28616:36;:::i;:::-;28668:89;28750:6;28745:3;28668:89;:::i;:::-;28661:96;;28788:1;28777:9;28773:17;28804:1;28799:166;;;;28979:1;28974:341;;;;28766:549;;28799:166;28883:4;28879:9;28868;28864:25;28859:3;28852:38;28945:6;28938:14;28931:22;28923:6;28919:35;28914:3;28910:45;28903:52;;28799:166;;28974:341;29041:38;29073:5;29041:38;:::i;:::-;29101:1;29115:154;29129:6;29126:1;29123:13;29115:154;;;29203:7;29197:14;29193:1;29188:3;29184:11;29177:35;29253:1;29244:7;29240:15;29229:26;;29151:4;29148:1;29144:12;29139:17;;29115:154;;;29298:6;29293:3;29289:16;29282:23;;28981:334;;28766:549;;28554:767;;28447:874;;;;:::o;29327:589::-;29552:3;29574:95;29665:3;29656:6;29574:95;:::i;:::-;29567:102;;29686:95;29777:3;29768:6;29686:95;:::i;:::-;29679:102;;29798:92;29886:3;29877:6;29798:92;:::i;:::-;29791:99;;29907:3;29900:10;;29327:589;;;;;;:::o;29922:1395::-;30039:37;30072:3;30039:37;:::i;:::-;30141:18;30133:6;30130:30;30127:56;;;30163:18;;:::i;:::-;30127:56;30207:38;30239:4;30233:11;30207:38;:::i;:::-;30292:67;30352:6;30344;30338:4;30292:67;:::i;:::-;30386:1;30410:4;30397:17;;30442:2;30434:6;30431:14;30459:1;30454:618;;;;31116:1;31133:6;31130:77;;;31182:9;31177:3;31173:19;31167:26;31158:35;;31130:77;31233:67;31293:6;31286:5;31233:67;:::i;:::-;31227:4;31220:81;31089:222;30424:887;;30454:618;30506:4;30502:9;30494:6;30490:22;30540:37;30572:4;30540:37;:::i;:::-;30599:1;30613:208;30627:7;30624:1;30621:14;30613:208;;;30706:9;30701:3;30697:19;30691:26;30683:6;30676:42;30757:1;30749:6;30745:14;30735:24;;30804:2;30793:9;30789:18;30776:31;;30650:4;30647:1;30643:12;30638:17;;30613:208;;;30849:6;30840:7;30837:19;30834:179;;;30907:9;30902:3;30898:19;30892:26;30950:48;30992:4;30984:6;30980:17;30969:9;30950:48;:::i;:::-;30942:6;30935:64;30857:156;30834:179;31059:1;31055;31047:6;31043:14;31039:22;31033:4;31026:36;30461:611;;;30424:887;;30014:1303;;;29922:1395;;:::o;31323:140::-;31372:9;31405:52;31423:33;31432:23;31449:5;31432:23;:::i;:::-;31423:33;:::i;:::-;31405:52;:::i;:::-;31392:65;;31323:140;;;:::o;31469:129::-;31555:36;31585:5;31555:36;:::i;:::-;31550:3;31543:49;31469:129;;:::o;31604:330::-;31724:4;31762:2;31751:9;31747:18;31739:26;;31775:70;31842:1;31831:9;31827:17;31818:6;31775:70;:::i;:::-;31855:72;31923:2;31912:9;31908:18;31899:6;31855:72;:::i;:::-;31604:330;;;;;:::o;31940:98::-;31991:6;32025:5;32019:12;32009:22;;31940:98;;;:::o;32044:168::-;32127:11;32161:6;32156:3;32149:19;32201:4;32196:3;32192:14;32177:29;;32044:168;;;;:::o;32218:373::-;32304:3;32332:38;32364:5;32332:38;:::i;:::-;32386:70;32449:6;32444:3;32386:70;:::i;:::-;32379:77;;32465:65;32523:6;32518:3;32511:4;32504:5;32500:16;32465:65;:::i;:::-;32555:29;32577:6;32555:29;:::i;:::-;32550:3;32546:39;32539:46;;32308:283;32218:373;;;;:::o;32597:640::-;32792:4;32830:3;32819:9;32815:19;32807:27;;32844:71;32912:1;32901:9;32897:17;32888:6;32844:71;:::i;:::-;32925:72;32993:2;32982:9;32978:18;32969:6;32925:72;:::i;:::-;33007;33075:2;33064:9;33060:18;33051:6;33007:72;:::i;:::-;33126:9;33120:4;33116:20;33111:2;33100:9;33096:18;33089:48;33154:76;33225:4;33216:6;33154:76;:::i;:::-;33146:84;;32597:640;;;;;;;:::o;33243:141::-;33299:5;33330:6;33324:13;33315:22;;33346:32;33372:5;33346:32;:::i;:::-;33243:141;;;;:::o;33390:349::-;33459:6;33508:2;33496:9;33487:7;33483:23;33479:32;33476:119;;;33514:79;;:::i;:::-;33476:119;33634:1;33659:63;33714:7;33705:6;33694:9;33690:22;33659:63;:::i;:::-;33649:73;;33605:127;33390:349;;;;:::o
Swarm Source
ipfs://e4eeb855fde223fcbf7d48c9ca912f1cc2eaf5521b01ee295d2e07e848c3f5fd
Loading...
Loading
Loading...
Loading
OVERVIEW
The drawing ‘Snowball warming’ is from a series called ‘Twisted toys’. Nostalgic childhood figures with a twist. The piece highlights global warming, juxtaposing the climate crisis with a childlike ignorance. This is the first ever animated Zoë Moss digital collectible as a pr...Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.