ERC-721
Overview
Max Total Supply
378 MLV
Holders
209
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 MLVLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Source Code Verified (Exact Match)
Contract Name:
MetaLifeVehicle
Compiler Version
v0.8.23+commit.f704f362
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-12-02 */ // File: @openzeppelin/contracts/utils/math/Math.sol // SPDX-License-Identifier: MIT // 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/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/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/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.20; /** * @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: @openzeppelin/contracts/utils/ReentrancyGuard.sol // // OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } } // File: contracts/ERC721.sol // pragma solidity ^0.8.4; /// @notice Simple ERC721 implementation with storage hitchhiking. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC721.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC721/ERC721.sol) /// /// @dev Note: /// The ERC721 standard allows for self-approvals. /// For performance, this implementation WILL NOT revert for such actions. /// Please add any checks with overrides if desired. abstract contract ERC721 { /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* CONSTANTS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev An account can hold up to 4294967295 tokens. uint256 internal constant _MAX_ACCOUNT_BALANCE = 0xffffffff; /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev Only the token owner or an approved account can manage the token. error NotOwnerNorApproved(); /// @dev The token does not exist. error TokenDoesNotExist(); /// @dev The token already exists. error TokenAlreadyExists(); /// @dev Cannot query the balance for the zero address. error BalanceQueryForZeroAddress(); /// @dev Cannot mint or transfer to the zero address. error TransferToZeroAddress(); /// @dev The token must be owned by `from`. error TransferFromIncorrectOwner(); /// @dev The recipient's balance has overflowed. error AccountBalanceOverflow(); /// @dev Cannot safely transfer to a contract that does not implement /// the ERC721Receiver interface. error TransferToNonERC721ReceiverImplementer(); /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* EVENTS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev Emitted when token `id` is transferred from `from` to `to`. event Transfer(address indexed from, address indexed to, uint256 indexed id); /// @dev Emitted when `owner` enables `account` to manage the `id` token. event Approval(address indexed owner, address indexed account, uint256 indexed id); /// @dev Emitted when `owner` enables or disables `operator` to manage all of their tokens. event ApprovalForAll(address indexed owner, address indexed operator, bool isApproved); /// @dev `keccak256(bytes("Transfer(address,address,uint256)"))`. uint256 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; /// @dev `keccak256(bytes("Approval(address,address,uint256)"))`. uint256 private constant _APPROVAL_EVENT_SIGNATURE = 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925; /// @dev `keccak256(bytes("ApprovalForAll(address,address,bool)"))`. uint256 private constant _APPROVAL_FOR_ALL_EVENT_SIGNATURE = 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31; /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* STORAGE */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev The ownership data slot of `id` is given by: /// ``` /// mstore(0x00, id) /// mstore(0x1c, _ERC721_MASTER_SLOT_SEED) /// let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) /// ``` /// Bits Layout: // - [0..159] `addr` // - [160..223] `extraData` /// /// The approved address slot is given by: `add(1, ownershipSlot)`. /// /// See: https://notes.ethereum.org/%40vbuterin/verkle_tree_eip /// /// The balance slot of `owner` is given by: /// ``` /// mstore(0x1c, _ERC721_MASTER_SLOT_SEED) /// mstore(0x00, owner) /// let balanceSlot := keccak256(0x0c, 0x1c) /// ``` /// Bits Layout: /// - [0..31] `balance` /// - [32..225] `aux` /// /// The `operator` approval slot of `owner` is given by: /// ``` /// mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator)) /// mstore(0x00, owner) /// let operatorApprovalSlot := keccak256(0x0c, 0x30) /// ``` uint256 private constant _ERC721_MASTER_SLOT_SEED = 0x7d8825530a5a2e7a << 192; /// @dev Pre-shifted and pre-masked constant. uint256 private constant _ERC721_MASTER_SLOT_SEED_MASKED = 0x0a5a2e7a00000000; /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* ERC721 METADATA */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev Returns the token collection name. function name() public view virtual returns (string memory); /// @dev Returns the token collection symbol. function symbol() public view virtual returns (string memory); /// @dev Returns the Uniform Resource Identifier (URI) for token `id`. function tokenURI(uint256 id) public view virtual returns (string memory); /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* ERC721 */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev Returns the owner of token `id`. /// /// Requirements: /// - Token `id` must exist. function ownerOf(uint256 id) public view virtual returns (address result) { result = _ownerOf(id); /// @solidity memory-safe-assembly assembly { if iszero(result) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } } } /// @dev Returns the number of tokens owned by `owner`. /// /// Requirements: /// - `owner` must not be the zero address. function balanceOf(address owner) public view virtual returns (uint256 result) { /// @solidity memory-safe-assembly assembly { // Revert if the `owner` is the zero address. if iszero(owner) { mstore(0x00, 0x8f4eb604) // `BalanceQueryForZeroAddress()`. revert(0x1c, 0x04) } mstore(0x1c, _ERC721_MASTER_SLOT_SEED) mstore(0x00, owner) result := and(sload(keccak256(0x0c, 0x1c)), _MAX_ACCOUNT_BALANCE) } } /// @dev Returns the account approved to managed token `id`. /// /// Requirements: /// - Token `id` must exist. function getApproved(uint256 id) public view virtual returns (address result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) if iszero(shr(96, shl(96, sload(ownershipSlot)))) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } result := sload(add(1, ownershipSlot)) } } /// @dev Sets `account` as the approved account to manage token `id`. /// /// Requirements: /// - Token `id` must exist. /// - The caller must be the owner of the token, /// or an approved operator for the token owner. /// /// Emits a {Approval} event. function approve(address account, uint256 id) public payable virtual { _approve(msg.sender, account, id); } /// @dev Returns whether `operator` is approved to manage the tokens of `owner`. function isApprovedForAll(address owner, address operator) public view virtual returns (bool result) { /// @solidity memory-safe-assembly assembly { mstore(0x1c, operator) mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED) mstore(0x00, owner) result := sload(keccak256(0x0c, 0x30)) } } /// @dev Sets whether `operator` is approved to manage the tokens of the caller. /// /// Emits a {ApprovalForAll} event. function setApprovalForAll(address operator, bool isApproved) public virtual { /// @solidity memory-safe-assembly assembly { // Convert to 0 or 1. isApproved := iszero(iszero(isApproved)) // Update the `isApproved` for (`msg.sender`, `operator`). mstore(0x1c, operator) mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED) mstore(0x00, caller()) sstore(keccak256(0x0c, 0x30), isApproved) // Emit the {ApprovalForAll} event. mstore(0x00, isApproved) log3( 0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, caller(), shr(96, shl(96, operator)) ) } } /// @dev Transfers token `id` from `from` to `to`. /// /// Requirements: /// /// - Token `id` must exist. /// - `from` must be the owner of the token. /// - `to` cannot be the zero address. /// - The caller must be the owner of the token, or be approved to manage the token. /// /// Emits a {Transfer} event. function transferFrom(address from, address to, uint256 id) public payable virtual { _beforeTokenTransfer(from, to, id); /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. let bitmaskAddress := shr(96, not(0)) from := and(bitmaskAddress, from) to := and(bitmaskAddress, to) // Load the ownership data. mstore(0x00, id) mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, caller())) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let ownershipPacked := sload(ownershipSlot) let owner := and(bitmaskAddress, ownershipPacked) // Revert if `from` is not the owner, or does not exist. if iszero(mul(owner, eq(owner, from))) { if iszero(owner) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } mstore(0x00, 0xa1148100) // `TransferFromIncorrectOwner()`. revert(0x1c, 0x04) } // Revert if `to` is the zero address. if iszero(to) { mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. revert(0x1c, 0x04) } // Load, check, and update the token approval. { mstore(0x00, from) let approvedAddress := sload(add(1, ownershipSlot)) // Revert if the caller is not the owner, nor approved. if iszero(or(eq(caller(), from), eq(caller(), approvedAddress))) { if iszero(sload(keccak256(0x0c, 0x30))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Delete the approved address if any. if approvedAddress { sstore(add(1, ownershipSlot), 0) } } // Update with the new owner. sstore(ownershipSlot, xor(ownershipPacked, xor(from, to))) // Decrement the balance of `from`. { let fromBalanceSlot := keccak256(0x0c, 0x1c) sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1)) } // Increment the balance of `to`. { mstore(0x00, to) let toBalanceSlot := keccak256(0x0c, 0x1c) let toBalanceSlotPacked := add(sload(toBalanceSlot), 1) if iszero(and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE)) { mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. revert(0x1c, 0x04) } sstore(toBalanceSlot, toBalanceSlotPacked) } // Emit the {Transfer} event. log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id) } _afterTokenTransfer(from, to, id); } /// @dev Equivalent to `safeTransferFrom(from, to, id, "")`. function safeTransferFrom(address from, address to, uint256 id) public payable virtual { transferFrom(from, to, id); if (_hasCode(to)) _checkOnERC721Received(from, to, id, ""); } /// @dev Transfers token `id` from `from` to `to`. /// /// Requirements: /// /// - Token `id` must exist. /// - `from` must be the owner of the token. /// - `to` cannot be the zero address. /// - The caller must be the owner of the token, or be approved to manage the token. /// - 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 id, bytes calldata data) public payable virtual { transferFrom(from, to, id); if (_hasCode(to)) _checkOnERC721Received(from, to, id, data); } /// @dev Returns true if this contract implements the interface defined by `interfaceId`. /// See: https://eips.ethereum.org/EIPS/eip-165 /// This function call must use less than 30000 gas. function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) { /// @solidity memory-safe-assembly assembly { let s := shr(224, interfaceId) // ERC165: 0x01ffc9a7, ERC721: 0x80ac58cd, ERC721Metadata: 0x5b5e139f. result := or(or(eq(s, 0x01ffc9a7), eq(s, 0x80ac58cd)), eq(s, 0x5b5e139f)) } } /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* INTERNAL QUERY FUNCTIONS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev Returns if token `id` exists. function _exists(uint256 id) internal view virtual returns (bool result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) result := shl(96, sload(add(id, add(id, keccak256(0x00, 0x20))))) } } /// @dev Returns the owner of token `id`. /// Returns the zero address instead of reverting if the token does not exist. function _ownerOf(uint256 id) internal view virtual returns (address result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) result := shr(96, shl(96, sload(add(id, add(id, keccak256(0x00, 0x20)))))) } } /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* INTERNAL DATA HITCHHIKING FUNCTIONS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev Returns the auxiliary data for `owner`. /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data. /// Auxiliary data can be set for any address, even if it does not have any tokens. function _getAux(address owner) internal view virtual returns (uint224 result) { /// @solidity memory-safe-assembly assembly { mstore(0x1c, _ERC721_MASTER_SLOT_SEED) mstore(0x00, owner) result := shr(32, sload(keccak256(0x0c, 0x1c))) } } /// @dev Set the auxiliary data for `owner` to `value`. /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data. /// Auxiliary data can be set for any address, even if it does not have any tokens. function _setAux(address owner, uint224 value) internal virtual { /// @solidity memory-safe-assembly assembly { mstore(0x1c, _ERC721_MASTER_SLOT_SEED) mstore(0x00, owner) let balanceSlot := keccak256(0x0c, 0x1c) let packed := sload(balanceSlot) sstore(balanceSlot, xor(packed, shl(32, xor(value, shr(32, packed))))) } } /// @dev Returns the extra data for token `id`. /// Minting, transferring, burning a token will not change the extra data. /// The extra data can be set on a non-existent token. function _getExtraData(uint256 id) internal view virtual returns (uint96 result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) result := shr(160, sload(add(id, add(id, keccak256(0x00, 0x20))))) } } /// @dev Sets the extra data for token `id` to `value`. /// Minting, transferring, burning a token will not change the extra data. /// The extra data can be set on a non-existent token. function _setExtraData(uint256 id, uint96 value) internal virtual { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let packed := sload(ownershipSlot) sstore(ownershipSlot, xor(packed, shl(160, xor(value, shr(160, packed))))) } } /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* INTERNAL MINT FUNCTIONS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev Mints token `id` to `to`. /// /// Requirements: /// /// - Token `id` must not exist. /// - `to` cannot be the zero address. /// /// Emits a {Transfer} event. function _mint(address to, uint256 id) internal virtual { _beforeTokenTransfer(address(0), to, id); /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. to := shr(96, shl(96, to)) // Revert if `to` is the zero address. if iszero(to) { mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. revert(0x1c, 0x04) } // Load the ownership data. mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let ownershipPacked := sload(ownershipSlot) // Revert if the token already exists. if shl(96, ownershipPacked) { mstore(0x00, 0xc991cbb1) // `TokenAlreadyExists()`. revert(0x1c, 0x04) } // Update with the owner. sstore(ownershipSlot, or(ownershipPacked, to)) // Increment the balance of the owner. { mstore(0x00, to) let balanceSlot := keccak256(0x0c, 0x1c) let balanceSlotPacked := add(sload(balanceSlot), 1) if iszero(and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE)) { mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. revert(0x1c, 0x04) } sstore(balanceSlot, balanceSlotPacked) } // Emit the {Transfer} event. log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id) } _afterTokenTransfer(address(0), to, id); } /// @dev Equivalent to `_safeMint(to, id, "")`. function _safeMint(address to, uint256 id) internal virtual { _safeMint(to, id, ""); } /// @dev Mints token `id` to `to`. /// /// Requirements: /// /// - Token `id` must not exist. /// - `to` cannot be the zero address. /// - If `to` refers to a smart contract, it must implement /// {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. /// /// Emits a {Transfer} event. function _safeMint(address to, uint256 id, bytes memory data) internal virtual { _mint(to, id); if (_hasCode(to)) _checkOnERC721Received(address(0), to, id, data); } /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* INTERNAL BURN FUNCTIONS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev Equivalent to `_burn(address(0), id)`. function _burn(uint256 id) internal virtual { _burn(address(0), id); } /// @dev Destroys token `id`, using `by`. /// /// Requirements: /// /// - Token `id` must exist. /// - If `by` is not the zero address, /// it must be the owner of the token, or be approved to manage the token. /// /// Emits a {Transfer} event. function _burn(address by, uint256 id) internal virtual { address owner = ownerOf(id); _beforeTokenTransfer(owner, address(0), id); /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. by := shr(96, shl(96, by)) // Load the ownership data. mstore(0x00, id) mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by)) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let ownershipPacked := sload(ownershipSlot) // Reload the owner in case it is changed in `_beforeTokenTransfer`. owner := shr(96, shl(96, ownershipPacked)) // Revert if the token does not exist. if iszero(owner) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } // Load and check the token approval. { mstore(0x00, owner) let approvedAddress := sload(add(1, ownershipSlot)) // If `by` is not the zero address, do the authorization check. // Revert if the `by` is not the owner, nor approved. if iszero(or(iszero(by), or(eq(by, owner), eq(by, approvedAddress)))) { if iszero(sload(keccak256(0x0c, 0x30))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Delete the approved address if any. if approvedAddress { sstore(add(1, ownershipSlot), 0) } } // Clear the owner. sstore(ownershipSlot, xor(ownershipPacked, owner)) // Decrement the balance of `owner`. { let balanceSlot := keccak256(0x0c, 0x1c) sstore(balanceSlot, sub(sload(balanceSlot), 1)) } // Emit the {Transfer} event. log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, owner, 0, id) } _afterTokenTransfer(owner, address(0), id); } /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* INTERNAL APPROVAL FUNCTIONS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev Returns whether `account` is the owner of token `id`, or is approved to managed it. /// /// Requirements: /// - Token `id` must exist. function _isApprovedOrOwner(address account, uint256 id) internal view virtual returns (bool result) { /// @solidity memory-safe-assembly assembly { result := 1 // Clear the upper 96 bits. account := shr(96, shl(96, account)) // Load the ownership data. mstore(0x00, id) mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, account)) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let owner := shr(96, shl(96, sload(ownershipSlot))) // Revert if the token does not exist. if iszero(owner) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } // Check if `account` is the `owner`. if iszero(eq(account, owner)) { mstore(0x00, owner) // Check if `account` is approved to if iszero(sload(keccak256(0x0c, 0x30))) { result := eq(account, sload(add(1, ownershipSlot))) } } } } /// @dev Returns the account approved to manage token `id`. /// Returns the zero address instead of reverting if the token does not exist. function _getApproved(uint256 id) internal view virtual returns (address result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) result := sload(add(1, add(id, add(id, keccak256(0x00, 0x20))))) } } /// @dev Equivalent to `_approve(address(0), account, id)`. function _approve(address account, uint256 id) internal virtual { _approve(address(0), account, id); } /// @dev Sets `account` as the approved account to manage token `id`, using `by`. /// /// Requirements: /// - Token `id` must exist. /// - If `by` is not the zero address, `by` must be the owner /// or an approved operator for the token owner. /// /// Emits a {Transfer} event. function _approve(address by, address account, uint256 id) internal virtual { assembly { // Clear the upper 96 bits. let bitmaskAddress := shr(96, not(0)) account := and(bitmaskAddress, account) by := and(bitmaskAddress, by) // Load the owner of the token. mstore(0x00, id) mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by)) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let owner := and(bitmaskAddress, sload(ownershipSlot)) // Revert if the token does not exist. if iszero(owner) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } // If `by` is not the zero address, do the authorization check. // Revert if `by` is not the owner, nor approved. if iszero(or(iszero(by), eq(by, owner))) { mstore(0x00, owner) if iszero(sload(keccak256(0x0c, 0x30))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Sets `account` as the approved account to manage `id`. sstore(add(1, ownershipSlot), account) // Emit the {Approval} event. log4(0x00, 0x00, _APPROVAL_EVENT_SIGNATURE, owner, account, id) } } /// @dev Approve or remove the `operator` as an operator for `by`, /// without authorization checks. /// /// Emits a {ApprovalForAll} event. function _setApprovalForAll(address by, address operator, bool isApproved) internal virtual { /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. by := shr(96, shl(96, by)) operator := shr(96, shl(96, operator)) // Convert to 0 or 1. isApproved := iszero(iszero(isApproved)) // Update the `isApproved` for (`by`, `operator`). mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator)) mstore(0x00, by) sstore(keccak256(0x0c, 0x30), isApproved) // Emit the {ApprovalForAll} event. mstore(0x00, isApproved) log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, by, operator) } } /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* INTERNAL TRANSFER FUNCTIONS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev Equivalent to `_transfer(address(0), from, to, id)`. function _transfer(address from, address to, uint256 id) internal virtual { _transfer(address(0), from, to, id); } /// @dev Transfers token `id` from `from` to `to`. /// /// Requirements: /// /// - Token `id` must exist. /// - `from` must be the owner of the token. /// - `to` cannot be the zero address. /// - If `by` is not the zero address, /// it must be the owner of the token, or be approved to manage the token. /// /// Emits a {Transfer} event. function _transfer(address by, address from, address to, uint256 id) internal virtual { _beforeTokenTransfer(from, to, id); /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. let bitmaskAddress := shr(96, not(0)) from := and(bitmaskAddress, from) to := and(bitmaskAddress, to) by := and(bitmaskAddress, by) // Load the ownership data. mstore(0x00, id) mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by)) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let ownershipPacked := sload(ownershipSlot) let owner := and(bitmaskAddress, ownershipPacked) // Revert if `from` is not the owner, or does not exist. if iszero(mul(owner, eq(owner, from))) { if iszero(owner) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } mstore(0x00, 0xa1148100) // `TransferFromIncorrectOwner()`. revert(0x1c, 0x04) } // Revert if `to` is the zero address. if iszero(to) { mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. revert(0x1c, 0x04) } // Load, check, and update the token approval. { mstore(0x00, from) let approvedAddress := sload(add(1, ownershipSlot)) // If `by` is not the zero address, do the authorization check. // Revert if the `by` is not the owner, nor approved. if iszero(or(iszero(by), or(eq(by, from), eq(by, approvedAddress)))) { if iszero(sload(keccak256(0x0c, 0x30))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Delete the approved address if any. if approvedAddress { sstore(add(1, ownershipSlot), 0) } } // Update with the new owner. sstore(ownershipSlot, xor(ownershipPacked, xor(from, to))) // Decrement the balance of `from`. { let fromBalanceSlot := keccak256(0x0c, 0x1c) sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1)) } // Increment the balance of `to`. { mstore(0x00, to) let toBalanceSlot := keccak256(0x0c, 0x1c) let toBalanceSlotPacked := add(sload(toBalanceSlot), 1) if iszero(and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE)) { mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. revert(0x1c, 0x04) } sstore(toBalanceSlot, toBalanceSlotPacked) } // Emit the {Transfer} event. log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id) } _afterTokenTransfer(from, to, id); } /// @dev Equivalent to `_safeTransfer(from, to, id, "")`. function _safeTransfer(address from, address to, uint256 id) internal virtual { _safeTransfer(from, to, id, ""); } /// @dev Transfers token `id` from `from` to `to`. /// /// Requirements: /// /// - Token `id` must exist. /// - `from` must be the owner of the token. /// - `to` cannot be the zero address. /// - The caller must be the owner of the token, or be approved to manage the token. /// - If `to` refers to a smart contract, it must implement /// {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. /// /// Emits a {Transfer} event. function _safeTransfer(address from, address to, uint256 id, bytes memory data) internal virtual { _transfer(address(0), from, to, id); if (_hasCode(to)) _checkOnERC721Received(from, to, id, data); } /// @dev Equivalent to `_safeTransfer(by, from, to, id, "")`. function _safeTransfer(address by, address from, address to, uint256 id) internal virtual { _safeTransfer(by, from, to, id, ""); } /// @dev Transfers token `id` from `from` to `to`. /// /// Requirements: /// /// - Token `id` must exist. /// - `from` must be the owner of the token. /// - `to` cannot be the zero address. /// - If `by` is not the zero address, /// it must be the owner of the token, or be approved to manage the token. /// - If `to` refers to a smart contract, it must implement /// {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. /// /// Emits a {Transfer} event. function _safeTransfer(address by, address from, address to, uint256 id, bytes memory data) internal virtual { _transfer(by, from, to, id); if (_hasCode(to)) _checkOnERC721Received(from, to, id, data); } /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* HOOKS FOR OVERRIDING */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev Hook that is called before any token transfers, including minting and burning. function _beforeTokenTransfer(address from, address to, uint256 id) internal virtual {} /// @dev Hook that is called after any token transfers, including minting and burning. function _afterTokenTransfer(address from, address to, uint256 id) internal virtual {} /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* PRIVATE HELPERS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev Returns if `a` has bytecode of non-zero length. function _hasCode(address a) private view returns (bool result) { /// @solidity memory-safe-assembly assembly { result := extcodesize(a) // Can handle dirty upper bits. } } /// @dev Perform a call to invoke {IERC721Receiver-onERC721Received} on `to`. /// Reverts if the target does not support the function correctly. function _checkOnERC721Received(address from, address to, uint256 id, bytes memory data) private { /// @solidity memory-safe-assembly assembly { // Prepare the calldata. let m := mload(0x40) let onERC721ReceivedSelector := 0x150b7a02 mstore(m, onERC721ReceivedSelector) mstore(add(m, 0x20), caller()) // The `operator`, which is always `msg.sender`. mstore(add(m, 0x40), shr(96, shl(96, from))) mstore(add(m, 0x60), id) mstore(add(m, 0x80), 0x80) let n := mload(data) mstore(add(m, 0xa0), n) if n { pop(staticcall(gas(), 4, add(data, 0x20), n, add(m, 0xc0), n)) } // Revert if the call reverts. if iszero(call(gas(), to, 0, add(m, 0x1c), add(n, 0xa4), m, 0x20)) { if returndatasize() { // Bubble up the revert if the call reverts. returndatacopy(0x00, 0x00, returndatasize()) revert(0x00, returndatasize()) } mstore(m, 0) } // Load the returndata and compare it. if iszero(eq(mload(m), shl(224, onERC721ReceivedSelector))) { mstore(0x00, 0xd1a57ed6) // `TransferToNonERC721ReceiverImplementer()`. revert(0x1c, 0x04) } } } } // File: contracts/LibPRNG.sol // pragma solidity ^0.8.4; /// @notice Library for generating psuedorandom numbers. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibPRNG.sol) library LibPRNG { /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* STRUCTS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev A psuedorandom number state in memory. struct PRNG { uint256 state; } /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* OPERATIONS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev Seeds the `prng` with `state`. function seed(PRNG memory prng, uint256 state) internal pure { /// @solidity memory-safe-assembly assembly { mstore(prng, state) } } /// @dev Returns the next psuedorandom uint256. /// All bits of the returned uint256 pass the NIST Statistical Test Suite. function next(PRNG memory prng) internal pure returns (uint256 result) { // We simply use `keccak256` for a great balance between // runtime gas costs, bytecode size, and statistical properties. // // A high-quality LCG with a 32-byte state // is only about 30% more gas efficient during runtime, // but requires a 32-byte multiplier, which can cause bytecode bloat // when this function is inlined. // // Using this method is about 2x more efficient than // `nextRandomness = uint256(keccak256(abi.encode(randomness)))`. /// @solidity memory-safe-assembly assembly { result := keccak256(prng, 0x20) mstore(prng, result) } } /// @dev Returns a psuedorandom uint256, uniformly distributed /// between 0 (inclusive) and `upper` (exclusive). /// If your modulus is big, this method is recommended /// for uniform sampling to avoid modulo bias. /// For uniform sampling across all uint256 values, /// or for small enough moduli such that the bias is neligible, /// use {next} instead. function uniform(PRNG memory prng, uint256 upper) internal pure returns (uint256 result) { /// @solidity memory-safe-assembly assembly { for {} 1 {} { result := keccak256(prng, 0x20) mstore(prng, result) if iszero(lt(result, mod(sub(0, upper), upper))) { break } } result := mod(result, upper) } } /// @dev Shuffles the array in-place with Fisher-Yates shuffle. function shuffle(PRNG memory prng, uint256[] memory a) internal pure { /// @solidity memory-safe-assembly assembly { let n := mload(a) let w := not(0) let mask := shr(128, w) if n { for { a := add(a, 0x20) } 1 {} { // We can just directly use `keccak256`, cuz // the other approaches don't save much. let r := keccak256(prng, 0x20) mstore(prng, r) // Note that there will be a very tiny modulo bias // if the length of the array is not a power of 2. // For all practical purposes, it is negligible // and will not be a fairness or security concern. { let j := add(a, shl(5, mod(shr(128, r), n))) n := add(n, w) // `sub(n, 1)`. if iszero(n) { break } let i := add(a, shl(5, n)) let t := mload(i) mstore(i, mload(j)) mstore(j, t) } { let j := add(a, shl(5, mod(and(r, mask), n))) n := add(n, w) // `sub(n, 1)`. if iszero(n) { break } let i := add(a, shl(5, n)) let t := mload(i) mstore(i, mload(j)) mstore(j, t) } } } } } /// @dev Shuffles the bytes in-place with Fisher-Yates shuffle. function shuffle(PRNG memory prng, bytes memory a) internal pure { /// @solidity memory-safe-assembly assembly { let n := mload(a) let w := not(0) let mask := shr(128, w) if n { let b := add(a, 0x01) for { a := add(a, 0x20) } 1 {} { // We can just directly use `keccak256`, cuz // the other approaches don't save much. let r := keccak256(prng, 0x20) mstore(prng, r) // Note that there will be a very tiny modulo bias // if the length of the array is not a power of 2. // For all practical purposes, it is negligible // and will not be a fairness or security concern. { let o := mod(shr(128, r), n) n := add(n, w) // `sub(n, 1)`. if iszero(n) { break } let t := mload(add(b, n)) mstore8(add(a, n), mload(add(b, o))) mstore8(add(a, o), t) } { let o := mod(and(r, mask), n) n := add(n, w) // `sub(n, 1)`. if iszero(n) { break } let t := mload(add(b, n)) mstore8(add(a, n), mload(add(b, o))) mstore8(add(a, o), t) } } } } } } // File: contracts/LibString.sol // pragma solidity ^0.8.4; /// @notice Library for converting numbers into strings and other string operations. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibString.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol) library LibString { /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev The `length` of the output is too small to contain all the hex digits. error HexLengthInsufficient(); /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* CONSTANTS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev The constant returned when the `search` is not found in the string. uint256 internal constant NOT_FOUND = type(uint256).max; /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* DECIMAL OPERATIONS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev Returns the base 10 decimal representation of `value`. function toString(uint256 value) internal pure returns (string memory str) { /// @solidity memory-safe-assembly 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. str := add(mload(0x40), 0x80) // Update the free memory pointer to allocate. mstore(0x40, add(str, 0x20)) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str let w := not(0) // Tsk. // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. for { let temp := value } 1 {} { str := add(str, w) // `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) 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) } } /// @dev Returns the base 10 decimal representation of `value`. function toString(int256 value) internal pure returns (string memory str) { if (value >= 0) { return toString(uint256(value)); } unchecked { str = toString(uint256(-value)); } /// @solidity memory-safe-assembly assembly { // We still have some spare memory space on the left, // as we have allocated 3 words (96 bytes) for up to 78 digits. let length := mload(str) // Load the string length. mstore(str, 0x2d) // Store the '-' character. str := sub(str, 1) // Move back the string pointer by a byte. mstore(str, add(length, 1)) // Update the string length. } } /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* HEXADECIMAL OPERATIONS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev Returns the hexadecimal representation of `value`, /// left-padded to an input length of `length` bytes. /// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte, /// giving a total length of `length * 2 + 2` bytes. /// Reverts if `length` is too small for the output to contain all the digits. function toHexString(uint256 value, uint256 length) internal pure returns (string memory str) { str = toHexStringNoPrefix(value, length); /// @solidity memory-safe-assembly assembly { let strLength := add(mload(str), 2) // Compute the length. mstore(str, 0x3078) // Write the "0x" prefix. str := sub(str, 2) // Move the pointer. mstore(str, strLength) // Write the length. } } /// @dev Returns the hexadecimal representation of `value`, /// left-padded to an input length of `length` bytes. /// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte, /// giving a total length of `length * 2` bytes. /// Reverts if `length` is too small for the output to contain all the digits. function toHexStringNoPrefix(uint256 value, uint256 length) internal pure returns (string memory str) { /// @solidity memory-safe-assembly assembly { // We need 0x20 bytes for the trailing zeros padding, `length * 2` bytes // for the digits, 0x02 bytes for the prefix, and 0x20 bytes for the length. // We add 0x20 to the total and round down to a multiple of 0x20. // (0x20 + 0x20 + 0x02 + 0x20) = 0x62. str := add(mload(0x40), and(add(shl(1, length), 0x42), not(0x1f))) // Allocate the memory. mstore(0x40, add(str, 0x20)) // Zeroize the slot after the string. mstore(str, 0) // Cache the end to calculate the length later. let end := str // Store "0123456789abcdef" in scratch space. mstore(0x0f, 0x30313233343536373839616263646566) let start := sub(str, add(length, length)) let w := not(1) // Tsk. let temp := value // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. for {} 1 {} { str := add(str, w) // `sub(str, 2)`. mstore8(add(str, 1), mload(and(temp, 15))) mstore8(str, mload(and(shr(4, temp), 15))) temp := shr(8, temp) if iszero(xor(str, start)) { break } } if temp { // Store the function selector of `HexLengthInsufficient()`. mstore(0x00, 0x2194895a) // Revert with (offset, size). revert(0x1c, 0x04) } // Compute the string's length. let strLength := sub(end, str) // Move the pointer and write the length. str := sub(str, 0x20) mstore(str, strLength) } } /// @dev Returns the hexadecimal representation of `value`. /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte. /// As address are 20 bytes long, the output will left-padded to have /// a length of `20 * 2 + 2` bytes. function toHexString(uint256 value) internal pure returns (string memory str) { str = toHexStringNoPrefix(value); /// @solidity memory-safe-assembly assembly { let strLength := add(mload(str), 2) // Compute the length. mstore(str, 0x3078) // Write the "0x" prefix. str := sub(str, 2) // Move the pointer. mstore(str, strLength) // Write the length. } } /// @dev Returns the hexadecimal representation of `value`. /// The output is encoded using 2 hexadecimal digits per byte. /// As address are 20 bytes long, the output will left-padded to have /// a length of `20 * 2` bytes. function toHexStringNoPrefix(uint256 value) internal pure returns (string memory str) { /// @solidity memory-safe-assembly assembly { // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length, // 0x02 bytes for the prefix, and 0x40 bytes for the digits. // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x40) is 0xa0. str := add(mload(0x40), 0x80) // Allocate the memory. mstore(0x40, add(str, 0x20)) // Zeroize the slot after the string. mstore(str, 0) // Cache the end to calculate the length later. let end := str // Store "0123456789abcdef" in scratch space. mstore(0x0f, 0x30313233343536373839616263646566) let w := not(1) // Tsk. // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. for { let temp := value } 1 {} { str := add(str, w) // `sub(str, 2)`. mstore8(add(str, 1), mload(and(temp, 15))) mstore8(str, mload(and(shr(4, temp), 15))) temp := shr(8, temp) if iszero(temp) { break } } // Compute the string's length. let strLength := sub(end, str) // Move the pointer and write the length. str := sub(str, 0x20) mstore(str, strLength) } } /// @dev Returns the hexadecimal representation of `value`. /// The output is prefixed with "0x", encoded using 2 hexadecimal digits per byte, /// and the alphabets are capitalized conditionally according to /// https://eips.ethereum.org/EIPS/eip-55 function toHexStringChecksummed(address value) internal pure returns (string memory str) { str = toHexString(value); /// @solidity memory-safe-assembly assembly { let mask := shl(6, div(not(0), 255)) // `0b010000000100000000 ...` let o := add(str, 0x22) let hashed := and(keccak256(o, 40), mul(34, mask)) // `0b10001000 ... ` let t := shl(240, 136) // `0b10001000 << 240` for { let i := 0 } 1 {} { mstore(add(i, i), mul(t, byte(i, hashed))) i := add(i, 1) if eq(i, 20) { break } } mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask))))) o := add(o, 0x20) mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask))))) } } /// @dev Returns the hexadecimal representation of `value`. /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte. function toHexString(address value) internal pure returns (string memory str) { str = toHexStringNoPrefix(value); /// @solidity memory-safe-assembly assembly { let strLength := add(mload(str), 2) // Compute the length. mstore(str, 0x3078) // Write the "0x" prefix. str := sub(str, 2) // Move the pointer. mstore(str, strLength) // Write the length. } } /// @dev Returns the hexadecimal representation of `value`. /// The output is encoded using 2 hexadecimal digits per byte. function toHexStringNoPrefix(address value) internal pure returns (string memory str) { /// @solidity memory-safe-assembly assembly { str := mload(0x40) // Allocate the memory. // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length, // 0x02 bytes for the prefix, and 0x28 bytes for the digits. // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80. mstore(0x40, add(str, 0x80)) // Store "0123456789abcdef" in scratch space. mstore(0x0f, 0x30313233343536373839616263646566) str := add(str, 2) mstore(str, 40) let o := add(str, 0x20) mstore(add(o, 40), 0) value := shl(96, value) // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. for { let i := 0 } 1 {} { let p := add(o, add(i, i)) let temp := byte(i, value) mstore8(add(p, 1), mload(and(temp, 15))) mstore8(p, mload(shr(4, temp))) i := add(i, 1) if eq(i, 20) { break } } } } /// @dev Returns the hex encoded string from the raw bytes. /// The output is encoded using 2 hexadecimal digits per byte. function toHexString(bytes memory raw) internal pure returns (string memory str) { str = toHexStringNoPrefix(raw); /// @solidity memory-safe-assembly assembly { let strLength := add(mload(str), 2) // Compute the length. mstore(str, 0x3078) // Write the "0x" prefix. str := sub(str, 2) // Move the pointer. mstore(str, strLength) // Write the length. } } /// @dev Returns the hex encoded string from the raw bytes. /// The output is encoded using 2 hexadecimal digits per byte. function toHexStringNoPrefix(bytes memory raw) internal pure returns (string memory str) { /// @solidity memory-safe-assembly assembly { let length := mload(raw) str := add(mload(0x40), 2) // Skip 2 bytes for the optional prefix. mstore(str, add(length, length)) // Store the length of the output. // Store "0123456789abcdef" in scratch space. mstore(0x0f, 0x30313233343536373839616263646566) let o := add(str, 0x20) let end := add(raw, length) for {} iszero(eq(raw, end)) {} { raw := add(raw, 1) mstore8(add(o, 1), mload(and(mload(raw), 15))) mstore8(o, mload(and(shr(4, mload(raw)), 15))) o := add(o, 2) } mstore(o, 0) // Zeroize the slot after the string. mstore(0x40, add(o, 0x20)) // Allocate the memory. } } /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* RUNE STRING OPERATIONS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ /// @dev Returns the number of UTF characters in the string. function runeCount(string memory s) internal pure returns (uint256 result) { /// @solidity memory-safe-assembly assembly { if mload(s) { mstore(0x00, div(not(0), 255)) mstore(0x20, 0x0202020202020202020202020202020202020202020202020303030304040506) let o := add(s, 0x20) let end := add(o, mload(s)) for { result := 1 } 1 { result := add(result, 1) } { o := add(o, byte(0, mload(shr(250, mload(o))))) if iszero(lt(o, end)) { break } } } } } /// @dev Returns if this string is a 7-bit ASCII string. /// (i.e. all characters codes are in [0..127]) function is7BitASCII(string memory s) internal pure returns (bool result) { /// @solidity memory-safe-assembly assembly { let mask := shl(7, div(not(0), 255)) result := 1 let n := mload(s) if n { let o := add(s, 0x20) let end := add(o, n) let last := mload(end) mstore(end, 0) for {} 1 {} { if and(mask, mload(o)) { result := 0 break } o := add(o, 0x20) if iszero(lt(o, end)) { break } } mstore(end, last) } } } /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/ /* BYTE STRING OPERATIONS */ /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/ // For performance and bytecode compactness, all indices of the following operations // are byte (ASCII) offsets, not UTF character offsets. /// @dev Returns `subject` all occurrences of `search` replaced with `replacement`. function replace(string memory subject, string memory search, string memory replacement) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let subjectLength := mload(subject) let searchLength := mload(search) let replacementLength := mload(replacement) subject := add(subject, 0x20) search := add(search, 0x20) replacement := add(replacement, 0x20) result := add(mload(0x40), 0x20) let subjectEnd := add(subject, subjectLength) if iszero(gt(searchLength, subjectLength)) { let subjectSearchEnd := add(sub(subjectEnd, searchLength), 1) let h := 0 if iszero(lt(searchLength, 0x20)) { h := keccak256(search, searchLength) } let m := shl(3, sub(0x20, and(searchLength, 0x1f))) let s := mload(search) for {} 1 {} { let t := mload(subject) // Whether the first `searchLength % 32` bytes of // `subject` and `search` matches. if iszero(shr(m, xor(t, s))) { if h { if iszero(eq(keccak256(subject, searchLength), h)) { mstore(result, t) result := add(result, 1) subject := add(subject, 1) if iszero(lt(subject, subjectSearchEnd)) { break } continue } } // Copy the `replacement` one word at a time. for { let o := 0 } 1 {} { mstore(add(result, o), mload(add(replacement, o))) o := add(o, 0x20) if iszero(lt(o, replacementLength)) { break } } result := add(result, replacementLength) subject := add(subject, searchLength) if searchLength { if iszero(lt(subject, subjectSearchEnd)) { break } continue } } mstore(result, t) result := add(result, 1) subject := add(subject, 1) if iszero(lt(subject, subjectSearchEnd)) { break } } } let resultRemainder := result result := add(mload(0x40), 0x20) let k := add(sub(resultRemainder, result), sub(subjectEnd, subject)) // Copy the rest of the string one word at a time. for {} lt(subject, subjectEnd) {} { mstore(resultRemainder, mload(subject)) resultRemainder := add(resultRemainder, 0x20) subject := add(subject, 0x20) } result := sub(result, 0x20) let last := add(add(result, 0x20), k) // Zeroize the slot after the string. mstore(last, 0) mstore(0x40, add(last, 0x20)) // Allocate the memory. mstore(result, k) // Store the length. } } /// @dev Returns the byte index of the first location of `search` in `subject`, /// searching from left to right, starting from `from`. /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found. function indexOf(string memory subject, string memory search, uint256 from) internal pure returns (uint256 result) { /// @solidity memory-safe-assembly assembly { for { let subjectLength := mload(subject) } 1 {} { if iszero(mload(search)) { if iszero(gt(from, subjectLength)) { result := from break } result := subjectLength break } let searchLength := mload(search) let subjectStart := add(subject, 0x20) result := not(0) // Initialize to `NOT_FOUND`. subject := add(subjectStart, from) let end := add(sub(add(subjectStart, subjectLength), searchLength), 1) let m := shl(3, sub(0x20, and(searchLength, 0x1f))) let s := mload(add(search, 0x20)) if iszero(and(lt(subject, end), lt(from, subjectLength))) { break } if iszero(lt(searchLength, 0x20)) { for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} { if iszero(shr(m, xor(mload(subject), s))) { if eq(keccak256(subject, searchLength), h) { result := sub(subject, subjectStart) break } } subject := add(subject, 1) if iszero(lt(subject, end)) { break } } break } for {} 1 {} { if iszero(shr(m, xor(mload(subject), s))) { result := sub(subject, subjectStart) break } subject := add(subject, 1) if iszero(lt(subject, end)) { break } } break } } } /// @dev Returns the byte index of the first location of `search` in `subject`, /// searching from left to right. /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found. function indexOf(string memory subject, string memory search) internal pure returns (uint256 result) { result = indexOf(subject, search, 0); } /// @dev Returns the byte index of the first location of `search` in `subject`, /// searching from right to left, starting from `from`. /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found. function lastIndexOf(string memory subject, string memory search, uint256 from) internal pure returns (uint256 result) { /// @solidity memory-safe-assembly assembly { for {} 1 {} { result := not(0) // Initialize to `NOT_FOUND`. let searchLength := mload(search) if gt(searchLength, mload(subject)) { break } let w := result let fromMax := sub(mload(subject), searchLength) if iszero(gt(fromMax, from)) { from := fromMax } let end := add(add(subject, 0x20), w) subject := add(add(subject, 0x20), from) if iszero(gt(subject, end)) { break } // As this function is not too often used, // we shall simply use keccak256 for smaller bytecode size. for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} { if eq(keccak256(subject, searchLength), h) { result := sub(subject, add(end, 1)) break } subject := add(subject, w) // `sub(subject, 1)`. if iszero(gt(subject, end)) { break } } break } } } /// @dev Returns the byte index of the first location of `search` in `subject`, /// searching from right to left. /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found. function lastIndexOf(string memory subject, string memory search) internal pure returns (uint256 result) { result = lastIndexOf(subject, search, uint256(int256(-1))); } /// @dev Returns whether `subject` starts with `search`. function startsWith(string memory subject, string memory search) internal pure returns (bool result) { /// @solidity memory-safe-assembly assembly { let searchLength := mload(search) // Just using keccak256 directly is actually cheaper. // forgefmt: disable-next-item result := and( iszero(gt(searchLength, mload(subject))), eq( keccak256(add(subject, 0x20), searchLength), keccak256(add(search, 0x20), searchLength) ) ) } } /// @dev Returns whether `subject` ends with `search`. function endsWith(string memory subject, string memory search) internal pure returns (bool result) { /// @solidity memory-safe-assembly assembly { let searchLength := mload(search) let subjectLength := mload(subject) // Whether `search` is not longer than `subject`. let withinRange := iszero(gt(searchLength, subjectLength)) // Just using keccak256 directly is actually cheaper. // forgefmt: disable-next-item result := and( withinRange, eq( keccak256( // `subject + 0x20 + max(subjectLength - searchLength, 0)`. add(add(subject, 0x20), mul(withinRange, sub(subjectLength, searchLength))), searchLength ), keccak256(add(search, 0x20), searchLength) ) ) } } /// @dev Returns `subject` repeated `times`. function repeat(string memory subject, uint256 times) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let subjectLength := mload(subject) if iszero(or(iszero(times), iszero(subjectLength))) { subject := add(subject, 0x20) result := mload(0x40) let output := add(result, 0x20) for {} 1 {} { // Copy the `subject` one word at a time. for { let o := 0 } 1 {} { mstore(add(output, o), mload(add(subject, o))) o := add(o, 0x20) if iszero(lt(o, subjectLength)) { break } } output := add(output, subjectLength) times := sub(times, 1) if iszero(times) { break } } mstore(output, 0) // Zeroize the slot after the string. let resultLength := sub(output, add(result, 0x20)) mstore(result, resultLength) // Store the length. // Allocate the memory. mstore(0x40, add(result, add(resultLength, 0x20))) } } } /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive). /// `start` and `end` are byte offsets. function slice(string memory subject, uint256 start, uint256 end) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let subjectLength := mload(subject) if iszero(gt(subjectLength, end)) { end := subjectLength } if iszero(gt(subjectLength, start)) { start := subjectLength } if lt(start, end) { result := mload(0x40) let resultLength := sub(end, start) mstore(result, resultLength) subject := add(subject, start) let w := not(0x1f) // Copy the `subject` one word at a time, backwards. for { let o := and(add(resultLength, 0x1f), w) } 1 {} { mstore(add(result, o), mload(add(subject, o))) o := add(o, w) // `sub(o, 0x20)`. if iszero(o) { break } } // Zeroize the slot after the string. mstore(add(add(result, 0x20), resultLength), 0) // Allocate memory for the length and the bytes, // rounded up to a multiple of 32. mstore(0x40, add(result, and(add(resultLength, 0x3f), w))) } } } /// @dev Returns a copy of `subject` sliced from `start` to the end of the string. /// `start` is a byte offset. function slice(string memory subject, uint256 start) internal pure returns (string memory result) { result = slice(subject, start, uint256(int256(-1))); } /// @dev Returns all the indices of `search` in `subject`. /// The indices are byte offsets. function indicesOf(string memory subject, string memory search) internal pure returns (uint256[] memory result) { /// @solidity memory-safe-assembly assembly { let subjectLength := mload(subject) let searchLength := mload(search) if iszero(gt(searchLength, subjectLength)) { subject := add(subject, 0x20) search := add(search, 0x20) result := add(mload(0x40), 0x20) let subjectStart := subject let subjectSearchEnd := add(sub(add(subject, subjectLength), searchLength), 1) let h := 0 if iszero(lt(searchLength, 0x20)) { h := keccak256(search, searchLength) } let m := shl(3, sub(0x20, and(searchLength, 0x1f))) let s := mload(search) for {} 1 {} { let t := mload(subject) // Whether the first `searchLength % 32` bytes of // `subject` and `search` matches. if iszero(shr(m, xor(t, s))) { if h { if iszero(eq(keccak256(subject, searchLength), h)) { subject := add(subject, 1) if iszero(lt(subject, subjectSearchEnd)) { break } continue } } // Append to `result`. mstore(result, sub(subject, subjectStart)) result := add(result, 0x20) // Advance `subject` by `searchLength`. subject := add(subject, searchLength) if searchLength { if iszero(lt(subject, subjectSearchEnd)) { break } continue } } subject := add(subject, 1) if iszero(lt(subject, subjectSearchEnd)) { break } } let resultEnd := result // Assign `result` to the free memory pointer. result := mload(0x40) // Store the length of `result`. mstore(result, shr(5, sub(resultEnd, add(result, 0x20)))) // Allocate memory for result. // We allocate one more word, so this array can be recycled for {split}. mstore(0x40, add(resultEnd, 0x20)) } } } /// @dev Returns a arrays of strings based on the `delimiter` inside of the `subject` string. function split(string memory subject, string memory delimiter) internal pure returns (string[] memory result) { uint256[] memory indices = indicesOf(subject, delimiter); /// @solidity memory-safe-assembly assembly { let w := not(0x1f) let indexPtr := add(indices, 0x20) let indicesEnd := add(indexPtr, shl(5, add(mload(indices), 1))) mstore(add(indicesEnd, w), mload(subject)) mstore(indices, add(mload(indices), 1)) let prevIndex := 0 for {} 1 {} { let index := mload(indexPtr) mstore(indexPtr, 0x60) if iszero(eq(index, prevIndex)) { let element := mload(0x40) let elementLength := sub(index, prevIndex) mstore(element, elementLength) // Copy the `subject` one word at a time, backwards. for { let o := and(add(elementLength, 0x1f), w) } 1 {} { mstore(add(element, o), mload(add(add(subject, prevIndex), o))) o := add(o, w) // `sub(o, 0x20)`. if iszero(o) { break } } // Zeroize the slot after the string. mstore(add(add(element, 0x20), elementLength), 0) // Allocate memory for the length and the bytes, // rounded up to a multiple of 32. mstore(0x40, add(element, and(add(elementLength, 0x3f), w))) // Store the `element` into the array. mstore(indexPtr, element) } prevIndex := add(index, mload(delimiter)) indexPtr := add(indexPtr, 0x20) if iszero(lt(indexPtr, indicesEnd)) { break } } result := indices if iszero(mload(delimiter)) { result := add(indices, 0x20) mstore(result, sub(mload(indices), 2)) } } } /// @dev Returns a concatenated string of `a` and `b`. /// Cheaper than `string.concat()` and does not de-align the free memory pointer. function concat(string memory a, string memory b) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let w := not(0x1f) result := mload(0x40) let aLength := mload(a) // Copy `a` one word at a time, backwards. for { let o := and(add(mload(a), 0x20), w) } 1 {} { mstore(add(result, o), mload(add(a, o))) o := add(o, w) // `sub(o, 0x20)`. if iszero(o) { break } } let bLength := mload(b) let output := add(result, mload(a)) // Copy `b` one word at a time, backwards. for { let o := and(add(bLength, 0x20), w) } 1 {} { mstore(add(output, o), mload(add(b, o))) o := add(o, w) // `sub(o, 0x20)`. if iszero(o) { break } } let totalLength := add(aLength, bLength) let last := add(add(result, 0x20), totalLength) // Zeroize the slot after the string. mstore(last, 0) // Stores the length. mstore(result, totalLength) // Allocate memory for the length and the bytes, // rounded up to a multiple of 32. mstore(0x40, and(add(last, 0x1f), w)) } } /// @dev Returns a copy of the string in either lowercase or UPPERCASE. /// WARNING! This function is only compatible with 7-bit ASCII strings. function toCase(string memory subject, bool toUpper) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let length := mload(subject) if length { result := add(mload(0x40), 0x20) subject := add(subject, 1) let flags := shl(add(70, shl(5, toUpper)), 0x3ffffff) let w := not(0) for { let o := length } 1 {} { o := add(o, w) let b := and(0xff, mload(add(subject, o))) mstore8(add(result, o), xor(b, and(shr(b, flags), 0x20))) if iszero(o) { break } } result := mload(0x40) mstore(result, length) // Store the length. let last := add(add(result, 0x20), length) mstore(last, 0) // Zeroize the slot after the string. mstore(0x40, add(last, 0x20)) // Allocate the memory. } } } /// @dev Returns a lowercased copy of the string. /// WARNING! This function is only compatible with 7-bit ASCII strings. function lower(string memory subject) internal pure returns (string memory result) { result = toCase(subject, false); } /// @dev Returns an UPPERCASED copy of the string. /// WARNING! This function is only compatible with 7-bit ASCII strings. function upper(string memory subject) internal pure returns (string memory result) { result = toCase(subject, true); } /// @dev Escapes the string to be used within HTML tags. function escapeHTML(string memory s) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { for { let end := add(s, mload(s)) result := add(mload(0x40), 0x20) // Store the bytes of the packed offsets and strides into the scratch space. // `packed = (stride << 5) | offset`. Max offset is 20. Max stride is 6. mstore(0x1f, 0x900094) mstore(0x08, 0xc0000000a6ab) // Store ""&'<>" into the scratch space. mstore(0x00, shl(64, 0x2671756f743b26616d703b262333393b266c743b2667743b)) } iszero(eq(s, end)) {} { s := add(s, 1) let c := and(mload(s), 0xff) // Not in `["\"","'","&","<",">"]`. if iszero(and(shl(c, 1), 0x500000c400000000)) { mstore8(result, c) result := add(result, 1) continue } let t := shr(248, mload(c)) mstore(result, mload(and(t, 0x1f))) result := add(result, shr(5, t)) } let last := result mstore(last, 0) // Zeroize the slot after the string. result := mload(0x40) mstore(result, sub(last, add(result, 0x20))) // Store the length. mstore(0x40, add(last, 0x20)) // Allocate the memory. } } /// @dev Escapes the string to be used within double-quotes in a JSON. function escapeJSON(string memory s) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { for { let end := add(s, mload(s)) result := add(mload(0x40), 0x20) // Store "\\u0000" in scratch space. // Store "0123456789abcdef" in scratch space. // Also, store `{0x08:"b", 0x09:"t", 0x0a:"n", 0x0c:"f", 0x0d:"r"}`. // into the scratch space. mstore(0x15, 0x5c75303030303031323334353637383961626364656662746e006672) // Bitmask for detecting `["\"","\\"]`. let e := or(shl(0x22, 1), shl(0x5c, 1)) } iszero(eq(s, end)) {} { s := add(s, 1) let c := and(mload(s), 0xff) if iszero(lt(c, 0x20)) { if iszero(and(shl(c, 1), e)) { // Not in `["\"","\\"]`. mstore8(result, c) result := add(result, 1) continue } mstore8(result, 0x5c) // "\\". mstore8(add(result, 1), c) result := add(result, 2) continue } if iszero(and(shl(c, 1), 0x3700)) { // Not in `["\b","\t","\n","\f","\d"]`. mstore8(0x1d, mload(shr(4, c))) // Hex value. mstore8(0x1e, mload(and(c, 15))) // Hex value. mstore(result, mload(0x19)) // "\\u00XX". result := add(result, 6) continue } mstore8(result, 0x5c) // "\\". mstore8(add(result, 1), mload(add(c, 8))) result := add(result, 2) } let last := result mstore(last, 0) // Zeroize the slot after the string. result := mload(0x40) mstore(result, sub(last, add(result, 0x20))) // Store the length. mstore(0x40, add(last, 0x20)) // Allocate the memory. } } /// @dev Returns whether `a` equals `b`. function eq(string memory a, string memory b) internal pure returns (bool result) { assembly { result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b))) } } /// @dev Packs a single string with its length into a single word. /// Returns `bytes32(0)` if the length is zero or greater than 31. function packOne(string memory a) internal pure returns (bytes32 result) { /// @solidity memory-safe-assembly assembly { // We don't need to zero right pad the string, // since this is our own custom non-standard packing scheme. result := mul( // Load the length and the bytes. mload(add(a, 0x1f)), // `length != 0 && length < 32`. Abuses underflow. // Assumes that the length is valid and within the block gas limit. lt(sub(mload(a), 1), 0x1f) ) } } /// @dev Unpacks a string packed using {packOne}. /// Returns the empty string if `packed` is `bytes32(0)`. /// If `packed` is not an output of {packOne}, the output behaviour is undefined. function unpackOne(bytes32 packed) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { // Grab the free memory pointer. result := mload(0x40) // Allocate 2 words (1 for the length, 1 for the bytes). mstore(0x40, add(result, 0x40)) // Zeroize the length slot. mstore(result, 0) // Store the length and bytes. mstore(add(result, 0x1f), packed) // Right pad with zeroes. mstore(add(add(result, 0x20), mload(result)), 0) } } /// @dev Packs two strings with their lengths into a single word. /// Returns `bytes32(0)` if combined length is zero or greater than 30. function packTwo(string memory a, string memory b) internal pure returns (bytes32 result) { /// @solidity memory-safe-assembly assembly { let aLength := mload(a) // We don't need to zero right pad the strings, // since this is our own custom non-standard packing scheme. result := mul( // Load the length and the bytes of `a` and `b`. or( shl(shl(3, sub(0x1f, aLength)), mload(add(a, aLength))), mload(sub(add(b, 0x1e), aLength)) ), // `totalLength != 0 && totalLength < 31`. Abuses underflow. // Assumes that the lengths are valid and within the block gas limit. lt(sub(add(aLength, mload(b)), 1), 0x1e) ) } } /// @dev Unpacks strings packed using {packTwo}. /// Returns the empty strings if `packed` is `bytes32(0)`. /// If `packed` is not an output of {packTwo}, the output behaviour is undefined. function unpackTwo(bytes32 packed) internal pure returns (string memory resultA, string memory resultB) { /// @solidity memory-safe-assembly assembly { // Grab the free memory pointer. resultA := mload(0x40) resultB := add(resultA, 0x40) // Allocate 2 words for each string (1 for the length, 1 for the byte). Total 4 words. mstore(0x40, add(resultB, 0x40)) // Zeroize the length slots. mstore(resultA, 0) mstore(resultB, 0) // Store the lengths and bytes. mstore(add(resultA, 0x1f), packed) mstore(add(resultB, 0x1f), mload(add(add(resultA, 0x20), mload(resultA)))) // Right pad with zeroes. mstore(add(add(resultA, 0x20), mload(resultA)), 0) mstore(add(add(resultB, 0x20), mload(resultB)), 0) } } /// @dev Directly returns `a` without copying. function directReturn(string memory a) internal pure { assembly { // Assumes that the string does not start from the scratch space. let retStart := sub(a, 0x20) let retSize := add(mload(a), 0x40) // Right pad with zeroes. Just in case the string is produced // by a method that doesn't zero right pad. mstore(add(retStart, retSize), 0) // Store the return offset. mstore(retStart, 0x20) // End the transaction, returning the string. return(retStart, retSize) } } } // File: contracts/ERC721r.sol // pragma solidity ^0.8.17; //import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; //import {ERC721} from "solady/src/tokens/ERC721.sol"; //import {LibPRNG} from "solady/src/utils/LibPRNG.sol"; //import {LibString} from "solady/src/utils/LibString.sol"; abstract contract ERC721r is ERC721 { using LibPRNG for LibPRNG.PRNG; using LibString for uint256; error ContractsCannotMint(); error MustMintAtLeastOneToken(); error NotEnoughAvailableTokens(); string private _name; string private _symbol; mapping(uint256 => uint256) private _availableTokens; uint256 public remainingSupply; uint256 public immutable maxSupply; constructor(string memory name_, string memory symbol_, uint256 maxSupply_) { _name = name_; _symbol = symbol_; maxSupply = maxSupply_; remainingSupply = maxSupply_; } function totalSupply() public view virtual returns (uint256) { return maxSupply - remainingSupply; } function name() public view virtual override returns (string memory) { return _name; } function symbol() public view virtual override returns (string memory) { return _symbol; } function numberMinted(address minter) public view virtual returns (uint32) { return uint32(ERC721._getAux(minter) >> 192); } function _mintRandom(address to, uint256 _numToMint) internal virtual { if (msg.sender != tx.origin) revert ContractsCannotMint(); if (_numToMint == 0) revert MustMintAtLeastOneToken(); if (remainingSupply < _numToMint) revert NotEnoughAvailableTokens(); LibPRNG.PRNG memory prng = LibPRNG.PRNG(uint256(keccak256(abi.encodePacked( block.timestamp, block.prevrandao )))); uint256 updatedRemainingSupply = remainingSupply; for (uint256 i; i < _numToMint; ) { uint256 randomIndex = prng.uniform(updatedRemainingSupply); uint256 tokenId = getAvailableTokenAtIndex(randomIndex, updatedRemainingSupply); _mint(to, tokenId); --updatedRemainingSupply; unchecked {++i;} } _incrementAmountMinted(to, uint32(_numToMint)); remainingSupply = updatedRemainingSupply; } // Must be called in descending order of index function _mintAtIndex(address to, uint256 index) internal virtual { if (msg.sender != tx.origin) revert ContractsCannotMint(); if (remainingSupply == 0) revert NotEnoughAvailableTokens(); uint256 tokenId = getAvailableTokenAtIndex(index, remainingSupply); --remainingSupply; _incrementAmountMinted(to, 1); _mint(to, tokenId); } // Implements https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle. Code taken from CryptoPhunksV2 function getAvailableTokenAtIndex(uint256 indexToUse, uint256 updatedNumAvailableTokens) private returns (uint256 result) { uint256 valAtIndex = _availableTokens[indexToUse]; uint256 lastIndex = updatedNumAvailableTokens - 1; uint256 lastValInArray = _availableTokens[lastIndex]; result = valAtIndex == 0 ? indexToUse : valAtIndex; if (indexToUse != lastIndex) { _availableTokens[indexToUse] = lastValInArray == 0 ? lastIndex : lastValInArray; } if (lastValInArray != 0) { delete _availableTokens[lastIndex]; } } function _setExtraAddressData(address minter, uint192 extraData) internal virtual { uint32 numMinted = numberMinted(minter); ERC721._setAux( minter, uint224((uint256(numMinted) << 192)) | uint224(extraData) ); } function _getAddressExtraData(address minter) internal view virtual returns (uint192) { return uint192(_getAux(minter)); } function _incrementAmountMinted(address minter, uint32 newMints) private { uint32 numMinted = numberMinted(minter); uint32 newMintNumMinted = numMinted + uint32(newMints); uint224 auxData = ERC721._getAux(minter); ERC721._setAux( minter, uint224(uint256(newMintNumMinted) << 192) | uint224(uint192(auxData)) ); } } // File: contracts/MetaLifeVehicle.sol // pragma solidity 0.8.23; contract MetaLifeVehicle is ReentrancyGuard, Ownable, ERC721r { using Strings for uint256; string public baseURI; uint16 public mainMaxSupply = 1200; uint16 public nbMintedCouncil = 0; uint16 public nbMintedHonorary = 0; uint16 public nbMintedGuardian = 0; uint16 public nbMintedJudge = 0; uint16 public nbMintedWhale = 0; uint16 public maxSupplyCouncil = 250; uint16 public maxSupplyHonorary = 66; uint16 public maxSupplyGuardian = 22; uint16 public maxSupplyJudge = 10; uint16 public maxSupplyWhale = 31; // Fri May 31 2024 21:59:59 GMT+0000 uint256 public limitSpecialMint = 1717192799; address public originOwner = 0x87a1AB9Aab7BAE43AD4ce4951A93e7F5bBCAc230; address payable public collector; struct Eligibility { uint8 total; uint8 claimed; } mapping(address => Eligibility) public allowlistRandom; event MintedRandom(address indexed from, uint256 timestamp); uint16 private _tokenIdCurrentCouncil = 822; mapping(address => Eligibility) public allowlistCouncil; event MintedCouncil(address indexed from, uint256 timestamp, uint16[] tokenIds); uint16 private _tokenIdCurrentHonorary = 1072; mapping(address => Eligibility) public allowlistHonorary; event MintedHonorary(address indexed from, uint256 timestamp, uint16[] tokenIds); uint16 private _tokenIdCurrentGuardian = 1138; mapping(address => Eligibility) public allowlistGuardian; event MintedGuardian(address indexed from, uint256 timestamp, uint16 tokenId); uint16 private _tokenIdCurrentJudge = 1160; mapping(address => Eligibility) public allowlistJudge; event MintedJudge(address indexed from, uint256 timestamp, uint16 tokenId); uint16 private _tokenIdCurrentWhale = 1170; mapping(address => Eligibility) public allowlistWhale; event MintedWhale(address indexed from, uint256 timestamp, uint16[] tokenIds); constructor() ERC721r('Meta-Life Vehicle', 'MLV', 8_20) Ownable(originOwner){} function withdrawAll() public payable onlyOwner { collector.transfer(address(this).balance); } function setCollector(address payable _newCollector) public onlyOwner { collector = _newCollector; } function _setBaseURI(string memory _newBaseURI) public onlyOwner { baseURI = _newBaseURI; } function _baseURI() internal view virtual returns (string memory) { return baseURI; } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), 'unknow token'); string memory uri = _baseURI(); return bytes(uri).length > 0 ? string(abi.encodePacked(uri, tokenId.toString())) : ""; } function tokenExist(uint256 tokenId) public view returns(bool) { return _exists(tokenId); } function mainTotalSupply() public view returns (uint256){ return totalSupply() + nbMintedCouncil + nbMintedHonorary + nbMintedGuardian + nbMintedJudge + nbMintedWhale; } function remainingRandom(address wallet) public view virtual returns (uint8) { return allowlistRandom[wallet].total - allowlistRandom[wallet].claimed; } function remainingCouncil(address wallet) public view virtual returns (uint8) { return allowlistCouncil[wallet].total - allowlistCouncil[wallet].claimed; } function remainingHonorary(address wallet) public view virtual returns (uint8) { return allowlistHonorary[wallet].total - allowlistHonorary[wallet].claimed; } function remainingWhale(address wallet) public view virtual returns (uint8) { return allowlistWhale[wallet].total - allowlistWhale[wallet].claimed; } function remainingJudge(address wallet) public view virtual returns (uint8) { return allowlistJudge[wallet].total - allowlistJudge[wallet].claimed; } function remainingGuardian(address wallet) public view virtual returns (uint8) { return allowlistGuardian[wallet].total - allowlistGuardian[wallet].claimed; } function addAllowlistRandom(address[] calldata _toAddAddresses, uint8[] calldata _quantities) external onlyOwner { require(_toAddAddresses.length == _quantities.length, 'Nb address and nb quantities must be equal'); for (uint i = 0; i < _toAddAddresses.length; i++) { allowlistRandom[_toAddAddresses[i]].total += _quantities[i]; } } function mintRandom(uint8 _quantities) external { require(remainingRandom(msg.sender) > 0, "Not eligible"); require(remainingRandom(msg.sender) >= _quantities, "Not enough claimable tokens"); require(maxSupply >= totalSupply() + _quantities, "Supply limit exceed"); allowlistRandom[msg.sender].claimed += _quantities; _mintRandom(msg.sender, _quantities); emit MintedRandom(msg.sender, block.timestamp); } function addAllowlistCouncil(address[] calldata _toAddAddresses, uint8[] calldata _quantities) external onlyOwner { require(_toAddAddresses.length == _quantities.length, 'Nb address and nb quantities must be equal'); for (uint i = 0; i < _toAddAddresses.length; i++) { allowlistCouncil[_toAddAddresses[i]].total = _quantities[i]; } } function mintCouncil(uint8 _quantities) external { require(block.timestamp < limitSpecialMint, "Council mint close"); require(remainingCouncil(msg.sender) > 0, "Not eligible"); require(remainingCouncil(msg.sender) >= _quantities, "Not enough claimable tokens"); require(nbMintedCouncil + _quantities <= maxSupplyCouncil, "Max supply council exceed"); uint16[] memory _tokenIdsMinted = new uint16[](_quantities); allowlistCouncil[msg.sender].claimed += _quantities; for (uint8 i = 0; i < _quantities; i++) { _safeMint(msg.sender, _tokenIdCurrentCouncil); _tokenIdsMinted[i] = _tokenIdCurrentCouncil; _tokenIdCurrentCouncil++; nbMintedCouncil++; } emit MintedCouncil(msg.sender, block.timestamp, _tokenIdsMinted); } function addAllowlistHonorary(address[] calldata _toAddAddresses, uint8[] calldata _quantities) external onlyOwner { require(_toAddAddresses.length == _quantities.length, 'Nb address and nb quantities must be equal'); for (uint i = 0; i < _toAddAddresses.length; i++) { allowlistHonorary[_toAddAddresses[i]].total = _quantities[i]; } } function mintHonorary(uint8 _quantities) external { require(block.timestamp < limitSpecialMint, "Honorary mint close"); require(remainingHonorary(msg.sender) > 0, "Not eligible"); require(remainingHonorary(msg.sender) >= _quantities, "Not enough claimable tokens"); require(nbMintedHonorary + _quantities <= maxSupplyHonorary, "Max supply honorary exceed"); uint16[] memory _tokenIdsMinted = new uint16[](_quantities); allowlistHonorary[msg.sender].claimed += _quantities; for (uint8 i = 0; i < _quantities; i++) { _safeMint(msg.sender, _tokenIdCurrentHonorary); _tokenIdsMinted[i] = _tokenIdCurrentHonorary; _tokenIdCurrentHonorary++; nbMintedHonorary++; } emit MintedHonorary(msg.sender, block.timestamp, _tokenIdsMinted); } function addAllowlistGuardian(address[] calldata _toAddAddresses) external onlyOwner { for (uint i = 0; i < _toAddAddresses.length; i++) { allowlistGuardian[_toAddAddresses[i]].total = 1; } } function mintGuardian() external { require(block.timestamp < limitSpecialMint, "Guardian mint close"); require(remainingGuardian(msg.sender) > 0, "No giveway"); require(nbMintedGuardian + 1 <= maxSupplyGuardian, "Max supply guardian exceed"); allowlistGuardian[msg.sender].claimed = 1; _safeMint(msg.sender, _tokenIdCurrentGuardian); emit MintedGuardian(msg.sender, block.timestamp, _tokenIdCurrentGuardian); _tokenIdCurrentGuardian++; nbMintedGuardian++; } function addAllowlistJudge(address[] calldata _toAddAddresses) external onlyOwner { for (uint i = 0; i < _toAddAddresses.length; i++) { allowlistJudge[_toAddAddresses[i]].total = 1; } } function mintJudge() external { require(block.timestamp < limitSpecialMint, "Judge mint close"); require(remainingJudge(msg.sender) > 0, "Not eligible"); require(nbMintedJudge + 1 <= maxSupplyJudge, "Max supply judge exceed"); allowlistJudge[msg.sender].claimed = 1; _safeMint(msg.sender, _tokenIdCurrentJudge); emit MintedJudge(msg.sender, block.timestamp, _tokenIdCurrentJudge); _tokenIdCurrentJudge++; nbMintedJudge++; } function addAllowlistWhale(address[] calldata _toAddAddresses, uint8[] calldata _quantities) external onlyOwner { for (uint i = 0; i < _toAddAddresses.length; i++) { allowlistWhale[_toAddAddresses[i]].total = _quantities[i]; } } function mintWhale(uint8 _quantities) external { require(block.timestamp < limitSpecialMint, "Whale mint close"); require(remainingWhale(msg.sender) > 0, "Not eligible"); require(remainingWhale(msg.sender) >= _quantities, "Not enough claimable tokens"); require(nbMintedWhale + _quantities <= maxSupplyCouncil, "Max supply whale exceed"); uint16[] memory _tokenIdsMinted = new uint16[](_quantities); allowlistWhale[msg.sender].claimed += _quantities; for (uint8 i = 0; i < _quantities; i++) { _safeMint(msg.sender, _tokenIdCurrentWhale); _tokenIdsMinted[i] = _tokenIdCurrentWhale; _tokenIdCurrentWhale++; nbMintedWhale++; } emit MintedWhale(msg.sender, block.timestamp, _tokenIdsMinted); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountBalanceOverflow","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"ContractsCannotMint","type":"error"},{"inputs":[],"name":"MustMintAtLeastOneToken","type":"error"},{"inputs":[],"name":"NotEnoughAvailableTokens","type":"error"},{"inputs":[],"name":"NotOwnerNorApproved","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":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","type":"error"},{"inputs":[],"name":"TokenDoesNotExist","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","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":"isApproved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint16[]","name":"tokenIds","type":"uint16[]"}],"name":"MintedCouncil","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"tokenId","type":"uint16"}],"name":"MintedGuardian","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint16[]","name":"tokenIds","type":"uint16[]"}],"name":"MintedHonorary","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"tokenId","type":"uint16"}],"name":"MintedJudge","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"MintedRandom","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint16[]","name":"tokenIds","type":"uint16[]"}],"name":"MintedWhale","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"_setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"},{"internalType":"uint8[]","name":"_quantities","type":"uint8[]"}],"name":"addAllowlistCouncil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"}],"name":"addAllowlistGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"},{"internalType":"uint8[]","name":"_quantities","type":"uint8[]"}],"name":"addAllowlistHonorary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"}],"name":"addAllowlistJudge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"},{"internalType":"uint8[]","name":"_quantities","type":"uint8[]"}],"name":"addAllowlistRandom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"},{"internalType":"uint8[]","name":"_quantities","type":"uint8[]"}],"name":"addAllowlistWhale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowlistCouncil","outputs":[{"internalType":"uint8","name":"total","type":"uint8"},{"internalType":"uint8","name":"claimed","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowlistGuardian","outputs":[{"internalType":"uint8","name":"total","type":"uint8"},{"internalType":"uint8","name":"claimed","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowlistHonorary","outputs":[{"internalType":"uint8","name":"total","type":"uint8"},{"internalType":"uint8","name":"claimed","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowlistJudge","outputs":[{"internalType":"uint8","name":"total","type":"uint8"},{"internalType":"uint8","name":"claimed","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowlistRandom","outputs":[{"internalType":"uint8","name":"total","type":"uint8"},{"internalType":"uint8","name":"claimed","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowlistWhale","outputs":[{"internalType":"uint8","name":"total","type":"uint8"},{"internalType":"uint8","name":"claimed","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collector","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"result","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":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"limitSpecialMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mainMaxSupply","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mainTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyCouncil","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyGuardian","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyHonorary","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyJudge","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyWhale","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_quantities","type":"uint8"}],"name":"mintCouncil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_quantities","type":"uint8"}],"name":"mintHonorary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintJudge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_quantities","type":"uint8"}],"name":"mintRandom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_quantities","type":"uint8"}],"name":"mintWhale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nbMintedCouncil","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nbMintedGuardian","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nbMintedHonorary","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nbMintedJudge","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nbMintedWhale","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"originOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"remainingCouncil","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"remainingGuardian","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"remainingHonorary","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"remainingJudge","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"remainingRandom","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"remainingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"remainingWhale","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","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":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"isApproved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_newCollector","type":"address"}],"name":"setCollector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"result","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":"tokenExist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
60a06040526104b060075f6101000a81548161ffff021916908361ffff1602179055505f600760026101000a81548161ffff021916908361ffff1602179055505f600760046101000a81548161ffff021916908361ffff1602179055505f600760066101000a81548161ffff021916908361ffff1602179055505f600760086101000a81548161ffff021916908361ffff1602179055505f6007600a6101000a81548161ffff021916908361ffff16021790555060fa6007600c6101000a81548161ffff021916908361ffff16021790555060426007600e6101000a81548161ffff021916908361ffff1602179055506016600760106101000a81548161ffff021916908361ffff160217905550600a600760126101000a81548161ffff021916908361ffff160217905550601f600760146101000a81548161ffff021916908361ffff16021790555063665a485f6008557387a1ab9aab7bae43ad4ce4951a93e7f5bbcac23060095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610336600c5f6101000a81548161ffff021916908361ffff160217905550610430600e5f6101000a81548161ffff021916908361ffff16021790555061047260105f6101000a81548161ffff021916908361ffff16021790555061048860125f6101000a81548161ffff021916908361ffff16021790555061049260145f6101000a81548161ffff021916908361ffff16021790555034801562000247575f80fd5b506040518060400160405280601181526020017f4d6574612d4c6966652056656869636c650000000000000000000000000000008152506040518060400160405280600381526020017f4d4c56000000000000000000000000000000000000000000000000000000000081525061033460095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660015f819055505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160362000353575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016200034a9190620004a7565b60405180910390fd5b6200036481620003a160201b60201c565b50826002908162000376919062000726565b50816003908162000388919062000726565b508060808181525050806005819055505050506200080a565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200048f8262000464565b9050919050565b620004a18162000483565b82525050565b5f602082019050620004bc5f83018462000496565b92915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200053e57607f821691505b602082108103620005545762000553620004f9565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620005b87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200057b565b620005c486836200057b565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200060e620006086200060284620005dc565b620005e5565b620005dc565b9050919050565b5f819050919050565b6200062983620005ee565b62000641620006388262000615565b84845462000587565b825550505050565b5f90565b6200065762000649565b620006648184846200061e565b505050565b5b818110156200068b576200067f5f826200064d565b6001810190506200066a565b5050565b601f821115620006da57620006a4816200055a565b620006af846200056c565b81016020851015620006bf578190505b620006d7620006ce856200056c565b83018262000669565b50505b505050565b5f82821c905092915050565b5f620006fc5f1984600802620006df565b1980831691505092915050565b5f620007168383620006eb565b9150826002028217905092915050565b6200073182620004c2565b67ffffffffffffffff8111156200074d576200074c620004cc565b5b62000759825462000526565b620007668282856200068f565b5f60209050601f8311600181146200079c575f841562000787578287015190505b62000793858262000709565b86555062000802565b601f198416620007ac866200055a565b5f5b82811015620007d557848901518255600182019150602085019450602081019050620007ae565b86831015620007f55784890151620007f1601f891682620006eb565b8355505b6001600288020188555050505b505050505050565b6080516154d2620008315f395f8181611419015281816116b0015261316e01526154d25ff3fe6080604052600436106103c2575f3560e01c80637a12ef82116101f1578063b88d4fde1161010c578063dc33e6811161009f578063ea3d74181161006e578063ea3d741814610e60578063f2fde38b14610e8a578063fb5b82d014610eb2578063fc89067914610eda576103c2565b8063dc33e68114610d6e578063dd330e4d14610daa578063df1dc2c514610de7578063e985e9c514610e24576103c2565b8063cc0c5236116100db578063cc0c523614610cb6578063d5abeb0114610cf2578063da0239a614610d1c578063dab00abb14610d46576103c2565b8063b88d4fde14610c0e578063b904e37a14610c2a578063bc68ed6c14610c52578063c87b56dd14610c7a576103c2565b8063916ec2c611610184578063a22cb46511610153578063a22cb46514610b6c578063a2cd568914610b94578063ac497a4814610bbe578063b55698d514610be6576103c2565b8063916ec2c614610ac657806391ec4b4c14610af057806395d89b4114610b1a5780639a3e276814610b44576103c2565b8063889960ea116101c0578063889960ea14610a0c5780638b4303a614610a485780638da5cb5b14610a72578063913e77ad14610a9c576103c2565b80637a12ef82146109885780637ca470b1146109b0578063853828b6146109da57806385ad1cf5146109e4576103c2565b80632ff1474d116102e157806352186417116102745780636c0360eb116102435780636c0360eb146108e457806370a082311461090e578063715018a61461094a5780637400c92214610960576103c2565b806352186417146108055780635d42a059146108415780636352211e1461087e5780636802e529146108ba576103c2565b8063376e1b1f116102b0578063376e1b1f1461076d57806342842e0e1461078357806346fbed6f1461079f5780634e27acff146107c9576103c2565b80632ff1474d146106a257806331b5b907146106de57806333a3600714610706578063343bc89314610730576103c2565b8063106e707b1161035957806323b872dd1161032857806323b872dd146105f757806326d6327914610613578063282e7811146106505780632db5b8e71461067a576103c2565b8063106e707b1461053d57806318160ddd146105795780631bf3dd4f146105a35780631d490ee3146105cd576103c2565b806306fdde031161039557806306fdde031461049157806307edf9ef146104bb578063081812fc146104e5578063095ea7b314610521576103c2565b80630129b0b9146103c657806301ffc9a714610403578063022c01991461043f5780630322ba9814610455575b5f80fd5b3480156103d1575f80fd5b506103ec60048036038101906103e79190613e8d565b610f04565b6040516103fa929190613ed3565b60405180910390f35b34801561040e575f80fd5b5061042960048036038101906104249190613f4f565b610f3c565b6040516104369190613f94565b60405180910390f35b34801561044a575f80fd5b50610453610f60565b005b348015610460575f80fd5b5061047b60048036038101906104769190613e8d565b6111b4565b6040516104889190613fad565b60405180910390f35b34801561049c575f80fd5b506104a561125f565b6040516104b29190614050565b60405180910390f35b3480156104c6575f80fd5b506104cf6112ef565b6040516104dc919061408c565b60405180910390f35b3480156104f0575f80fd5b5061050b600480360381019061050691906140d8565b611303565b6040516105189190614112565b60405180910390f35b61053b6004803603810190610536919061412b565b611359565b005b348015610548575f80fd5b50610563600480360381019061055e9190613e8d565b611368565b6040516105709190613fad565b60405180910390f35b348015610584575f80fd5b5061058d611413565b60405161059a9190614178565b60405180910390f35b3480156105ae575f80fd5b506105b7611447565b6040516105c49190614178565b60405180910390f35b3480156105d8575f80fd5b506105e161144d565b6040516105ee919061408c565b60405180910390f35b610611600480360381019061060c9190614191565b611461565b005b34801561061e575f80fd5b5061063960048036038101906106349190613e8d565b61159d565b604051610647929190613ed3565b60405180910390f35b34801561065b575f80fd5b506106646115d5565b6040516106719190614112565b60405180910390f35b348015610685575f80fd5b506106a0600480360381019061069b919061420b565b6115fa565b005b3480156106ad575f80fd5b506106c860048036038101906106c39190613e8d565b6117e1565b6040516106d59190613fad565b60405180910390f35b3480156106e9575f80fd5b5061070460048036038101906106ff9190614362565b61188c565b005b348015610711575f80fd5b5061071a6118a7565b6040516107279190614178565b60405180910390f35b34801561073b575f80fd5b5061075660048036038101906107519190613e8d565b611950565b604051610764929190613ed3565b60405180910390f35b348015610778575f80fd5b50610781611988565b005b61079d60048036038101906107989190614191565b611bdc565b005b3480156107aa575f80fd5b506107b3611c15565b6040516107c0919061408c565b60405180910390f35b3480156107d4575f80fd5b506107ef60048036038101906107ea9190613e8d565b611c29565b6040516107fc9190613fad565b60405180910390f35b348015610810575f80fd5b5061082b60048036038101906108269190613e8d565b611cd4565b6040516108389190613fad565b60405180910390f35b34801561084c575f80fd5b5061086760048036038101906108629190613e8d565b611d7f565b604051610875929190613ed3565b60405180910390f35b348015610889575f80fd5b506108a4600480360381019061089f91906140d8565b611db7565b6040516108b19190614112565b60405180910390f35b3480156108c5575f80fd5b506108ce611dda565b6040516108db919061408c565b60405180910390f35b3480156108ef575f80fd5b506108f8611dee565b6040516109059190614050565b60405180910390f35b348015610919575f80fd5b50610934600480360381019061092f9190613e8d565b611e7a565b6040516109419190614178565b60405180910390f35b348015610955575f80fd5b5061095e611ec7565b005b34801561096b575f80fd5b506109866004803603810190610981919061420b565b611eda565b005b348015610993575f80fd5b506109ae60048036038101906109a99190614406565b612237565b005b3480156109bb575f80fd5b506109c46122dd565b6040516109d1919061408c565b60405180910390f35b6109e26122f1565b005b3480156109ef575f80fd5b50610a0a6004803603810190610a05919061420b565b612360565b005b348015610a17575f80fd5b50610a326004803603810190610a2d9190613e8d565b6126bd565b604051610a3f9190613fad565b60405180910390f35b348015610a53575f80fd5b50610a5c612768565b604051610a69919061408c565b60405180910390f35b348015610a7d575f80fd5b50610a8661277b565b604051610a939190614112565b60405180910390f35b348015610aa7575f80fd5b50610ab06127a3565b604051610abd9190614471565b60405180910390f35b348015610ad1575f80fd5b50610ada6127c8565b604051610ae7919061408c565b60405180910390f35b348015610afb575f80fd5b50610b046127dc565b604051610b11919061408c565b60405180910390f35b348015610b25575f80fd5b50610b2e6127f0565b604051610b3b9190614050565b60405180910390f35b348015610b4f575f80fd5b50610b6a6004803603810190610b6591906144df565b612880565b005b348015610b77575f80fd5b50610b926004803603810190610b8d9190614587565b612996565b005b348015610b9f575f80fd5b50610ba86129e9565b604051610bb5919061408c565b60405180910390f35b348015610bc9575f80fd5b50610be46004803603810190610bdf91906144df565b6129fd565b005b348015610bf1575f80fd5b50610c0c6004803603810190610c0791906144df565b612b2e565b005b610c286004803603810190610c23919061461a565b612c44565b005b348015610c35575f80fd5b50610c506004803603810190610c4b9190614406565b612cb4565b005b348015610c5d575f80fd5b50610c786004803603810190610c73919061420b565b612d5a565b005b348015610c85575f80fd5b50610ca06004803603810190610c9b91906140d8565b6130b7565b604051610cad9190614050565b60405180910390f35b348015610cc1575f80fd5b50610cdc6004803603810190610cd791906140d8565b61315b565b604051610ce99190613f94565b60405180910390f35b348015610cfd575f80fd5b50610d0661316c565b604051610d139190614178565b60405180910390f35b348015610d27575f80fd5b50610d30613190565b604051610d3d9190614178565b60405180910390f35b348015610d51575f80fd5b50610d6c6004803603810190610d6791906144df565b613196565b005b348015610d79575f80fd5b50610d946004803603810190610d8f9190613e8d565b613264565b604051610da191906146bc565b60405180910390f35b348015610db5575f80fd5b50610dd06004803603810190610dcb9190613e8d565b613297565b604051610dde929190613ed3565b60405180910390f35b348015610df2575f80fd5b50610e0d6004803603810190610e089190613e8d565b6132cf565b604051610e1b929190613ed3565b60405180910390f35b348015610e2f575f80fd5b50610e4a6004803603810190610e4591906146d5565b613307565b604051610e579190613f94565b60405180910390f35b348015610e6b575f80fd5b50610e74613329565b604051610e81919061408c565b60405180910390f35b348015610e95575f80fd5b50610eb06004803603810190610eab9190613e8d565b61333d565b005b348015610ebd575f80fd5b50610ed86004803603810190610ed3919061473d565b6133c1565b005b348015610ee5575f80fd5b50610eee61340c565b604051610efb919061408c565b60405180910390f35b600f602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b5f8160e01c635b5e139f81146380ac58cd82146301ffc9a783141717915050919050565b6008544210610fa4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9b906147b2565b60405180910390fd5b5f610fae33611cd4565b60ff1611610ff1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe89061481a565b60405180910390fd5b600760129054906101000a900461ffff1661ffff166001600760089054906101000a900461ffff166110239190614865565b61ffff161115611068576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105f906148e4565b60405180910390fd5b600160135f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160016101000a81548160ff021916908360ff1602179055506110de3360125f9054906101000a900461ffff1661ffff16613420565b3373ffffffffffffffffffffffffffffffffffffffff167f2c1e4cf372ff5cbf0acd582e8b37836cb25ceeedaf74e174d4ff14656f21b39d4260125f9054906101000a900461ffff16604051611135929190614902565b60405180910390a260125f81819054906101000a900461ffff168092919061115c90614929565b91906101000a81548161ffff021916908361ffff160217905550506007600881819054906101000a900461ffff168092919061119790614929565b91906101000a81548161ffff021916908361ffff16021790555050565b5f600f5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff16600f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff166112589190614952565b9050919050565b60606002805461126e906149b3565b80601f016020809104026020016040519081016040528092919081815260200182805461129a906149b3565b80156112e55780601f106112bc576101008083540402835291602001916112e5565b820191905f5260205f20905b8154815290600101906020018083116112c857829003601f168201915b5050505050905090565b600760029054906101000a900461ffff1681565b5f815f527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260205f2082018201805460601b60601c61134c5763ceea21b65f526004601cfd5b8060010154915050919050565b61136433838361343d565b5050565b5f60115f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff1660115f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff1661140c9190614952565b9050919050565b5f6005547f000000000000000000000000000000000000000000000000000000000000000061144291906149e3565b905090565b60085481565b6007600e9054906101000a900461ffff1681565b61146c8383836134ed565b5f1960601c83811693508281169250815f52337f7d8825530a5a2e7a00000000000000000000000000000000000000000000000017601c5260205f2082018201805480831686811481026114d957806114cc5763ceea21b65f526004601cfd5b63a11481005f526004601cfd5b856114eb5763ea553b345f526004601cfd5b865f52826001015480331488331417611516576030600c205461151557634b6e7f185f526004601cfd5b5b8015611523575f84600101555b5085871882188355601c600c206001815403815550855f52601c600c20600181540163ffffffff811661155d576301336cea5f526004601cfd5b80825550508486887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4505050506115988383836134f2565b505050565b6013602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f611604336117e1565b60ff1611611647576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161163e9061481a565b60405180910390fd5b8060ff16611654336117e1565b60ff161015611698576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168f90614a60565b60405180910390fd5b8060ff166116a4611413565b6116ae9190614a7e565b7f00000000000000000000000000000000000000000000000000000000000000001015611710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170790614afb565b60405180910390fd5b80600b5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160018282829054906101000a900460ff1661176b9190614b19565b92506101000a81548160ff021916908360ff160217905550611790338260ff166134f7565b3373ffffffffffffffffffffffffffffffffffffffff167f30603f56befad35715d530ed1090c153118f6822d031c1e03fc5bc0e3f308089426040516117d69190614178565b60405180910390a250565b5f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff16600b5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff166118859190614952565b9050919050565b61189461367b565b80600690816118a39190614cea565b5050565b5f6007600a9054906101000a900461ffff1661ffff16600760089054906101000a900461ffff1661ffff16600760069054906101000a900461ffff1661ffff16600760049054906101000a900461ffff1661ffff16600760029054906101000a900461ffff1661ffff16611919611413565b6119239190614a7e565b61192d9190614a7e565b6119379190614a7e565b6119419190614a7e565b61194b9190614a7e565b905090565b6015602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b60085442106119cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c390614e03565b60405180910390fd5b5f6119d633611368565b60ff1611611a19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a1090614e6b565b60405180910390fd5b600760109054906101000a900461ffff1661ffff166001600760069054906101000a900461ffff16611a4b9190614865565b61ffff161115611a90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8790614ed3565b60405180910390fd5b600160115f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160016101000a81548160ff021916908360ff160217905550611b063360105f9054906101000a900461ffff1661ffff16613420565b3373ffffffffffffffffffffffffffffffffffffffff167f263f38b7218c24f51b965c0b6593d85c8dccaefbb20333808a8543f59874b6db4260105f9054906101000a900461ffff16604051611b5d929190614902565b60405180910390a260105f81819054906101000a900461ffff1680929190611b8490614929565b91906101000a81548161ffff021916908361ffff160217905550506007600681819054906101000a900461ffff1680929190611bbf90614929565b91906101000a81548161ffff021916908361ffff16021790555050565b611be7838383611461565b611bf082613702565b15611c1057611c0f83838360405180602001604052805f81525061370c565b5b505050565b600760049054906101000a900461ffff1681565b5f60155f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff1660155f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff16611ccd9190614952565b9050919050565b5f60135f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff1660135f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff16611d789190614952565b9050919050565b600d602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b5f611dc182613799565b905080611dd55763ceea21b65f526004601cfd5b919050565b6007600a9054906101000a900461ffff1681565b60068054611dfb906149b3565b80601f0160208091040260200160405190810160405280929190818152602001828054611e27906149b3565b8015611e725780601f10611e4957610100808354040283529160200191611e72565b820191905f5260205f20905b815481529060010190602001808311611e5557829003601f168201915b505050505081565b5f81611e8d57638f4eb6045f526004601cfd5b7f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c52815f5263ffffffff601c600c2054169050919050565b611ecf61367b565b611ed85f6137d7565b565b6008544210611f1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1590614f3b565b60405180910390fd5b5f611f2833611c29565b60ff1611611f6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f629061481a565b60405180910390fd5b8060ff16611f7833611c29565b60ff161015611fbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb390614a60565b60405180910390fd5b6007600c9054906101000a900461ffff1661ffff168160ff166007600a9054906101000a900461ffff16611ff09190614865565b61ffff161115612035576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202c90614fa3565b60405180910390fd5b5f8160ff1667ffffffffffffffff8111156120535761205261423e565b5b6040519080825280602002602001820160405280156120815781602001602082028036833780820191505090505b5090508160155f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160018282829054906101000a900460ff166120df9190614b19565b92506101000a81548160ff021916908360ff1602179055505f5b8260ff168160ff1610156121e2576121243360145f9054906101000a900461ffff1661ffff16613420565b60145f9054906101000a900461ffff16828260ff168151811061214a57612149614fc1565b5b602002602001019061ffff16908161ffff168152505060145f81819054906101000a900461ffff168092919061217f90614929565b91906101000a81548161ffff021916908361ffff160217905550506007600a81819054906101000a900461ffff16809291906121ba90614929565b91906101000a81548161ffff021916908361ffff1602179055505080806001019150506120f9565b503373ffffffffffffffffffffffffffffffffffffffff167f9a7729d96d93ef9a9153e2274fdbdf5c747b943e4279957ad6f7cf8ced687b27428360405161222b9291906150a5565b60405180910390a25050565b61223f61367b565b5f5b828290508110156122d857600160115f85858581811061226457612263614fc1565b5b90506020020160208101906122799190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff1602179055508080600101915050612241565b505050565b600760149054906101000a900461ffff1681565b6122f961367b565b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc4790811502906040515f60405180830381858888f1935050505015801561235d573d5f803e3d5ffd5b50565b60085442106123a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161239b9061511d565b60405180910390fd5b5f6123ae336111b4565b60ff16116123f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123e89061481a565b60405180910390fd5b8060ff166123fe336111b4565b60ff161015612442576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161243990614a60565b60405180910390fd5b6007600e9054906101000a900461ffff1661ffff168160ff16600760049054906101000a900461ffff166124769190614865565b61ffff1611156124bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124b290615185565b60405180910390fd5b5f8160ff1667ffffffffffffffff8111156124d9576124d861423e565b5b6040519080825280602002602001820160405280156125075781602001602082028036833780820191505090505b50905081600f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160018282829054906101000a900460ff166125659190614b19565b92506101000a81548160ff021916908360ff1602179055505f5b8260ff168160ff161015612668576125aa33600e5f9054906101000a900461ffff1661ffff16613420565b600e5f9054906101000a900461ffff16828260ff16815181106125d0576125cf614fc1565b5b602002602001019061ffff16908161ffff1681525050600e5f81819054906101000a900461ffff168092919061260590614929565b91906101000a81548161ffff021916908361ffff160217905550506007600481819054906101000a900461ffff168092919061264090614929565b91906101000a81548161ffff021916908361ffff16021790555050808060010191505061257f565b503373ffffffffffffffffffffffffffffffffffffffff167f8623fb7c4a27402c7d1eed0c33dbc59d1c2c0b397dd45db820a50b3ce3a67c9542836040516126b19291906150a5565b60405180910390a25050565b5f600d5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff16600d5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff166127619190614952565b9050919050565b60075f9054906101000a900461ffff1681565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6007600c9054906101000a900461ffff1681565b600760089054906101000a900461ffff1681565b6060600380546127ff906149b3565b80601f016020809104026020016040519081016040528092919081815260200182805461282b906149b3565b80156128765780601f1061284d57610100808354040283529160200191612876565b820191905f5260205f20905b81548152906001019060200180831161285957829003601f168201915b5050505050905090565b61288861367b565b8181905084849050146128d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128c790615213565b60405180910390fd5b5f5b8484905081101561298f578282828181106128f0576128ef614fc1565b5b9050602002016020810190612905919061420b565b600f5f87878581811061291b5761291a614fc1565b5b90506020020160208101906129309190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff16021790555080806001019150506128d2565b5050505050565b801515905081601c52670a5a2e7a00000000600852335f52806030600c2055805f528160601b60601c337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160205fa35050565b600760069054906101000a900461ffff1681565b612a0561367b565b818190508484905014612a4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a4490615213565b60405180910390fd5b5f5b84849050811015612b2757828282818110612a6d57612a6c614fc1565b5b9050602002016020810190612a82919061420b565b600b5f878785818110612a9857612a97614fc1565b5b9050602002016020810190612aad9190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f8282829054906101000a900460ff16612b029190614b19565b92506101000a81548160ff021916908360ff1602179055508080600101915050612a4f565b5050505050565b612b3661367b565b818190508484905014612b7e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b7590615213565b60405180910390fd5b5f5b84849050811015612c3d57828282818110612b9e57612b9d614fc1565b5b9050602002016020810190612bb3919061420b565b600d5f878785818110612bc957612bc8614fc1565b5b9050602002016020810190612bde9190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff1602179055508080600101915050612b80565b5050505050565b612c4f858585611461565b612c5884613702565b15612cad57612cac85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505061370c565b5b5050505050565b612cbc61367b565b5f5b82829050811015612d5557600160135f858585818110612ce157612ce0614fc1565b5b9050602002016020810190612cf69190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff1602179055508080600101915050612cbe565b505050565b6008544210612d9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d959061527b565b60405180910390fd5b5f612da8336126bd565b60ff1611612deb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612de29061481a565b60405180910390fd5b8060ff16612df8336126bd565b60ff161015612e3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e3390614a60565b60405180910390fd5b6007600c9054906101000a900461ffff1661ffff168160ff16600760029054906101000a900461ffff16612e709190614865565b61ffff161115612eb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612eac906152e3565b60405180910390fd5b5f8160ff1667ffffffffffffffff811115612ed357612ed261423e565b5b604051908082528060200260200182016040528015612f015781602001602082028036833780820191505090505b50905081600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160018282829054906101000a900460ff16612f5f9190614b19565b92506101000a81548160ff021916908360ff1602179055505f5b8260ff168160ff16101561306257612fa433600c5f9054906101000a900461ffff1661ffff16613420565b600c5f9054906101000a900461ffff16828260ff1681518110612fca57612fc9614fc1565b5b602002602001019061ffff16908161ffff1681525050600c5f81819054906101000a900461ffff1680929190612fff90614929565b91906101000a81548161ffff021916908361ffff160217905550506007600281819054906101000a900461ffff168092919061303a90614929565b91906101000a81548161ffff021916908361ffff160217905550508080600101915050612f79565b503373ffffffffffffffffffffffffffffffffffffffff167f217c0dc2383a06fa566bfc4a8dbe3281dc6a3642e0e56927edfdf03d8efbdf6042836040516130ab9291906150a5565b60405180910390a25050565b60606130c28261389a565b613101576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130f89061534b565b60405180910390fd5b5f61310a6138d5565b90505f8151116131285760405180602001604052805f815250613153565b8061313284613965565b6040516020016131439291906153a3565b6040516020818303038152906040525b915050919050565b5f6131658261389a565b9050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60055481565b61319e61367b565b5f5b8484905081101561325d578282828181106131be576131bd614fc1565b5b90506020020160208101906131d3919061420b565b60155f8787858181106131e9576131e8614fc1565b5b90506020020160208101906131fe9190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff16021790555080806001019150506131a0565b5050505050565b5f60c061327083613a2f565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16901c9050919050565b6011602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b600b602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b5f81601c52670a5a2e7a00000000600852825f526030600c2054905092915050565b600760109054906101000a900461ffff1681565b61334561367b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036133b5575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016133ac9190614112565b60405180910390fd5b6133be816137d7565b50565b6133c961367b565b80600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600760129054906101000a900461ffff1681565b613439828260405180602001604052805f815250613a67565b5050565b5f1960601c82811692508381169350815f52837f7d8825530a5a2e7a00000000000000000000000000000000000000000000000017601c5260205f208201820180548216806134935763ceea21b65f526004601cfd5b8086148615176134b857805f526030600c20546134b757634b6e7f185f526004601cfd5b5b8482600101558385827f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f80a4505050505050565b505050565b505050565b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461355c576040517fd9d552c900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8103613595576040517f4600cfe900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060055410156135d1576040517f7775abdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051806020016040528042446040516020016135f09291906153e6565b604051602081830303815290604052805190602001205f1c81525090505f60055490505f5b83811015613663575f6136318385613a9190919063ffffffff16565b90505f61363e8285613aba565b905061364a8782613b57565b8361365490615411565b93508260010192505050613615565b5061366e8484613c2b565b8060058190555050505050565b613683613c89565b73ffffffffffffffffffffffffffffffffffffffff166136a161277b565b73ffffffffffffffffffffffffffffffffffffffff1614613700576136c4613c89565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016136f79190614112565b60405180910390fd5b565b5f813b9050919050565b60405163150b7a028082523360208301528560601b60601c604083015283606083015260808083015282518060a08401528015613753578060c08401826020870160045afa505b60208360a48301601c86015f8a5af1613778573d15613774573d5f803e3d5ffd5b5f83525b8160e01b8351146137905763d1a57ed65f526004601cfd5b50505050505050565b5f815f527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260205f20820182015460601b60601c9050919050565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f815f527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260205f20820182015460601b9050919050565b6060600680546138e4906149b3565b80601f0160208091040260200160405190810160405280929190818152602001828054613910906149b3565b801561395b5780601f106139325761010080835404028352916020019161395b565b820191905f5260205f20905b81548152906001019060200180831161393e57829003601f168201915b5050505050905090565b60605f600161397384613c90565b0190505f8167ffffffffffffffff8111156139915761399061423e565b5b6040519080825280601f01601f1916602001820160405280156139c35781602001600182028036833780820191505090505b5090505f82602001820190505b600115613a24578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581613a1957613a18615438565b5b0494505f85036139d0575b819350505050919050565b5f7f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c52815f52601c600c205460201c9050919050565b613a718383613b57565b613a7a83613702565b15613a8c57613a8b5f84848461370c565b5b505050565b5f5b600115613aaf5760208320905080835281825f03068110613a93575b818106905092915050565b5f8060045f8581526020019081526020015f205490505f600184613ade91906149e3565b90505f60045f8381526020019081526020015f205490505f8314613b025782613b04565b855b9350818614613b32575f8114613b1a5780613b1c565b815b60045f8881526020019081526020015f20819055505b5f8114613b4e5760045f8381526020019081526020015f205f90555b50505092915050565b613b625f83836134ed565b8160601b60601c915081613b7d5763ea553b345f526004601cfd5b805f527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260205f208101810180548060601b15613bc45763c991cbb15f526004601cfd5b8381178255835f52601c600c20600181540163ffffffff8116613bee576301336cea5f526004601cfd5b808255505082845f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45050613c275f83836134f2565b5050565b5f613c3583613264565b90505f8282613c449190615465565b90505f613c5085613a2f565b9050613c82858277ffffffffffffffffffffffffffffffffffffffffffffffff1660c08563ffffffff16901b17613de1565b5050505050565b5f33905090565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613cec577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381613ce257613ce1615438565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310613d29576d04ee2d6d415b85acef81000000008381613d1f57613d1e615438565b5b0492506020810190505b662386f26fc100008310613d5857662386f26fc100008381613d4e57613d4d615438565b5b0492506010810190505b6305f5e1008310613d81576305f5e1008381613d7757613d76615438565b5b0492506008810190505b6127108310613da6576127108381613d9c57613d9b615438565b5b0492506004810190505b60648310613dc95760648381613dbf57613dbe615438565b5b0492506002810190505b600a8310613dd8576001810190505b80915050919050565b7f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c52815f52601c600c2080548060201c831860201b8118825550505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f613e5c82613e33565b9050919050565b613e6c81613e52565b8114613e76575f80fd5b50565b5f81359050613e8781613e63565b92915050565b5f60208284031215613ea257613ea1613e2b565b5b5f613eaf84828501613e79565b91505092915050565b5f60ff82169050919050565b613ecd81613eb8565b82525050565b5f604082019050613ee65f830185613ec4565b613ef36020830184613ec4565b9392505050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613f2e81613efa565b8114613f38575f80fd5b50565b5f81359050613f4981613f25565b92915050565b5f60208284031215613f6457613f63613e2b565b5b5f613f7184828501613f3b565b91505092915050565b5f8115159050919050565b613f8e81613f7a565b82525050565b5f602082019050613fa75f830184613f85565b92915050565b5f602082019050613fc05f830184613ec4565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015613ffd578082015181840152602081019050613fe2565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61402282613fc6565b61402c8185613fd0565b935061403c818560208601613fe0565b61404581614008565b840191505092915050565b5f6020820190508181035f8301526140688184614018565b905092915050565b5f61ffff82169050919050565b61408681614070565b82525050565b5f60208201905061409f5f83018461407d565b92915050565b5f819050919050565b6140b7816140a5565b81146140c1575f80fd5b50565b5f813590506140d2816140ae565b92915050565b5f602082840312156140ed576140ec613e2b565b5b5f6140fa848285016140c4565b91505092915050565b61410c81613e52565b82525050565b5f6020820190506141255f830184614103565b92915050565b5f806040838503121561414157614140613e2b565b5b5f61414e85828601613e79565b925050602061415f858286016140c4565b9150509250929050565b614172816140a5565b82525050565b5f60208201905061418b5f830184614169565b92915050565b5f805f606084860312156141a8576141a7613e2b565b5b5f6141b586828701613e79565b93505060206141c686828701613e79565b92505060406141d7868287016140c4565b9150509250925092565b6141ea81613eb8565b81146141f4575f80fd5b50565b5f81359050614205816141e1565b92915050565b5f602082840312156142205761421f613e2b565b5b5f61422d848285016141f7565b91505092915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61427482614008565b810181811067ffffffffffffffff821117156142935761429261423e565b5b80604052505050565b5f6142a5613e22565b90506142b1828261426b565b919050565b5f67ffffffffffffffff8211156142d0576142cf61423e565b5b6142d982614008565b9050602081019050919050565b828183375f83830152505050565b5f614306614301846142b6565b61429c565b9050828152602081018484840111156143225761432161423a565b5b61432d8482856142e6565b509392505050565b5f82601f83011261434957614348614236565b5b81356143598482602086016142f4565b91505092915050565b5f6020828403121561437757614376613e2b565b5b5f82013567ffffffffffffffff81111561439457614393613e2f565b5b6143a084828501614335565b91505092915050565b5f80fd5b5f80fd5b5f8083601f8401126143c6576143c5614236565b5b8235905067ffffffffffffffff8111156143e3576143e26143a9565b5b6020830191508360208202830111156143ff576143fe6143ad565b5b9250929050565b5f806020838503121561441c5761441b613e2b565b5b5f83013567ffffffffffffffff81111561443957614438613e2f565b5b614445858286016143b1565b92509250509250929050565b5f61445b82613e33565b9050919050565b61446b81614451565b82525050565b5f6020820190506144845f830184614462565b92915050565b5f8083601f84011261449f5761449e614236565b5b8235905067ffffffffffffffff8111156144bc576144bb6143a9565b5b6020830191508360208202830111156144d8576144d76143ad565b5b9250929050565b5f805f80604085870312156144f7576144f6613e2b565b5b5f85013567ffffffffffffffff81111561451457614513613e2f565b5b614520878288016143b1565b9450945050602085013567ffffffffffffffff81111561454357614542613e2f565b5b61454f8782880161448a565b925092505092959194509250565b61456681613f7a565b8114614570575f80fd5b50565b5f813590506145818161455d565b92915050565b5f806040838503121561459d5761459c613e2b565b5b5f6145aa85828601613e79565b92505060206145bb85828601614573565b9150509250929050565b5f8083601f8401126145da576145d9614236565b5b8235905067ffffffffffffffff8111156145f7576145f66143a9565b5b602083019150836001820283011115614613576146126143ad565b5b9250929050565b5f805f805f6080868803121561463357614632613e2b565b5b5f61464088828901613e79565b955050602061465188828901613e79565b9450506040614662888289016140c4565b935050606086013567ffffffffffffffff81111561468357614682613e2f565b5b61468f888289016145c5565b92509250509295509295909350565b5f63ffffffff82169050919050565b6146b68161469e565b82525050565b5f6020820190506146cf5f8301846146ad565b92915050565b5f80604083850312156146eb576146ea613e2b565b5b5f6146f885828601613e79565b925050602061470985828601613e79565b9150509250929050565b61471c81614451565b8114614726575f80fd5b50565b5f8135905061473781614713565b92915050565b5f6020828403121561475257614751613e2b565b5b5f61475f84828501614729565b91505092915050565b7f4a75646765206d696e7420636c6f7365000000000000000000000000000000005f82015250565b5f61479c601083613fd0565b91506147a782614768565b602082019050919050565b5f6020820190508181035f8301526147c981614790565b9050919050565b7f4e6f7420656c696769626c6500000000000000000000000000000000000000005f82015250565b5f614804600c83613fd0565b915061480f826147d0565b602082019050919050565b5f6020820190508181035f830152614831816147f8565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61486f82614070565b915061487a83614070565b9250828201905061ffff81111561489457614893614838565b5b92915050565b7f4d617820737570706c79206a75646765206578636565640000000000000000005f82015250565b5f6148ce601783613fd0565b91506148d98261489a565b602082019050919050565b5f6020820190508181035f8301526148fb816148c2565b9050919050565b5f6040820190506149155f830185614169565b614922602083018461407d565b9392505050565b5f61493382614070565b915061ffff820361494757614946614838565b5b600182019050919050565b5f61495c82613eb8565b915061496783613eb8565b9250828203905060ff8111156149805761497f614838565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806149ca57607f821691505b6020821081036149dd576149dc614986565b5b50919050565b5f6149ed826140a5565b91506149f8836140a5565b9250828203905081811115614a1057614a0f614838565b5b92915050565b7f4e6f7420656e6f75676820636c61696d61626c6520746f6b656e7300000000005f82015250565b5f614a4a601b83613fd0565b9150614a5582614a16565b602082019050919050565b5f6020820190508181035f830152614a7781614a3e565b9050919050565b5f614a88826140a5565b9150614a93836140a5565b9250828201905080821115614aab57614aaa614838565b5b92915050565b7f537570706c79206c696d697420657863656564000000000000000000000000005f82015250565b5f614ae5601383613fd0565b9150614af082614ab1565b602082019050919050565b5f6020820190508181035f830152614b1281614ad9565b9050919050565b5f614b2382613eb8565b9150614b2e83613eb8565b9250828201905060ff811115614b4757614b46614838565b5b92915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302614ba97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614b6e565b614bb38683614b6e565b95508019841693508086168417925050509392505050565b5f819050919050565b5f614bee614be9614be4846140a5565b614bcb565b6140a5565b9050919050565b5f819050919050565b614c0783614bd4565b614c1b614c1382614bf5565b848454614b7a565b825550505050565b5f90565b614c2f614c23565b614c3a818484614bfe565b505050565b5b81811015614c5d57614c525f82614c27565b600181019050614c40565b5050565b601f821115614ca257614c7381614b4d565b614c7c84614b5f565b81016020851015614c8b578190505b614c9f614c9785614b5f565b830182614c3f565b50505b505050565b5f82821c905092915050565b5f614cc25f1984600802614ca7565b1980831691505092915050565b5f614cda8383614cb3565b9150826002028217905092915050565b614cf382613fc6565b67ffffffffffffffff811115614d0c57614d0b61423e565b5b614d1682546149b3565b614d21828285614c61565b5f60209050601f831160018114614d52575f8415614d40578287015190505b614d4a8582614ccf565b865550614db1565b601f198416614d6086614b4d565b5f5b82811015614d8757848901518255600182019150602085019450602081019050614d62565b86831015614da45784890151614da0601f891682614cb3565b8355505b6001600288020188555050505b505050505050565b7f477561726469616e206d696e7420636c6f7365000000000000000000000000005f82015250565b5f614ded601383613fd0565b9150614df882614db9565b602082019050919050565b5f6020820190508181035f830152614e1a81614de1565b9050919050565b7f4e6f2067697665776179000000000000000000000000000000000000000000005f82015250565b5f614e55600a83613fd0565b9150614e6082614e21565b602082019050919050565b5f6020820190508181035f830152614e8281614e49565b9050919050565b7f4d617820737570706c7920677561726469616e206578636565640000000000005f82015250565b5f614ebd601a83613fd0565b9150614ec882614e89565b602082019050919050565b5f6020820190508181035f830152614eea81614eb1565b9050919050565b7f5768616c65206d696e7420636c6f7365000000000000000000000000000000005f82015250565b5f614f25601083613fd0565b9150614f3082614ef1565b602082019050919050565b5f6020820190508181035f830152614f5281614f19565b9050919050565b7f4d617820737570706c79207768616c65206578636565640000000000000000005f82015250565b5f614f8d601783613fd0565b9150614f9882614f59565b602082019050919050565b5f6020820190508181035f830152614fba81614f81565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61502081614070565b82525050565b5f6150318383615017565b60208301905092915050565b5f602082019050919050565b5f61505382614fee565b61505d8185614ff8565b935061506883615008565b805f5b8381101561509857815161507f8882615026565b975061508a8361503d565b92505060018101905061506b565b5085935050505092915050565b5f6040820190506150b85f830185614169565b81810360208301526150ca8184615049565b90509392505050565b7f486f6e6f72617279206d696e7420636c6f7365000000000000000000000000005f82015250565b5f615107601383613fd0565b9150615112826150d3565b602082019050919050565b5f6020820190508181035f830152615134816150fb565b9050919050565b7f4d617820737570706c7920686f6e6f72617279206578636565640000000000005f82015250565b5f61516f601a83613fd0565b915061517a8261513b565b602082019050919050565b5f6020820190508181035f83015261519c81615163565b9050919050565b7f4e62206164647265737320616e64206e62207175616e746974696573206d75735f8201527f7420626520657175616c00000000000000000000000000000000000000000000602082015250565b5f6151fd602a83613fd0565b9150615208826151a3565b604082019050919050565b5f6020820190508181035f83015261522a816151f1565b9050919050565b7f436f756e63696c206d696e7420636c6f736500000000000000000000000000005f82015250565b5f615265601283613fd0565b915061527082615231565b602082019050919050565b5f6020820190508181035f83015261529281615259565b9050919050565b7f4d617820737570706c7920636f756e63696c20657863656564000000000000005f82015250565b5f6152cd601983613fd0565b91506152d882615299565b602082019050919050565b5f6020820190508181035f8301526152fa816152c1565b9050919050565b7f756e6b6e6f7720746f6b656e00000000000000000000000000000000000000005f82015250565b5f615335600c83613fd0565b915061534082615301565b602082019050919050565b5f6020820190508181035f83015261536281615329565b9050919050565b5f81905092915050565b5f61537d82613fc6565b6153878185615369565b9350615397818560208601613fe0565b80840191505092915050565b5f6153ae8285615373565b91506153ba8284615373565b91508190509392505050565b5f819050919050565b6153e06153db826140a5565b6153c6565b82525050565b5f6153f182856153cf565b60208201915061540182846153cf565b6020820191508190509392505050565b5f61541b826140a5565b91505f820361542d5761542c614838565b5b600182039050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61546f8261469e565b915061547a8361469e565b9250828201905063ffffffff81111561549657615495614838565b5b9291505056fea2646970667358221220e90b78fd1e48f9522ce04e38979dd9b18bffed2f6a6e775afd6152c433fa750964736f6c63430008170033
Deployed Bytecode
0x6080604052600436106103c2575f3560e01c80637a12ef82116101f1578063b88d4fde1161010c578063dc33e6811161009f578063ea3d74181161006e578063ea3d741814610e60578063f2fde38b14610e8a578063fb5b82d014610eb2578063fc89067914610eda576103c2565b8063dc33e68114610d6e578063dd330e4d14610daa578063df1dc2c514610de7578063e985e9c514610e24576103c2565b8063cc0c5236116100db578063cc0c523614610cb6578063d5abeb0114610cf2578063da0239a614610d1c578063dab00abb14610d46576103c2565b8063b88d4fde14610c0e578063b904e37a14610c2a578063bc68ed6c14610c52578063c87b56dd14610c7a576103c2565b8063916ec2c611610184578063a22cb46511610153578063a22cb46514610b6c578063a2cd568914610b94578063ac497a4814610bbe578063b55698d514610be6576103c2565b8063916ec2c614610ac657806391ec4b4c14610af057806395d89b4114610b1a5780639a3e276814610b44576103c2565b8063889960ea116101c0578063889960ea14610a0c5780638b4303a614610a485780638da5cb5b14610a72578063913e77ad14610a9c576103c2565b80637a12ef82146109885780637ca470b1146109b0578063853828b6146109da57806385ad1cf5146109e4576103c2565b80632ff1474d116102e157806352186417116102745780636c0360eb116102435780636c0360eb146108e457806370a082311461090e578063715018a61461094a5780637400c92214610960576103c2565b806352186417146108055780635d42a059146108415780636352211e1461087e5780636802e529146108ba576103c2565b8063376e1b1f116102b0578063376e1b1f1461076d57806342842e0e1461078357806346fbed6f1461079f5780634e27acff146107c9576103c2565b80632ff1474d146106a257806331b5b907146106de57806333a3600714610706578063343bc89314610730576103c2565b8063106e707b1161035957806323b872dd1161032857806323b872dd146105f757806326d6327914610613578063282e7811146106505780632db5b8e71461067a576103c2565b8063106e707b1461053d57806318160ddd146105795780631bf3dd4f146105a35780631d490ee3146105cd576103c2565b806306fdde031161039557806306fdde031461049157806307edf9ef146104bb578063081812fc146104e5578063095ea7b314610521576103c2565b80630129b0b9146103c657806301ffc9a714610403578063022c01991461043f5780630322ba9814610455575b5f80fd5b3480156103d1575f80fd5b506103ec60048036038101906103e79190613e8d565b610f04565b6040516103fa929190613ed3565b60405180910390f35b34801561040e575f80fd5b5061042960048036038101906104249190613f4f565b610f3c565b6040516104369190613f94565b60405180910390f35b34801561044a575f80fd5b50610453610f60565b005b348015610460575f80fd5b5061047b60048036038101906104769190613e8d565b6111b4565b6040516104889190613fad565b60405180910390f35b34801561049c575f80fd5b506104a561125f565b6040516104b29190614050565b60405180910390f35b3480156104c6575f80fd5b506104cf6112ef565b6040516104dc919061408c565b60405180910390f35b3480156104f0575f80fd5b5061050b600480360381019061050691906140d8565b611303565b6040516105189190614112565b60405180910390f35b61053b6004803603810190610536919061412b565b611359565b005b348015610548575f80fd5b50610563600480360381019061055e9190613e8d565b611368565b6040516105709190613fad565b60405180910390f35b348015610584575f80fd5b5061058d611413565b60405161059a9190614178565b60405180910390f35b3480156105ae575f80fd5b506105b7611447565b6040516105c49190614178565b60405180910390f35b3480156105d8575f80fd5b506105e161144d565b6040516105ee919061408c565b60405180910390f35b610611600480360381019061060c9190614191565b611461565b005b34801561061e575f80fd5b5061063960048036038101906106349190613e8d565b61159d565b604051610647929190613ed3565b60405180910390f35b34801561065b575f80fd5b506106646115d5565b6040516106719190614112565b60405180910390f35b348015610685575f80fd5b506106a0600480360381019061069b919061420b565b6115fa565b005b3480156106ad575f80fd5b506106c860048036038101906106c39190613e8d565b6117e1565b6040516106d59190613fad565b60405180910390f35b3480156106e9575f80fd5b5061070460048036038101906106ff9190614362565b61188c565b005b348015610711575f80fd5b5061071a6118a7565b6040516107279190614178565b60405180910390f35b34801561073b575f80fd5b5061075660048036038101906107519190613e8d565b611950565b604051610764929190613ed3565b60405180910390f35b348015610778575f80fd5b50610781611988565b005b61079d60048036038101906107989190614191565b611bdc565b005b3480156107aa575f80fd5b506107b3611c15565b6040516107c0919061408c565b60405180910390f35b3480156107d4575f80fd5b506107ef60048036038101906107ea9190613e8d565b611c29565b6040516107fc9190613fad565b60405180910390f35b348015610810575f80fd5b5061082b60048036038101906108269190613e8d565b611cd4565b6040516108389190613fad565b60405180910390f35b34801561084c575f80fd5b5061086760048036038101906108629190613e8d565b611d7f565b604051610875929190613ed3565b60405180910390f35b348015610889575f80fd5b506108a4600480360381019061089f91906140d8565b611db7565b6040516108b19190614112565b60405180910390f35b3480156108c5575f80fd5b506108ce611dda565b6040516108db919061408c565b60405180910390f35b3480156108ef575f80fd5b506108f8611dee565b6040516109059190614050565b60405180910390f35b348015610919575f80fd5b50610934600480360381019061092f9190613e8d565b611e7a565b6040516109419190614178565b60405180910390f35b348015610955575f80fd5b5061095e611ec7565b005b34801561096b575f80fd5b506109866004803603810190610981919061420b565b611eda565b005b348015610993575f80fd5b506109ae60048036038101906109a99190614406565b612237565b005b3480156109bb575f80fd5b506109c46122dd565b6040516109d1919061408c565b60405180910390f35b6109e26122f1565b005b3480156109ef575f80fd5b50610a0a6004803603810190610a05919061420b565b612360565b005b348015610a17575f80fd5b50610a326004803603810190610a2d9190613e8d565b6126bd565b604051610a3f9190613fad565b60405180910390f35b348015610a53575f80fd5b50610a5c612768565b604051610a69919061408c565b60405180910390f35b348015610a7d575f80fd5b50610a8661277b565b604051610a939190614112565b60405180910390f35b348015610aa7575f80fd5b50610ab06127a3565b604051610abd9190614471565b60405180910390f35b348015610ad1575f80fd5b50610ada6127c8565b604051610ae7919061408c565b60405180910390f35b348015610afb575f80fd5b50610b046127dc565b604051610b11919061408c565b60405180910390f35b348015610b25575f80fd5b50610b2e6127f0565b604051610b3b9190614050565b60405180910390f35b348015610b4f575f80fd5b50610b6a6004803603810190610b6591906144df565b612880565b005b348015610b77575f80fd5b50610b926004803603810190610b8d9190614587565b612996565b005b348015610b9f575f80fd5b50610ba86129e9565b604051610bb5919061408c565b60405180910390f35b348015610bc9575f80fd5b50610be46004803603810190610bdf91906144df565b6129fd565b005b348015610bf1575f80fd5b50610c0c6004803603810190610c0791906144df565b612b2e565b005b610c286004803603810190610c23919061461a565b612c44565b005b348015610c35575f80fd5b50610c506004803603810190610c4b9190614406565b612cb4565b005b348015610c5d575f80fd5b50610c786004803603810190610c73919061420b565b612d5a565b005b348015610c85575f80fd5b50610ca06004803603810190610c9b91906140d8565b6130b7565b604051610cad9190614050565b60405180910390f35b348015610cc1575f80fd5b50610cdc6004803603810190610cd791906140d8565b61315b565b604051610ce99190613f94565b60405180910390f35b348015610cfd575f80fd5b50610d0661316c565b604051610d139190614178565b60405180910390f35b348015610d27575f80fd5b50610d30613190565b604051610d3d9190614178565b60405180910390f35b348015610d51575f80fd5b50610d6c6004803603810190610d6791906144df565b613196565b005b348015610d79575f80fd5b50610d946004803603810190610d8f9190613e8d565b613264565b604051610da191906146bc565b60405180910390f35b348015610db5575f80fd5b50610dd06004803603810190610dcb9190613e8d565b613297565b604051610dde929190613ed3565b60405180910390f35b348015610df2575f80fd5b50610e0d6004803603810190610e089190613e8d565b6132cf565b604051610e1b929190613ed3565b60405180910390f35b348015610e2f575f80fd5b50610e4a6004803603810190610e4591906146d5565b613307565b604051610e579190613f94565b60405180910390f35b348015610e6b575f80fd5b50610e74613329565b604051610e81919061408c565b60405180910390f35b348015610e95575f80fd5b50610eb06004803603810190610eab9190613e8d565b61333d565b005b348015610ebd575f80fd5b50610ed86004803603810190610ed3919061473d565b6133c1565b005b348015610ee5575f80fd5b50610eee61340c565b604051610efb919061408c565b60405180910390f35b600f602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b5f8160e01c635b5e139f81146380ac58cd82146301ffc9a783141717915050919050565b6008544210610fa4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9b906147b2565b60405180910390fd5b5f610fae33611cd4565b60ff1611610ff1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe89061481a565b60405180910390fd5b600760129054906101000a900461ffff1661ffff166001600760089054906101000a900461ffff166110239190614865565b61ffff161115611068576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105f906148e4565b60405180910390fd5b600160135f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160016101000a81548160ff021916908360ff1602179055506110de3360125f9054906101000a900461ffff1661ffff16613420565b3373ffffffffffffffffffffffffffffffffffffffff167f2c1e4cf372ff5cbf0acd582e8b37836cb25ceeedaf74e174d4ff14656f21b39d4260125f9054906101000a900461ffff16604051611135929190614902565b60405180910390a260125f81819054906101000a900461ffff168092919061115c90614929565b91906101000a81548161ffff021916908361ffff160217905550506007600881819054906101000a900461ffff168092919061119790614929565b91906101000a81548161ffff021916908361ffff16021790555050565b5f600f5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff16600f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff166112589190614952565b9050919050565b60606002805461126e906149b3565b80601f016020809104026020016040519081016040528092919081815260200182805461129a906149b3565b80156112e55780601f106112bc576101008083540402835291602001916112e5565b820191905f5260205f20905b8154815290600101906020018083116112c857829003601f168201915b5050505050905090565b600760029054906101000a900461ffff1681565b5f815f527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260205f2082018201805460601b60601c61134c5763ceea21b65f526004601cfd5b8060010154915050919050565b61136433838361343d565b5050565b5f60115f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff1660115f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff1661140c9190614952565b9050919050565b5f6005547f000000000000000000000000000000000000000000000000000000000000033461144291906149e3565b905090565b60085481565b6007600e9054906101000a900461ffff1681565b61146c8383836134ed565b5f1960601c83811693508281169250815f52337f7d8825530a5a2e7a00000000000000000000000000000000000000000000000017601c5260205f2082018201805480831686811481026114d957806114cc5763ceea21b65f526004601cfd5b63a11481005f526004601cfd5b856114eb5763ea553b345f526004601cfd5b865f52826001015480331488331417611516576030600c205461151557634b6e7f185f526004601cfd5b5b8015611523575f84600101555b5085871882188355601c600c206001815403815550855f52601c600c20600181540163ffffffff811661155d576301336cea5f526004601cfd5b80825550508486887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4505050506115988383836134f2565b505050565b6013602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f611604336117e1565b60ff1611611647576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161163e9061481a565b60405180910390fd5b8060ff16611654336117e1565b60ff161015611698576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168f90614a60565b60405180910390fd5b8060ff166116a4611413565b6116ae9190614a7e565b7f00000000000000000000000000000000000000000000000000000000000003341015611710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170790614afb565b60405180910390fd5b80600b5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160018282829054906101000a900460ff1661176b9190614b19565b92506101000a81548160ff021916908360ff160217905550611790338260ff166134f7565b3373ffffffffffffffffffffffffffffffffffffffff167f30603f56befad35715d530ed1090c153118f6822d031c1e03fc5bc0e3f308089426040516117d69190614178565b60405180910390a250565b5f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff16600b5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff166118859190614952565b9050919050565b61189461367b565b80600690816118a39190614cea565b5050565b5f6007600a9054906101000a900461ffff1661ffff16600760089054906101000a900461ffff1661ffff16600760069054906101000a900461ffff1661ffff16600760049054906101000a900461ffff1661ffff16600760029054906101000a900461ffff1661ffff16611919611413565b6119239190614a7e565b61192d9190614a7e565b6119379190614a7e565b6119419190614a7e565b61194b9190614a7e565b905090565b6015602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b60085442106119cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c390614e03565b60405180910390fd5b5f6119d633611368565b60ff1611611a19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a1090614e6b565b60405180910390fd5b600760109054906101000a900461ffff1661ffff166001600760069054906101000a900461ffff16611a4b9190614865565b61ffff161115611a90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8790614ed3565b60405180910390fd5b600160115f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160016101000a81548160ff021916908360ff160217905550611b063360105f9054906101000a900461ffff1661ffff16613420565b3373ffffffffffffffffffffffffffffffffffffffff167f263f38b7218c24f51b965c0b6593d85c8dccaefbb20333808a8543f59874b6db4260105f9054906101000a900461ffff16604051611b5d929190614902565b60405180910390a260105f81819054906101000a900461ffff1680929190611b8490614929565b91906101000a81548161ffff021916908361ffff160217905550506007600681819054906101000a900461ffff1680929190611bbf90614929565b91906101000a81548161ffff021916908361ffff16021790555050565b611be7838383611461565b611bf082613702565b15611c1057611c0f83838360405180602001604052805f81525061370c565b5b505050565b600760049054906101000a900461ffff1681565b5f60155f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff1660155f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff16611ccd9190614952565b9050919050565b5f60135f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff1660135f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff16611d789190614952565b9050919050565b600d602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b5f611dc182613799565b905080611dd55763ceea21b65f526004601cfd5b919050565b6007600a9054906101000a900461ffff1681565b60068054611dfb906149b3565b80601f0160208091040260200160405190810160405280929190818152602001828054611e27906149b3565b8015611e725780601f10611e4957610100808354040283529160200191611e72565b820191905f5260205f20905b815481529060010190602001808311611e5557829003601f168201915b505050505081565b5f81611e8d57638f4eb6045f526004601cfd5b7f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c52815f5263ffffffff601c600c2054169050919050565b611ecf61367b565b611ed85f6137d7565b565b6008544210611f1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1590614f3b565b60405180910390fd5b5f611f2833611c29565b60ff1611611f6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f629061481a565b60405180910390fd5b8060ff16611f7833611c29565b60ff161015611fbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb390614a60565b60405180910390fd5b6007600c9054906101000a900461ffff1661ffff168160ff166007600a9054906101000a900461ffff16611ff09190614865565b61ffff161115612035576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202c90614fa3565b60405180910390fd5b5f8160ff1667ffffffffffffffff8111156120535761205261423e565b5b6040519080825280602002602001820160405280156120815781602001602082028036833780820191505090505b5090508160155f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160018282829054906101000a900460ff166120df9190614b19565b92506101000a81548160ff021916908360ff1602179055505f5b8260ff168160ff1610156121e2576121243360145f9054906101000a900461ffff1661ffff16613420565b60145f9054906101000a900461ffff16828260ff168151811061214a57612149614fc1565b5b602002602001019061ffff16908161ffff168152505060145f81819054906101000a900461ffff168092919061217f90614929565b91906101000a81548161ffff021916908361ffff160217905550506007600a81819054906101000a900461ffff16809291906121ba90614929565b91906101000a81548161ffff021916908361ffff1602179055505080806001019150506120f9565b503373ffffffffffffffffffffffffffffffffffffffff167f9a7729d96d93ef9a9153e2274fdbdf5c747b943e4279957ad6f7cf8ced687b27428360405161222b9291906150a5565b60405180910390a25050565b61223f61367b565b5f5b828290508110156122d857600160115f85858581811061226457612263614fc1565b5b90506020020160208101906122799190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff1602179055508080600101915050612241565b505050565b600760149054906101000a900461ffff1681565b6122f961367b565b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc4790811502906040515f60405180830381858888f1935050505015801561235d573d5f803e3d5ffd5b50565b60085442106123a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161239b9061511d565b60405180910390fd5b5f6123ae336111b4565b60ff16116123f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123e89061481a565b60405180910390fd5b8060ff166123fe336111b4565b60ff161015612442576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161243990614a60565b60405180910390fd5b6007600e9054906101000a900461ffff1661ffff168160ff16600760049054906101000a900461ffff166124769190614865565b61ffff1611156124bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124b290615185565b60405180910390fd5b5f8160ff1667ffffffffffffffff8111156124d9576124d861423e565b5b6040519080825280602002602001820160405280156125075781602001602082028036833780820191505090505b50905081600f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160018282829054906101000a900460ff166125659190614b19565b92506101000a81548160ff021916908360ff1602179055505f5b8260ff168160ff161015612668576125aa33600e5f9054906101000a900461ffff1661ffff16613420565b600e5f9054906101000a900461ffff16828260ff16815181106125d0576125cf614fc1565b5b602002602001019061ffff16908161ffff1681525050600e5f81819054906101000a900461ffff168092919061260590614929565b91906101000a81548161ffff021916908361ffff160217905550506007600481819054906101000a900461ffff168092919061264090614929565b91906101000a81548161ffff021916908361ffff16021790555050808060010191505061257f565b503373ffffffffffffffffffffffffffffffffffffffff167f8623fb7c4a27402c7d1eed0c33dbc59d1c2c0b397dd45db820a50b3ce3a67c9542836040516126b19291906150a5565b60405180910390a25050565b5f600d5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160019054906101000a900460ff16600d5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f9054906101000a900460ff166127619190614952565b9050919050565b60075f9054906101000a900461ffff1681565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6007600c9054906101000a900461ffff1681565b600760089054906101000a900461ffff1681565b6060600380546127ff906149b3565b80601f016020809104026020016040519081016040528092919081815260200182805461282b906149b3565b80156128765780601f1061284d57610100808354040283529160200191612876565b820191905f5260205f20905b81548152906001019060200180831161285957829003601f168201915b5050505050905090565b61288861367b565b8181905084849050146128d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128c790615213565b60405180910390fd5b5f5b8484905081101561298f578282828181106128f0576128ef614fc1565b5b9050602002016020810190612905919061420b565b600f5f87878581811061291b5761291a614fc1565b5b90506020020160208101906129309190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff16021790555080806001019150506128d2565b5050505050565b801515905081601c52670a5a2e7a00000000600852335f52806030600c2055805f528160601b60601c337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160205fa35050565b600760069054906101000a900461ffff1681565b612a0561367b565b818190508484905014612a4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a4490615213565b60405180910390fd5b5f5b84849050811015612b2757828282818110612a6d57612a6c614fc1565b5b9050602002016020810190612a82919061420b565b600b5f878785818110612a9857612a97614fc1565b5b9050602002016020810190612aad9190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f8282829054906101000a900460ff16612b029190614b19565b92506101000a81548160ff021916908360ff1602179055508080600101915050612a4f565b5050505050565b612b3661367b565b818190508484905014612b7e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b7590615213565b60405180910390fd5b5f5b84849050811015612c3d57828282818110612b9e57612b9d614fc1565b5b9050602002016020810190612bb3919061420b565b600d5f878785818110612bc957612bc8614fc1565b5b9050602002016020810190612bde9190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff1602179055508080600101915050612b80565b5050505050565b612c4f858585611461565b612c5884613702565b15612cad57612cac85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505061370c565b5b5050505050565b612cbc61367b565b5f5b82829050811015612d5557600160135f858585818110612ce157612ce0614fc1565b5b9050602002016020810190612cf69190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff1602179055508080600101915050612cbe565b505050565b6008544210612d9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d959061527b565b60405180910390fd5b5f612da8336126bd565b60ff1611612deb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612de29061481a565b60405180910390fd5b8060ff16612df8336126bd565b60ff161015612e3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e3390614a60565b60405180910390fd5b6007600c9054906101000a900461ffff1661ffff168160ff16600760029054906101000a900461ffff16612e709190614865565b61ffff161115612eb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612eac906152e3565b60405180910390fd5b5f8160ff1667ffffffffffffffff811115612ed357612ed261423e565b5b604051908082528060200260200182016040528015612f015781602001602082028036833780820191505090505b50905081600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160018282829054906101000a900460ff16612f5f9190614b19565b92506101000a81548160ff021916908360ff1602179055505f5b8260ff168160ff16101561306257612fa433600c5f9054906101000a900461ffff1661ffff16613420565b600c5f9054906101000a900461ffff16828260ff1681518110612fca57612fc9614fc1565b5b602002602001019061ffff16908161ffff1681525050600c5f81819054906101000a900461ffff1680929190612fff90614929565b91906101000a81548161ffff021916908361ffff160217905550506007600281819054906101000a900461ffff168092919061303a90614929565b91906101000a81548161ffff021916908361ffff160217905550508080600101915050612f79565b503373ffffffffffffffffffffffffffffffffffffffff167f217c0dc2383a06fa566bfc4a8dbe3281dc6a3642e0e56927edfdf03d8efbdf6042836040516130ab9291906150a5565b60405180910390a25050565b60606130c28261389a565b613101576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130f89061534b565b60405180910390fd5b5f61310a6138d5565b90505f8151116131285760405180602001604052805f815250613153565b8061313284613965565b6040516020016131439291906153a3565b6040516020818303038152906040525b915050919050565b5f6131658261389a565b9050919050565b7f000000000000000000000000000000000000000000000000000000000000033481565b60055481565b61319e61367b565b5f5b8484905081101561325d578282828181106131be576131bd614fc1565b5b90506020020160208101906131d3919061420b565b60155f8787858181106131e9576131e8614fc1565b5b90506020020160208101906131fe9190613e8d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015f6101000a81548160ff021916908360ff16021790555080806001019150506131a0565b5050505050565b5f60c061327083613a2f565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16901c9050919050565b6011602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b600b602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff16905082565b5f81601c52670a5a2e7a00000000600852825f526030600c2054905092915050565b600760109054906101000a900461ffff1681565b61334561367b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036133b5575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016133ac9190614112565b60405180910390fd5b6133be816137d7565b50565b6133c961367b565b80600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600760129054906101000a900461ffff1681565b613439828260405180602001604052805f815250613a67565b5050565b5f1960601c82811692508381169350815f52837f7d8825530a5a2e7a00000000000000000000000000000000000000000000000017601c5260205f208201820180548216806134935763ceea21b65f526004601cfd5b8086148615176134b857805f526030600c20546134b757634b6e7f185f526004601cfd5b5b8482600101558385827f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f80a4505050505050565b505050565b505050565b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461355c576040517fd9d552c900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8103613595576040517f4600cfe900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060055410156135d1576040517f7775abdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051806020016040528042446040516020016135f09291906153e6565b604051602081830303815290604052805190602001205f1c81525090505f60055490505f5b83811015613663575f6136318385613a9190919063ffffffff16565b90505f61363e8285613aba565b905061364a8782613b57565b8361365490615411565b93508260010192505050613615565b5061366e8484613c2b565b8060058190555050505050565b613683613c89565b73ffffffffffffffffffffffffffffffffffffffff166136a161277b565b73ffffffffffffffffffffffffffffffffffffffff1614613700576136c4613c89565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016136f79190614112565b60405180910390fd5b565b5f813b9050919050565b60405163150b7a028082523360208301528560601b60601c604083015283606083015260808083015282518060a08401528015613753578060c08401826020870160045afa505b60208360a48301601c86015f8a5af1613778573d15613774573d5f803e3d5ffd5b5f83525b8160e01b8351146137905763d1a57ed65f526004601cfd5b50505050505050565b5f815f527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260205f20820182015460601b60601c9050919050565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f815f527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260205f20820182015460601b9050919050565b6060600680546138e4906149b3565b80601f0160208091040260200160405190810160405280929190818152602001828054613910906149b3565b801561395b5780601f106139325761010080835404028352916020019161395b565b820191905f5260205f20905b81548152906001019060200180831161393e57829003601f168201915b5050505050905090565b60605f600161397384613c90565b0190505f8167ffffffffffffffff8111156139915761399061423e565b5b6040519080825280601f01601f1916602001820160405280156139c35781602001600182028036833780820191505090505b5090505f82602001820190505b600115613a24578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581613a1957613a18615438565b5b0494505f85036139d0575b819350505050919050565b5f7f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c52815f52601c600c205460201c9050919050565b613a718383613b57565b613a7a83613702565b15613a8c57613a8b5f84848461370c565b5b505050565b5f5b600115613aaf5760208320905080835281825f03068110613a93575b818106905092915050565b5f8060045f8581526020019081526020015f205490505f600184613ade91906149e3565b90505f60045f8381526020019081526020015f205490505f8314613b025782613b04565b855b9350818614613b32575f8114613b1a5780613b1c565b815b60045f8881526020019081526020015f20819055505b5f8114613b4e5760045f8381526020019081526020015f205f90555b50505092915050565b613b625f83836134ed565b8160601b60601c915081613b7d5763ea553b345f526004601cfd5b805f527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260205f208101810180548060601b15613bc45763c991cbb15f526004601cfd5b8381178255835f52601c600c20600181540163ffffffff8116613bee576301336cea5f526004601cfd5b808255505082845f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45050613c275f83836134f2565b5050565b5f613c3583613264565b90505f8282613c449190615465565b90505f613c5085613a2f565b9050613c82858277ffffffffffffffffffffffffffffffffffffffffffffffff1660c08563ffffffff16901b17613de1565b5050505050565b5f33905090565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613cec577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381613ce257613ce1615438565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310613d29576d04ee2d6d415b85acef81000000008381613d1f57613d1e615438565b5b0492506020810190505b662386f26fc100008310613d5857662386f26fc100008381613d4e57613d4d615438565b5b0492506010810190505b6305f5e1008310613d81576305f5e1008381613d7757613d76615438565b5b0492506008810190505b6127108310613da6576127108381613d9c57613d9b615438565b5b0492506004810190505b60648310613dc95760648381613dbf57613dbe615438565b5b0492506002810190505b600a8310613dd8576001810190505b80915050919050565b7f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c52815f52601c600c2080548060201c831860201b8118825550505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f613e5c82613e33565b9050919050565b613e6c81613e52565b8114613e76575f80fd5b50565b5f81359050613e8781613e63565b92915050565b5f60208284031215613ea257613ea1613e2b565b5b5f613eaf84828501613e79565b91505092915050565b5f60ff82169050919050565b613ecd81613eb8565b82525050565b5f604082019050613ee65f830185613ec4565b613ef36020830184613ec4565b9392505050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613f2e81613efa565b8114613f38575f80fd5b50565b5f81359050613f4981613f25565b92915050565b5f60208284031215613f6457613f63613e2b565b5b5f613f7184828501613f3b565b91505092915050565b5f8115159050919050565b613f8e81613f7a565b82525050565b5f602082019050613fa75f830184613f85565b92915050565b5f602082019050613fc05f830184613ec4565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015613ffd578082015181840152602081019050613fe2565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61402282613fc6565b61402c8185613fd0565b935061403c818560208601613fe0565b61404581614008565b840191505092915050565b5f6020820190508181035f8301526140688184614018565b905092915050565b5f61ffff82169050919050565b61408681614070565b82525050565b5f60208201905061409f5f83018461407d565b92915050565b5f819050919050565b6140b7816140a5565b81146140c1575f80fd5b50565b5f813590506140d2816140ae565b92915050565b5f602082840312156140ed576140ec613e2b565b5b5f6140fa848285016140c4565b91505092915050565b61410c81613e52565b82525050565b5f6020820190506141255f830184614103565b92915050565b5f806040838503121561414157614140613e2b565b5b5f61414e85828601613e79565b925050602061415f858286016140c4565b9150509250929050565b614172816140a5565b82525050565b5f60208201905061418b5f830184614169565b92915050565b5f805f606084860312156141a8576141a7613e2b565b5b5f6141b586828701613e79565b93505060206141c686828701613e79565b92505060406141d7868287016140c4565b9150509250925092565b6141ea81613eb8565b81146141f4575f80fd5b50565b5f81359050614205816141e1565b92915050565b5f602082840312156142205761421f613e2b565b5b5f61422d848285016141f7565b91505092915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61427482614008565b810181811067ffffffffffffffff821117156142935761429261423e565b5b80604052505050565b5f6142a5613e22565b90506142b1828261426b565b919050565b5f67ffffffffffffffff8211156142d0576142cf61423e565b5b6142d982614008565b9050602081019050919050565b828183375f83830152505050565b5f614306614301846142b6565b61429c565b9050828152602081018484840111156143225761432161423a565b5b61432d8482856142e6565b509392505050565b5f82601f83011261434957614348614236565b5b81356143598482602086016142f4565b91505092915050565b5f6020828403121561437757614376613e2b565b5b5f82013567ffffffffffffffff81111561439457614393613e2f565b5b6143a084828501614335565b91505092915050565b5f80fd5b5f80fd5b5f8083601f8401126143c6576143c5614236565b5b8235905067ffffffffffffffff8111156143e3576143e26143a9565b5b6020830191508360208202830111156143ff576143fe6143ad565b5b9250929050565b5f806020838503121561441c5761441b613e2b565b5b5f83013567ffffffffffffffff81111561443957614438613e2f565b5b614445858286016143b1565b92509250509250929050565b5f61445b82613e33565b9050919050565b61446b81614451565b82525050565b5f6020820190506144845f830184614462565b92915050565b5f8083601f84011261449f5761449e614236565b5b8235905067ffffffffffffffff8111156144bc576144bb6143a9565b5b6020830191508360208202830111156144d8576144d76143ad565b5b9250929050565b5f805f80604085870312156144f7576144f6613e2b565b5b5f85013567ffffffffffffffff81111561451457614513613e2f565b5b614520878288016143b1565b9450945050602085013567ffffffffffffffff81111561454357614542613e2f565b5b61454f8782880161448a565b925092505092959194509250565b61456681613f7a565b8114614570575f80fd5b50565b5f813590506145818161455d565b92915050565b5f806040838503121561459d5761459c613e2b565b5b5f6145aa85828601613e79565b92505060206145bb85828601614573565b9150509250929050565b5f8083601f8401126145da576145d9614236565b5b8235905067ffffffffffffffff8111156145f7576145f66143a9565b5b602083019150836001820283011115614613576146126143ad565b5b9250929050565b5f805f805f6080868803121561463357614632613e2b565b5b5f61464088828901613e79565b955050602061465188828901613e79565b9450506040614662888289016140c4565b935050606086013567ffffffffffffffff81111561468357614682613e2f565b5b61468f888289016145c5565b92509250509295509295909350565b5f63ffffffff82169050919050565b6146b68161469e565b82525050565b5f6020820190506146cf5f8301846146ad565b92915050565b5f80604083850312156146eb576146ea613e2b565b5b5f6146f885828601613e79565b925050602061470985828601613e79565b9150509250929050565b61471c81614451565b8114614726575f80fd5b50565b5f8135905061473781614713565b92915050565b5f6020828403121561475257614751613e2b565b5b5f61475f84828501614729565b91505092915050565b7f4a75646765206d696e7420636c6f7365000000000000000000000000000000005f82015250565b5f61479c601083613fd0565b91506147a782614768565b602082019050919050565b5f6020820190508181035f8301526147c981614790565b9050919050565b7f4e6f7420656c696769626c6500000000000000000000000000000000000000005f82015250565b5f614804600c83613fd0565b915061480f826147d0565b602082019050919050565b5f6020820190508181035f830152614831816147f8565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61486f82614070565b915061487a83614070565b9250828201905061ffff81111561489457614893614838565b5b92915050565b7f4d617820737570706c79206a75646765206578636565640000000000000000005f82015250565b5f6148ce601783613fd0565b91506148d98261489a565b602082019050919050565b5f6020820190508181035f8301526148fb816148c2565b9050919050565b5f6040820190506149155f830185614169565b614922602083018461407d565b9392505050565b5f61493382614070565b915061ffff820361494757614946614838565b5b600182019050919050565b5f61495c82613eb8565b915061496783613eb8565b9250828203905060ff8111156149805761497f614838565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806149ca57607f821691505b6020821081036149dd576149dc614986565b5b50919050565b5f6149ed826140a5565b91506149f8836140a5565b9250828203905081811115614a1057614a0f614838565b5b92915050565b7f4e6f7420656e6f75676820636c61696d61626c6520746f6b656e7300000000005f82015250565b5f614a4a601b83613fd0565b9150614a5582614a16565b602082019050919050565b5f6020820190508181035f830152614a7781614a3e565b9050919050565b5f614a88826140a5565b9150614a93836140a5565b9250828201905080821115614aab57614aaa614838565b5b92915050565b7f537570706c79206c696d697420657863656564000000000000000000000000005f82015250565b5f614ae5601383613fd0565b9150614af082614ab1565b602082019050919050565b5f6020820190508181035f830152614b1281614ad9565b9050919050565b5f614b2382613eb8565b9150614b2e83613eb8565b9250828201905060ff811115614b4757614b46614838565b5b92915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302614ba97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614b6e565b614bb38683614b6e565b95508019841693508086168417925050509392505050565b5f819050919050565b5f614bee614be9614be4846140a5565b614bcb565b6140a5565b9050919050565b5f819050919050565b614c0783614bd4565b614c1b614c1382614bf5565b848454614b7a565b825550505050565b5f90565b614c2f614c23565b614c3a818484614bfe565b505050565b5b81811015614c5d57614c525f82614c27565b600181019050614c40565b5050565b601f821115614ca257614c7381614b4d565b614c7c84614b5f565b81016020851015614c8b578190505b614c9f614c9785614b5f565b830182614c3f565b50505b505050565b5f82821c905092915050565b5f614cc25f1984600802614ca7565b1980831691505092915050565b5f614cda8383614cb3565b9150826002028217905092915050565b614cf382613fc6565b67ffffffffffffffff811115614d0c57614d0b61423e565b5b614d1682546149b3565b614d21828285614c61565b5f60209050601f831160018114614d52575f8415614d40578287015190505b614d4a8582614ccf565b865550614db1565b601f198416614d6086614b4d565b5f5b82811015614d8757848901518255600182019150602085019450602081019050614d62565b86831015614da45784890151614da0601f891682614cb3565b8355505b6001600288020188555050505b505050505050565b7f477561726469616e206d696e7420636c6f7365000000000000000000000000005f82015250565b5f614ded601383613fd0565b9150614df882614db9565b602082019050919050565b5f6020820190508181035f830152614e1a81614de1565b9050919050565b7f4e6f2067697665776179000000000000000000000000000000000000000000005f82015250565b5f614e55600a83613fd0565b9150614e6082614e21565b602082019050919050565b5f6020820190508181035f830152614e8281614e49565b9050919050565b7f4d617820737570706c7920677561726469616e206578636565640000000000005f82015250565b5f614ebd601a83613fd0565b9150614ec882614e89565b602082019050919050565b5f6020820190508181035f830152614eea81614eb1565b9050919050565b7f5768616c65206d696e7420636c6f7365000000000000000000000000000000005f82015250565b5f614f25601083613fd0565b9150614f3082614ef1565b602082019050919050565b5f6020820190508181035f830152614f5281614f19565b9050919050565b7f4d617820737570706c79207768616c65206578636565640000000000000000005f82015250565b5f614f8d601783613fd0565b9150614f9882614f59565b602082019050919050565b5f6020820190508181035f830152614fba81614f81565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61502081614070565b82525050565b5f6150318383615017565b60208301905092915050565b5f602082019050919050565b5f61505382614fee565b61505d8185614ff8565b935061506883615008565b805f5b8381101561509857815161507f8882615026565b975061508a8361503d565b92505060018101905061506b565b5085935050505092915050565b5f6040820190506150b85f830185614169565b81810360208301526150ca8184615049565b90509392505050565b7f486f6e6f72617279206d696e7420636c6f7365000000000000000000000000005f82015250565b5f615107601383613fd0565b9150615112826150d3565b602082019050919050565b5f6020820190508181035f830152615134816150fb565b9050919050565b7f4d617820737570706c7920686f6e6f72617279206578636565640000000000005f82015250565b5f61516f601a83613fd0565b915061517a8261513b565b602082019050919050565b5f6020820190508181035f83015261519c81615163565b9050919050565b7f4e62206164647265737320616e64206e62207175616e746974696573206d75735f8201527f7420626520657175616c00000000000000000000000000000000000000000000602082015250565b5f6151fd602a83613fd0565b9150615208826151a3565b604082019050919050565b5f6020820190508181035f83015261522a816151f1565b9050919050565b7f436f756e63696c206d696e7420636c6f736500000000000000000000000000005f82015250565b5f615265601283613fd0565b915061527082615231565b602082019050919050565b5f6020820190508181035f83015261529281615259565b9050919050565b7f4d617820737570706c7920636f756e63696c20657863656564000000000000005f82015250565b5f6152cd601983613fd0565b91506152d882615299565b602082019050919050565b5f6020820190508181035f8301526152fa816152c1565b9050919050565b7f756e6b6e6f7720746f6b656e00000000000000000000000000000000000000005f82015250565b5f615335600c83613fd0565b915061534082615301565b602082019050919050565b5f6020820190508181035f83015261536281615329565b9050919050565b5f81905092915050565b5f61537d82613fc6565b6153878185615369565b9350615397818560208601613fe0565b80840191505092915050565b5f6153ae8285615373565b91506153ba8284615373565b91508190509392505050565b5f819050919050565b6153e06153db826140a5565b6153c6565b82525050565b5f6153f182856153cf565b60208201915061540182846153cf565b6020820191508190509392505050565b5f61541b826140a5565b91505f820361542d5761542c614838565b5b600182039050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61546f8261469e565b915061547a8361469e565b9250828201905063ffffffff81111561549657615495614838565b5b9291505056fea2646970667358221220e90b78fd1e48f9522ce04e38979dd9b18bffed2f6a6e775afd6152c433fa750964736f6c63430008170033
Deployed Bytecode Sourcemap
123205:10171:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;124464:56;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;41940:383;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;131766:500;;;;;;;;;;;;;:::i;:::-;;126696:172;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119787:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123379:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34991:553;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35847:121;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;127218:172;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119665:114;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123832:44;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123622:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37675:3015;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;124866:53;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;123883:71;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;127783:464;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;126345:166;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;125528:105;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;126154:183;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;125058:53;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;130995:534;;;;;;;;;;;;;:::i;:::-;;40764:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123419:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;126876:163;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;127047;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;124262:55;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;33819:341;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123539:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123308:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34310:541;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;23319:103;;;;;;;;;;;;;:::i;:::-;;132546:827;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;130760:227;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123748:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;125290:108;;;:::i;:::-;;129888:864;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;126519:169;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123336:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22644:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123961:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123579:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123501:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119895:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;129500:380;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;36595:713;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123460:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;127398:377;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;128255:378;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;41482:244;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;131537:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;128641:851;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;125748:285;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;126041:105;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119406:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119367:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;132274:264;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;120007:138;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;124668:56;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;124083:54;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;36062:389;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123665:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;23577:220;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;125406:114;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123708:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;124464:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;41940:383::-;42016:11;42126;42121:3;42117:21;42293:10;42290:1;42287:17;42273:10;42270:1;42267:17;42254:10;42251:1;42248:17;42245:40;42242:63;42232:73;;42093:223;41940:383;;;:::o;131766:500::-;131833:16;;131815:15;:34;131807:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;131918:1;131889:26;131904:10;131889:14;:26::i;:::-;:30;;;131881:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;131976:14;;;;;;;;;;;131955:35;;131971:1;131955:13;;;;;;;;;;;:17;;;;:::i;:::-;:35;;;;131947:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;132066:1;132029:14;:26;132044:10;132029:26;;;;;;;;;;;;;;;:34;;;:38;;;;;;;;;;;;;;;;;;132078:43;132088:10;132100:20;;;;;;;;;;;132078:43;;:9;:43::i;:::-;132149:10;132137:62;;;132161:15;132178:20;;;;;;;;;;;132137:62;;;;;;;:::i;:::-;;;;;;;;132210:20;;:22;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;132243:13;;:15;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;131766:500::o;126696:172::-;126768:5;126827:17;:25;126845:6;126827:25;;;;;;;;;;;;;;;:33;;;;;;;;;;;;126793:17;:25;126811:6;126793:25;;;;;;;;;;;;;;;:31;;;;;;;;;;;;:67;;;;:::i;:::-;126786:74;;126696:172;;;:::o;119787:100::-;119841:13;119874:5;119867:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;119787:100;:::o;123379:33::-;;;;;;;;;;;;;:::o;34991:553::-;35053:14;35161:2;35155:4;35148:16;35191:24;35185:4;35178:38;35283:4;35277;35267:21;35263:2;35259:30;35255:2;35251:39;35336:13;35330:20;35326:2;35322:29;35318:2;35314:38;35304:170;;35386:10;35380:4;35373:24;35454:4;35448;35441:18;35304:170;35511:13;35508:1;35504:21;35498:28;35488:38;;35133:404;34991:553;;;:::o;35847:121::-;35927:33;35936:10;35948:7;35957:2;35927:8;:33::i;:::-;35847:121;;:::o;127218:172::-;127290:5;127349:17;:25;127367:6;127349:25;;;;;;;;;;;;;;;:33;;;;;;;;;;;;127315:17;:25;127333:6;127315:25;;;;;;;;;;;;;;;:31;;;;;;;;;;;;:67;;;;:::i;:::-;127308:74;;127218:172;;;:::o;119665:114::-;119717:7;119756:15;;119744:9;:27;;;;:::i;:::-;119737:34;;119665:114;:::o;123832:44::-;;;;:::o;123622:36::-;;;;;;;;;;;;;:::o;37675:3015::-;37769:34;37790:4;37796:2;37800;37769:20;:34::i;:::-;37953:1;37949:6;37945:2;37941:15;37998:4;37982:14;37978:25;37970:33;;38043:2;38027:14;38023:23;38017:29;;38110:2;38104:4;38097:16;38169:8;38143:24;38140:38;38134:4;38127:52;38246:4;38240;38230:21;38226:2;38222:30;38218:2;38214:39;38296:13;38290:20;38357:15;38341:14;38337:36;38484:4;38477:5;38474:15;38467:5;38463:27;38453:335;;38521:5;38511:149;;38564:10;38558:4;38551:24;38636:4;38630;38623:18;38511:149;38691:10;38685:4;38678:24;38768:4;38762;38755:18;38453:335;38860:2;38850:138;;38896:10;38890:4;38883:24;38968:4;38962;38955:18;38850:138;39090:4;39084;39077:18;39149:13;39146:1;39142:21;39136:28;39297:15;39287:8;39284:29;39277:4;39267:8;39264:18;39261:53;39251:293;;39371:4;39365;39355:21;39349:28;39339:186;;39419:10;39413:4;39406:24;39497:4;39491;39484:18;39339:186;39251:293;39617:15;39614:55;;;39665:1;39649:13;39646:1;39642:21;39635:32;39614:55;39058:626;39790:2;39784:4;39780:13;39763:15;39759:35;39744:13;39737:58;39912:4;39906;39896:21;39987:1;39969:15;39963:22;39959:30;39942:15;39935:55;39854:151;40094:2;40088:4;40081:16;40152:4;40146;40136:21;40228:1;40212:13;40206:20;40202:28;40283:20;40262:19;40258:46;40248:195;;40342:10;40336:4;40329:24;40419:4;40413;40406:18;40248:195;40483:19;40468:13;40461:42;40062:456;;40625:2;40621;40615:4;40588:25;40582:4;40576;40571:57;37867:2772;;;;40649:33;40669:4;40675:2;40679;40649:19;:33::i;:::-;37675:3015;;;:::o;124866:53::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;123883:71::-;;;;;;;;;;;;;:::o;127783:464::-;127880:1;127850:27;127866:10;127850:15;:27::i;:::-;:31;;;127842:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;127948:11;127917:42;;:27;127933:10;127917:15;:27::i;:::-;:42;;;;127909:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;128039:11;128023:27;;:13;:11;:13::i;:::-;:27;;;;:::i;:::-;128010:9;:40;;128002:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;128124:11;128085:15;:27;128101:10;128085:27;;;;;;;;;;;;;;;:35;;;:50;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;128146:36;128158:10;128170:11;128146:36;;:11;:36::i;:::-;128211:10;128198:41;;;128223:15;128198:41;;;;;;:::i;:::-;;;;;;;;127783:464;:::o;126345:166::-;126415:5;126472:15;:23;126488:6;126472:23;;;;;;;;;;;;;;;:31;;;;;;;;;;;;126440:15;:23;126456:6;126440:23;;;;;;;;;;;;;;;:29;;;;;;;;;;;;:63;;;;:::i;:::-;126433:70;;126345:166;;;:::o;125528:105::-;22530:13;:11;:13::i;:::-;125614:11:::1;125604:7;:21;;;;;;:::i;:::-;;125528:105:::0;:::o;126154:183::-;126202:7;126316:13;;;;;;;;;;;126228:101;;126300:13;;;;;;;;;;;126228:85;;126281:16;;;;;;;;;;;126228:69;;126262:16;;;;;;;;;;;126228:50;;126244:15;;;;;;;;;;;126228:31;;:13;:11;:13::i;:::-;:31;;;;:::i;:::-;:50;;;;:::i;:::-;:69;;;;:::i;:::-;:85;;;;:::i;:::-;:101;;;;:::i;:::-;126221:108;;126154:183;:::o;125058:53::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;130995:534::-;131065:16;;131047:15;:34;131039:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;131156:1;131124:29;131142:10;131124:17;:29::i;:::-;:33;;;131116:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;131215:17;;;;;;;;;;;131191:41;;131210:1;131191:16;;;;;;;;;;;:20;;;;:::i;:::-;:41;;;;131183:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;131314:1;131274:17;:29;131292:10;131274:29;;;;;;;;;;;;;;;:37;;;:41;;;;;;;;;;;;;;;;;;131326:46;131336:10;131348:23;;;;;;;;;;;131326:46;;:9;:46::i;:::-;131403:10;131388:68;;;131415:15;131432:23;;;;;;;;;;;131388:68;;;;;;;:::i;:::-;;;;;;;;131467:23;;:25;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;131503:16;;:18;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;130995:534::o;40764:201::-;40862:26;40875:4;40881:2;40885;40862:12;:26::i;:::-;40903:12;40912:2;40903:8;:12::i;:::-;40899:58;;;40917:40;40940:4;40946:2;40950;40917:40;;;;;;;;;;;;:22;:40::i;:::-;40899:58;40764:201;;;:::o;123419:34::-;;;;;;;;;;;;;:::o;126876:163::-;126945:5;127001:14;:22;127016:6;127001:22;;;;;;;;;;;;;;;:30;;;;;;;;;;;;126970:14;:22;126985:6;126970:22;;;;;;;;;;;;;;;:28;;;;;;;;;;;;:61;;;;:::i;:::-;126963:68;;126876:163;;;:::o;127047:::-;127116:5;127172:14;:22;127187:6;127172:22;;;;;;;;;;;;;;;:30;;;;;;;;;;;;127141:14;:22;127156:6;127141:22;;;;;;;;;;;;;;;:28;;;;;;;;;;;;:61;;;;:::i;:::-;127134:68;;127047:163;;;:::o;124262:55::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;33819:341::-;33877:14;33913:12;33922:2;33913:8;:12::i;:::-;33904:21;;34014:6;34004:138;;34054:10;34048:4;34041:24;34122:4;34116;34109:18;34004:138;33819:341;;;:::o;123539:31::-;;;;;;;;;;;;;:::o;123308:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;34310:541::-;34373:14;34533:5;34523:146;;34572:10;34566:4;34559:24;34649:4;34643;34636:18;34523:146;34696:24;34690:4;34683:38;34748:5;34742:4;34735:19;34812:20;34804:4;34798;34788:21;34782:28;34778:55;34768:65;;34310:541;;;:::o;23319:103::-;22530:13;:11;:13::i;:::-;23384:30:::1;23411:1;23384:18;:30::i;:::-;23319:103::o:0;132546:827::-;132630:16;;132612:15;:34;132604:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;132715:1;132686:26;132701:10;132686:14;:26::i;:::-;:30;;;132678:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;132782:11;132752:41;;:26;132767:10;132752:14;:26::i;:::-;:41;;;;132744:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;132875:16;;;;;;;;;;;132844:47;;132860:11;132844:27;;:13;;;;;;;;;;;:27;;;;:::i;:::-;:47;;;;132836:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;132930:31;132977:11;132964:25;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;132930:59;;133038:11;133000:14;:26;133015:10;133000:26;;;;;;;;;;;;;;;:34;;;:49;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;133065:7;133060:233;133082:11;133078:15;;:1;:15;;;133060:233;;;133115:43;133125:10;133137:20;;;;;;;;;;;133115:43;;:9;:43::i;:::-;133194:20;;;;;;;;;;;133173:15;133189:1;133173:18;;;;;;;;;;:::i;:::-;;;;;;;:41;;;;;;;;;;;133229:20;;:22;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;133266:13;;:15;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;133095:3;;;;;;;133060:233;;;;133320:10;133308:57;;;133332:15;133349;133308:57;;;;;;;:::i;:::-;;;;;;;;132593:780;132546:827;:::o;130760:227::-;22530:13;:11;:13::i;:::-;130861:6:::1;130856:124;130877:15;;:22;;130873:1;:26;130856:124;;;130967:1;130921:17;:37;130939:15;;130955:1;130939:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;130921:37;;;;;;;;;;;;;;;:43;;;:47;;;;;;;;;;;;;;;;;;130901:3;;;;;;;130856:124;;;;130760:227:::0;;:::o;123748:33::-;;;;;;;;;;;;;:::o;125290:108::-;22530:13;:11;:13::i;:::-;125349:9:::1;;;;;;;;;;;:18;;:41;125368:21;125349:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;125290:108::o:0;129888:864::-;129975:16;;129957:15;:34;129949:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;130066:1;130034:29;130052:10;130034:17;:29::i;:::-;:33;;;130026:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;130136:11;130103:44;;:29;130121:10;130103:17;:29::i;:::-;:44;;;;130095:84;;;;;;;;;;;;:::i;:::-;;;;;;;;;130232:17;;;;;;;;;;;130198:51;;130217:11;130198:30;;:16;;;;;;;;;;;:30;;;;:::i;:::-;:51;;;;130190:90;;;;;;;;;;;;:::i;:::-;;;;;;;;;130291:31;130338:11;130325:25;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;130291:59;;130402:11;130361:17;:29;130379:10;130361:29;;;;;;;;;;;;;;;:37;;;:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;130429:7;130424:245;130446:11;130442:15;;:1;:15;;;130424:245;;;130479:46;130489:10;130501:23;;;;;;;;;;;130479:46;;:9;:46::i;:::-;130561:23;;;;;;;;;;;130540:15;130556:1;130540:18;;;;;;;;;;:::i;:::-;;;;;;;:44;;;;;;;;;;;130599:23;;:25;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;130639:16;;:18;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;130459:3;;;;;;;130424:245;;;;130699:10;130684:60;;;130711:15;130728;130684:60;;;;;;;:::i;:::-;;;;;;;;129938:814;129888:864;:::o;126519:169::-;126590:5;126648:16;:24;126665:6;126648:24;;;;;;;;;;;;;;;:32;;;;;;;;;;;;126615:16;:24;126632:6;126615:24;;;;;;;;;;;;;;;:30;;;;;;;;;;;;:65;;;;:::i;:::-;126608:72;;126519:169;;;:::o;123336:34::-;;;;;;;;;;;;;:::o;22644:87::-;22690:7;22717:6;;;;;;;;;;;22710:13;;22644:87;:::o;123961:32::-;;;;;;;;;;;;;:::o;123579:36::-;;;;;;;;;;;;;:::o;123501:31::-;;;;;;;;;;;;;:::o;119895:104::-;119951:13;119984:7;119977:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;119895:104;:::o;129500:380::-;22530:13;:11;:13::i;:::-;129660:11:::1;;:18;;129634:15;;:22;;:44;129626:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;129741:6;129736:137;129757:15;;:22;;129753:1;:26;129736:137;;;129847:11;;129859:1;129847:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;129801:17;:37;129819:15;;129835:1;129819:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;129801:37;;;;;;;;;;;;;;;:43;;;:60;;;;;;;;;;;;;;;;;;129781:3;;;;;;;129736:137;;;;129500:380:::0;;;;:::o;36595:713::-;36810:10;36803:18;36796:26;36782:40;;36917:8;36911:4;36904:22;36953:31;36947:4;36940:45;37012:8;37006:4;36999:22;37065:10;37058:4;37052;37042:21;37035:41;37148:10;37142:4;37135:24;37265:8;37261:2;37257:17;37253:2;37249:26;37239:8;37204:33;37198:4;37192;37173:117;36595:713;;:::o;123460:34::-;;;;;;;;;;;;;:::o;127398:377::-;22530:13;:11;:13::i;:::-;127556:11:::1;;:18;;127530:15;;:22;;:44;127522:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;127637:6;127632:136;127653:15;;:22;;127649:1;:26;127632:136;;;127742:11;;127754:1;127742:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;127697:15;:35;127713:15;;127729:1;127713:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;127697:35;;;;;;;;;;;;;;;:41;;;:59;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;127677:3;;;;;;;127632:136;;;;127398:377:::0;;;;:::o;128255:378::-;22530:13;:11;:13::i;:::-;128414:11:::1;;:18;;128388:15;;:22;;:44;128380:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;128495:6;128490:136;128511:15;;:22;;128507:1;:26;128490:136;;;128600:11;;128612:1;128600:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;128555:16;:36;128572:15;;128588:1;128572:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;128555:36;;;;;;;;;;;;;;;:42;;;:59;;;;;;;;;;;;;;;;;;128535:3;;;;;;;128490:136;;;;128255:378:::0;;;;:::o;41482:244::-;41621:26;41634:4;41640:2;41644;41621:12;:26::i;:::-;41662:12;41671:2;41662:8;:12::i;:::-;41658:60;;;41676:42;41699:4;41705:2;41709;41713:4;;41676:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:22;:42::i;:::-;41658:60;41482:244;;;;;:::o;131537:221::-;22530:13;:11;:13::i;:::-;131635:6:::1;131630:121;131651:15;;:22;;131647:1;:26;131630:121;;;131738:1;131695:14;:34;131710:15;;131726:1;131710:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;131695:34;;;;;;;;;;;;;;;:40;;;:44;;;;;;;;;;;;;;;;;;131675:3;;;;;;;131630:121;;;;131537:221:::0;;:::o;128641:851::-;128727:16;;128709:15;:34;128701:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;128816:1;128785:28;128802:10;128785:16;:28::i;:::-;:32;;;128777:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;128885:11;128853:43;;:28;128870:10;128853:16;:28::i;:::-;:43;;;;128845:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;128980:16;;;;;;;;;;;128947:49;;128965:11;128947:29;;:15;;;;;;;;;;;:29;;;;:::i;:::-;:49;;;;128939:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;129037:31;129084:11;129071:25;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;129037:59;;129147:11;129107:16;:28;129124:10;129107:28;;;;;;;;;;;;;;;:36;;;:51;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;129174:7;129169:241;129191:11;129187:15;;:1;:15;;;129169:241;;;129224:45;129234:10;129246:22;;;;;;;;;;;129224:45;;:9;:45::i;:::-;129305:22;;;;;;;;;;;129284:15;129300:1;129284:18;;;;;;;;;;:::i;:::-;;;;;;;:43;;;;;;;;;;;129342:22;;:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;129381:15;;:17;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;129204:3;;;;;;;129169:241;;;;129439:10;129425:59;;;129451:15;129468;129425:59;;;;;;;:::i;:::-;;;;;;;;128690:802;128641:851;:::o;125748:285::-;125821:13;125855:16;125863:7;125855;:16::i;:::-;125847:41;;;;;;;;;;;;:::i;:::-;;;;;;;;;125899:17;125919:10;:8;:10::i;:::-;125899:30;;125967:1;125953:3;125947:17;:21;:78;;;;;;;;;;;;;;;;;125995:3;126000:18;:7;:16;:18::i;:::-;125978:41;;;;;;;;;:::i;:::-;;;;;;;;;;;;;125947:78;125940:85;;;125748:285;;;:::o;126041:105::-;126098:4;126122:16;126130:7;126122;:16::i;:::-;126115:23;;126041:105;;;:::o;119406:34::-;;;:::o;119367:30::-;;;;:::o;132274:264::-;22530:13;:11;:13::i;:::-;132402:6:::1;132397:134;132418:15;;:22;;132414:1;:26;132397:134;;;132505:11;;132517:1;132505:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;132462;:34;132477:15;;132493:1;132477:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;132462:34;;;;;;;;;;;;;;;:40;;;:57;;;;;;;;;;;;;;;;;;132442:3;;;;;;;132397:134;;;;132274:264:::0;;;;:::o;120007:138::-;120074:6;120133:3;120107:22;120122:6;120107:14;:22::i;:::-;:29;;;;120093:44;;120007:138;;;:::o;124668:56::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;124083:54::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;36062:389::-;36170:11;36280:8;36274:4;36267:22;36316:31;36310:4;36303:45;36375:5;36369:4;36362:19;36427:4;36421;36411:21;36405:28;36395:38;;36062:389;;;;:::o;123665:36::-;;;;;;;;;;;;;:::o;23577:220::-;22530:13;:11;:13::i;:::-;23682:1:::1;23662:22;;:8;:22;;::::0;23658:93:::1;;23736:1;23708:31;;;;;;;;;;;:::i;:::-;;;;;;;;23658:93;23761:28;23780:8;23761:18;:28::i;:::-;23577:220:::0;:::o;125406:114::-;22530:13;:11;:13::i;:::-;125499::::1;125487:9;;:25;;;;;;;;;;;;;;;;;;125406:114:::0;:::o;123708:33::-;;;;;;;;;;;;;:::o;48390:100::-;48461:21;48471:2;48475;48461:21;;;;;;;;;;;;:9;:21::i;:::-;48390:100;;:::o;54490:1438::-;54672:1;54668:6;54664:2;54660:15;54720:7;54704:14;54700:28;54689:39;;54768:2;54752:14;54748:23;54742:29;;54839:2;54833:4;54826:16;54898:2;54872:24;54869:32;54863:4;54856:46;54969:4;54963;54953:21;54949:2;54945:30;54941:2;54937:39;55029:13;55023:20;55007:14;55003:41;55116:5;55106:137;;55155:10;55149:4;55142:24;55223:4;55217;55210:18;55106:137;55421:5;55417:2;55414:13;55409:2;55402:10;55399:29;55389:286;;55462:5;55456:4;55449:19;55518:4;55512;55502:21;55496:28;55486:174;;55562:10;55556:4;55549:24;55636:4;55630;55623:18;55486:174;55389:286;55786:7;55770:13;55767:1;55763:21;55756:38;55907:2;55898:7;55891:5;55864:25;55858:4;55852;55847:63;54586:1335;;;54490:1438;;;:::o;63240:87::-;;;;:::o;63427:86::-;;;;:::o;120153:939::-;120252:9;120238:23;;:10;:23;;;120234:57;;120270:21;;;;;;;;;;;;;;120234:57;120320:1;120306:10;:15;120302:53;;120330:25;;;;;;;;;;;;;;120302:53;120388:10;120370:15;;:28;120366:67;;;120407:26;;;;;;;;;;;;;;120366:67;120446:24;120473:109;;;;;;;;120535:15;120552:16;120504:75;;;;;;;;;:::i;:::-;;;;;;;;;;;;;120494:86;;;;;;120486:95;;120473:109;;;120446:136;;120595:30;120628:15;;120595:48;;120661:9;120656:319;120676:10;120672:1;:14;120656:319;;;120705:19;120727:36;120740:22;120727:4;:12;;:36;;;;:::i;:::-;120705:58;;120780:15;120798:61;120823:11;120836:22;120798:24;:61::i;:::-;120780:79;;120876:18;120882:2;120886:7;120876:5;:18::i;:::-;120911:24;;;;:::i;:::-;;;120959:3;;;;;120690:285;;120656:319;;;;120987:46;121010:2;121021:10;120987:22;:46::i;:::-;121062:22;121044:15;:40;;;;120223:869;;120153:939;;:::o;22809:166::-;22880:12;:10;:12::i;:::-;22869:23;;:7;:5;:7::i;:::-;:23;;;22865:103;;22943:12;:10;:12::i;:::-;22916:40;;;;;;;;;;;:::i;:::-;;;;;;;;22865:103;22809:166::o;63870:217::-;63921:11;64035:1;64023:14;64013:24;;63870:217;;;:::o;64250:1416::-;64485:4;64479:11;64536:10;64570:24;64567:1;64560:35;64630:8;64623:4;64620:1;64616:12;64609:30;64739:4;64735:2;64731:13;64727:2;64723:22;64716:4;64713:1;64709:12;64702:44;64781:2;64774:4;64771:1;64767:12;64760:24;64819:4;64812;64809:1;64805:12;64798:26;64853:4;64847:11;64893:1;64886:4;64883:1;64879:12;64872:23;64912:1;64909:71;;;64975:1;64968:4;64965:1;64961:12;64958:1;64951:4;64945;64941:15;64938:1;64931:5;64920:57;64916:62;64909:71;65094:4;65091:1;65084:4;65081:1;65077:12;65070:4;65067:1;65063:12;65060:1;65056:2;65049:5;65044:55;65034:351;;65123:16;65120:220;;;65252:16;65246:4;65240;65225:44;65304:16;65298:4;65291:30;65120:220;65368:1;65365;65358:12;65034:351;65479:24;65474:3;65470:34;65466:1;65460:8;65457:48;65447:201;;65539:10;65533:4;65526:24;65628:4;65622;65615:18;65447:201;64421:1238;;;64250:1416;;;;:::o;43118:330::-;43179:14;43287:2;43281:4;43274:16;43317:24;43311:4;43304:38;43420:4;43414;43404:21;43400:2;43396:30;43392:2;43388:39;43382:46;43378:2;43374:55;43370:2;43366:64;43356:74;;43118:330;;;:::o;23957:191::-;24031:16;24050:6;;;;;;;;;;;24031:25;;24076:8;24067:6;;:17;;;;;;;;;;;;;;;;;;24131:8;24100:40;;24121:8;24100:40;;;;;;;;;;;;24020:128;23957:191;:::o;42662:317::-;42722:11;42827:2;42821:4;42814:16;42857:24;42851:4;42844:38;42952:4;42946;42936:21;42932:2;42928:30;42924:2;42920:39;42914:46;42910:2;42906:55;42896:65;;42662:317;;;:::o;125641:99::-;125692:13;125725:7;125718:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;125641:99;:::o;17528:718::-;17584:13;17635:14;17672:1;17652:17;17663:5;17652:10;:17::i;:::-;:21;17635:38;;17688:20;17722:6;17711:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17688:41;;17744:11;17873:6;17869:2;17865:15;17857:6;17853:28;17846:35;;17910:290;17917:4;17910:290;;;17942:5;;;;;;;;18084:10;18079:2;18072:5;18068:14;18063:32;18058:3;18050:46;18142:2;18133:11;;;;;;:::i;:::-;;;;;18176:1;18167:5;:10;17910:290;18163:21;17910:290;18221:6;18214:13;;;;;17528:718;;;:::o;43984:308::-;44047:14;44155:24;44149:4;44142:38;44207:5;44201:4;44194:19;44267:4;44261;44251:21;44245:28;44241:2;44237:37;44227:47;;43984:308;;;:::o;48855:188::-;48945:13;48951:2;48955;48945:5;:13::i;:::-;48973:12;48982:2;48973:8;:12::i;:::-;48969:66;;;48987:48;49018:1;49022:2;49026;49030:4;48987:22;:48::i;:::-;48969:66;48855:188;;;:::o;68123:419::-;68196:14;68291:191;68298:1;68291:191;;;68348:4;68342;68332:21;68322:31;;68384:6;68378:4;68371:20;68449:5;68441;68438:1;68434:13;68430:25;68422:6;68419:37;68291:191;68409:58;68291:191;68518:5;68510:6;68506:18;68496:28;;68123:419;;;;:::o;121662:636::-;121778:14;121810:18;121831:16;:28;121848:10;121831:28;;;;;;;;;;;;121810:49;;121870:17;121918:1;121890:25;:29;;;;:::i;:::-;121870:49;;121930:22;121955:16;:27;121972:9;121955:27;;;;;;;;;;;;121930:52;;122018:1;122004:10;:15;:41;;122035:10;122004:41;;;122022:10;122004:41;121995:50;;122076:9;122062:10;:23;122058:135;;122151:1;122133:14;:19;:48;;122167:14;122133:48;;;122155:9;122133:48;122102:16;:28;122119:10;122102:28;;;;;;;;;;;:79;;;;122058:135;122227:1;122209:14;:19;122205:86;;122252:16;:27;122269:9;122252:27;;;;;;;;;;;122245:34;;;122205:86;121799:499;;;121662:636;;;;:::o;46643:1686::-;46710:40;46739:1;46743:2;46747;46710:20;:40::i;:::-;46888:2;46884;46880:11;46876:2;46872:20;46866:26;;46964:2;46954:138;;47000:10;46994:4;46987:24;47072:4;47066;47059:18;46954:138;47156:2;47150:4;47143:16;47186:24;47180:4;47173:38;47278:4;47272;47262:21;47258:2;47254:30;47250:2;47246:39;47328:13;47322:20;47415:15;47411:2;47407:24;47404:149;;;47464:10;47458:4;47451:24;47533:4;47527;47520:18;47404:149;47644:2;47627:15;47624:23;47609:13;47602:46;47742:2;47736:4;47729:16;47798:4;47792;47782:21;47870:1;47856:11;47850:18;47846:26;47923:20;47904:17;47900:44;47890:193;;47982:10;47976:4;47969:24;48059:4;48053;48046:18;47890:193;48121:17;48108:11;48101:38;47710:444;;48258:2;48254;48251:1;48224:25;48218:4;48212;48207:54;46814:1458;;48282:39;48310:1;48314:2;48318;48282:19;:39::i;:::-;46643:1686;;:::o;122729:390::-;122813:16;122832:20;122845:6;122832:12;:20::i;:::-;122813:39;;122863:23;122908:8;122889:9;:28;;;;:::i;:::-;122863:54;;122928:15;122946:22;122961:6;122946:14;:22::i;:::-;122928:40;;122981:130;123010:6;123091:7;123075:25;;123068:3;123047:16;123039:25;;:32;;123031:69;122981:14;:130::i;:::-;122802:317;;;122729:390;;:::o;20760:98::-;20813:7;20840:10;20833:17;;20760:98;:::o;12590:948::-;12643:7;12663:14;12680:1;12663:18;;12730:8;12721:5;:17;12717:106;;12768:8;12759:17;;;;;;:::i;:::-;;;;;12805:2;12795:12;;;;12717:106;12850:8;12841:5;:17;12837:106;;12888:8;12879:17;;;;;;:::i;:::-;;;;;12925:2;12915:12;;;;12837:106;12970:8;12961:5;:17;12957:106;;13008:8;12999:17;;;;;;:::i;:::-;;;;;13045:2;13035:12;;;;12957:106;13090:7;13081:5;:16;13077:103;;13127:7;13118:16;;;;;;:::i;:::-;;;;;13163:1;13153:11;;;;13077:103;13207:7;13198:5;:16;13194:103;;13244:7;13235:16;;;;;;:::i;:::-;;;;;13280:1;13270:11;;;;13194:103;13324:7;13315:5;:16;13311:103;;13361:7;13352:16;;;;;;:::i;:::-;;;;;13397:1;13387:11;;;;13311:103;13441:7;13432:5;:16;13428:68;;13479:1;13469:11;;;;13428:68;13524:6;13517:13;;;12590:948;;;:::o;44548:416::-;44704:24;44698:4;44691:38;44756:5;44750:4;44743:19;44811:4;44805;44795:21;44850:11;44844:18;44935:6;44931:2;44927:15;44920:5;44916:27;44912:2;44908:36;44900:6;44896:49;44883:11;44876:70;44676:281;;44548:416;;:::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:126;371:7;411:42;404:5;400:54;389:65;;334:126;;;:::o;466:96::-;503:7;532:24;550:5;532:24;:::i;:::-;521:35;;466:96;;;:::o;568:122::-;641:24;659:5;641:24;:::i;:::-;634:5;631:35;621:63;;680:1;677;670:12;621:63;568:122;:::o;696:139::-;742:5;780:6;767:20;758:29;;796:33;823:5;796:33;:::i;:::-;696:139;;;;:::o;841:329::-;900:6;949:2;937:9;928:7;924:23;920:32;917:119;;;955:79;;:::i;:::-;917:119;1075:1;1100:53;1145:7;1136:6;1125:9;1121:22;1100:53;:::i;:::-;1090:63;;1046:117;841:329;;;;:::o;1176:86::-;1211:7;1251:4;1244:5;1240:16;1229:27;;1176:86;;;:::o;1268:112::-;1351:22;1367:5;1351:22;:::i;:::-;1346:3;1339:35;1268:112;;:::o;1386:316::-;1499:4;1537:2;1526:9;1522:18;1514:26;;1550:67;1614:1;1603:9;1599:17;1590:6;1550:67;:::i;:::-;1627:68;1691:2;1680:9;1676:18;1667:6;1627:68;:::i;:::-;1386:316;;;;;:::o;1708:149::-;1744:7;1784:66;1777:5;1773:78;1762:89;;1708:149;;;:::o;1863:120::-;1935:23;1952:5;1935:23;:::i;:::-;1928:5;1925:34;1915:62;;1973:1;1970;1963:12;1915:62;1863:120;:::o;1989:137::-;2034:5;2072:6;2059:20;2050:29;;2088:32;2114:5;2088:32;:::i;:::-;1989:137;;;;:::o;2132:327::-;2190:6;2239:2;2227:9;2218:7;2214:23;2210:32;2207:119;;;2245:79;;:::i;:::-;2207:119;2365:1;2390:52;2434:7;2425:6;2414:9;2410:22;2390:52;:::i;:::-;2380:62;;2336:116;2132:327;;;;:::o;2465:90::-;2499:7;2542:5;2535:13;2528:21;2517:32;;2465:90;;;:::o;2561:109::-;2642:21;2657:5;2642:21;:::i;:::-;2637:3;2630:34;2561:109;;:::o;2676:210::-;2763:4;2801:2;2790:9;2786:18;2778:26;;2814:65;2876:1;2865:9;2861:17;2852:6;2814:65;:::i;:::-;2676:210;;;;:::o;2892:214::-;2981:4;3019:2;3008:9;3004:18;2996:26;;3032:67;3096:1;3085:9;3081:17;3072:6;3032:67;:::i;:::-;2892:214;;;;:::o;3112:99::-;3164:6;3198:5;3192:12;3182:22;;3112:99;;;:::o;3217:169::-;3301:11;3335:6;3330:3;3323:19;3375:4;3370:3;3366:14;3351:29;;3217:169;;;;:::o;3392:246::-;3473:1;3483:113;3497:6;3494:1;3491:13;3483:113;;;3582:1;3577:3;3573:11;3567:18;3563:1;3558:3;3554:11;3547:39;3519:2;3516:1;3512:10;3507:15;;3483:113;;;3630:1;3621:6;3616:3;3612:16;3605:27;3454:184;3392:246;;;:::o;3644:102::-;3685:6;3736:2;3732:7;3727:2;3720:5;3716:14;3712:28;3702:38;;3644:102;;;:::o;3752:377::-;3840:3;3868:39;3901:5;3868:39;:::i;:::-;3923:71;3987:6;3982:3;3923:71;:::i;:::-;3916:78;;4003:65;4061:6;4056:3;4049:4;4042:5;4038:16;4003:65;:::i;:::-;4093:29;4115:6;4093:29;:::i;:::-;4088:3;4084:39;4077:46;;3844:285;3752:377;;;;:::o;4135:313::-;4248:4;4286:2;4275:9;4271:18;4263:26;;4335:9;4329:4;4325:20;4321:1;4310:9;4306:17;4299:47;4363:78;4436:4;4427:6;4363:78;:::i;:::-;4355:86;;4135:313;;;;:::o;4454:89::-;4490:7;4530:6;4523:5;4519:18;4508:29;;4454:89;;;:::o;4549:115::-;4634:23;4651:5;4634:23;:::i;:::-;4629:3;4622:36;4549:115;;:::o;4670:218::-;4761:4;4799:2;4788:9;4784:18;4776:26;;4812:69;4878:1;4867:9;4863:17;4854:6;4812:69;:::i;:::-;4670:218;;;;:::o;4894:77::-;4931:7;4960:5;4949:16;;4894:77;;;:::o;4977:122::-;5050:24;5068:5;5050:24;:::i;:::-;5043:5;5040:35;5030:63;;5089:1;5086;5079:12;5030:63;4977:122;:::o;5105:139::-;5151:5;5189:6;5176:20;5167:29;;5205:33;5232:5;5205:33;:::i;:::-;5105:139;;;;:::o;5250:329::-;5309:6;5358:2;5346:9;5337:7;5333:23;5329:32;5326:119;;;5364:79;;:::i;:::-;5326:119;5484:1;5509:53;5554:7;5545:6;5534:9;5530:22;5509:53;:::i;:::-;5499:63;;5455:117;5250:329;;;;:::o;5585:118::-;5672:24;5690:5;5672:24;:::i;:::-;5667:3;5660:37;5585:118;;:::o;5709:222::-;5802:4;5840:2;5829:9;5825:18;5817:26;;5853:71;5921:1;5910:9;5906:17;5897:6;5853:71;:::i;:::-;5709:222;;;;:::o;5937:474::-;6005:6;6013;6062:2;6050:9;6041:7;6037:23;6033:32;6030:119;;;6068:79;;:::i;:::-;6030:119;6188:1;6213:53;6258:7;6249:6;6238:9;6234:22;6213:53;:::i;:::-;6203:63;;6159:117;6315:2;6341:53;6386:7;6377:6;6366:9;6362:22;6341:53;:::i;:::-;6331:63;;6286:118;5937:474;;;;;:::o;6417:118::-;6504:24;6522:5;6504:24;:::i;:::-;6499:3;6492:37;6417:118;;:::o;6541:222::-;6634:4;6672:2;6661:9;6657:18;6649:26;;6685:71;6753:1;6742:9;6738:17;6729:6;6685:71;:::i;:::-;6541:222;;;;:::o;6769:619::-;6846:6;6854;6862;6911:2;6899:9;6890:7;6886:23;6882:32;6879:119;;;6917:79;;:::i;:::-;6879:119;7037:1;7062:53;7107:7;7098:6;7087:9;7083:22;7062:53;:::i;:::-;7052:63;;7008:117;7164:2;7190:53;7235:7;7226:6;7215:9;7211:22;7190:53;:::i;:::-;7180:63;;7135:118;7292:2;7318:53;7363:7;7354:6;7343:9;7339:22;7318:53;:::i;:::-;7308:63;;7263:118;6769:619;;;;;:::o;7394:118::-;7465:22;7481:5;7465:22;:::i;:::-;7458:5;7455:33;7445:61;;7502:1;7499;7492:12;7445:61;7394:118;:::o;7518:135::-;7562:5;7600:6;7587:20;7578:29;;7616:31;7641:5;7616:31;:::i;:::-;7518:135;;;;:::o;7659:325::-;7716:6;7765:2;7753:9;7744:7;7740:23;7736:32;7733:119;;;7771:79;;:::i;:::-;7733:119;7891:1;7916:51;7959:7;7950:6;7939:9;7935:22;7916:51;:::i;:::-;7906:61;;7862:115;7659:325;;;;:::o;7990:117::-;8099:1;8096;8089:12;8113:117;8222:1;8219;8212:12;8236:180;8284:77;8281:1;8274:88;8381:4;8378:1;8371:15;8405:4;8402:1;8395:15;8422:281;8505:27;8527:4;8505:27;:::i;:::-;8497:6;8493:40;8635:6;8623:10;8620:22;8599:18;8587:10;8584:34;8581:62;8578:88;;;8646:18;;:::i;:::-;8578:88;8686:10;8682:2;8675:22;8465:238;8422:281;;:::o;8709:129::-;8743:6;8770:20;;:::i;:::-;8760:30;;8799:33;8827:4;8819:6;8799:33;:::i;:::-;8709:129;;;:::o;8844:308::-;8906:4;8996:18;8988:6;8985:30;8982:56;;;9018:18;;:::i;:::-;8982:56;9056:29;9078:6;9056:29;:::i;:::-;9048:37;;9140:4;9134;9130:15;9122:23;;8844:308;;;:::o;9158:146::-;9255:6;9250:3;9245;9232:30;9296:1;9287:6;9282:3;9278:16;9271:27;9158:146;;;:::o;9310:425::-;9388:5;9413:66;9429:49;9471:6;9429:49;:::i;:::-;9413:66;:::i;:::-;9404:75;;9502:6;9495:5;9488:21;9540:4;9533:5;9529:16;9578:3;9569:6;9564:3;9560:16;9557:25;9554:112;;;9585:79;;:::i;:::-;9554:112;9675:54;9722:6;9717:3;9712;9675:54;:::i;:::-;9394:341;9310:425;;;;;:::o;9755:340::-;9811:5;9860:3;9853:4;9845:6;9841:17;9837:27;9827:122;;9868:79;;:::i;:::-;9827:122;9985:6;9972:20;10010:79;10085:3;10077:6;10070:4;10062:6;10058:17;10010:79;:::i;:::-;10001:88;;9817:278;9755:340;;;;:::o;10101:509::-;10170:6;10219:2;10207:9;10198:7;10194:23;10190:32;10187:119;;;10225:79;;:::i;:::-;10187:119;10373:1;10362:9;10358:17;10345:31;10403:18;10395:6;10392:30;10389:117;;;10425:79;;:::i;:::-;10389:117;10530:63;10585:7;10576:6;10565:9;10561:22;10530:63;:::i;:::-;10520:73;;10316:287;10101:509;;;;:::o;10616:117::-;10725:1;10722;10715:12;10739:117;10848:1;10845;10838:12;10879:568;10952:8;10962:6;11012:3;11005:4;10997:6;10993:17;10989:27;10979:122;;11020:79;;:::i;:::-;10979:122;11133:6;11120:20;11110:30;;11163:18;11155:6;11152:30;11149:117;;;11185:79;;:::i;:::-;11149:117;11299:4;11291:6;11287:17;11275:29;;11353:3;11345:4;11337:6;11333:17;11323:8;11319:32;11316:41;11313:128;;;11360:79;;:::i;:::-;11313:128;10879:568;;;;;:::o;11453:559::-;11539:6;11547;11596:2;11584:9;11575:7;11571:23;11567:32;11564:119;;;11602:79;;:::i;:::-;11564:119;11750:1;11739:9;11735:17;11722:31;11780:18;11772:6;11769:30;11766:117;;;11802:79;;:::i;:::-;11766:117;11915:80;11987:7;11978:6;11967:9;11963:22;11915:80;:::i;:::-;11897:98;;;;11693:312;11453:559;;;;;:::o;12018:104::-;12063:7;12092:24;12110:5;12092:24;:::i;:::-;12081:35;;12018:104;;;:::o;12128:142::-;12231:32;12257:5;12231:32;:::i;:::-;12226:3;12219:45;12128:142;;:::o;12276:254::-;12385:4;12423:2;12412:9;12408:18;12400:26;;12436:87;12520:1;12509:9;12505:17;12496:6;12436:87;:::i;:::-;12276:254;;;;:::o;12551:566::-;12622:8;12632:6;12682:3;12675:4;12667:6;12663:17;12659:27;12649:122;;12690:79;;:::i;:::-;12649:122;12803:6;12790:20;12780:30;;12833:18;12825:6;12822:30;12819:117;;;12855:79;;:::i;:::-;12819:117;12969:4;12961:6;12957:17;12945:29;;13023:3;13015:4;13007:6;13003:17;12993:8;12989:32;12986:41;12983:128;;;13030:79;;:::i;:::-;12983:128;12551:566;;;;;:::o;13123:930::-;13243:6;13251;13259;13267;13316:2;13304:9;13295:7;13291:23;13287:32;13284:119;;;13322:79;;:::i;:::-;13284:119;13470:1;13459:9;13455:17;13442:31;13500:18;13492:6;13489:30;13486:117;;;13522:79;;:::i;:::-;13486:117;13635:80;13707:7;13698:6;13687:9;13683:22;13635:80;:::i;:::-;13617:98;;;;13413:312;13792:2;13781:9;13777:18;13764:32;13823:18;13815:6;13812:30;13809:117;;;13845:79;;:::i;:::-;13809:117;13958:78;14028:7;14019:6;14008:9;14004:22;13958:78;:::i;:::-;13940:96;;;;13735:311;13123:930;;;;;;;:::o;14059:116::-;14129:21;14144:5;14129:21;:::i;:::-;14122:5;14119:32;14109:60;;14165:1;14162;14155:12;14109:60;14059:116;:::o;14181:133::-;14224:5;14262:6;14249:20;14240:29;;14278:30;14302:5;14278:30;:::i;:::-;14181:133;;;;:::o;14320:468::-;14385:6;14393;14442:2;14430:9;14421:7;14417:23;14413:32;14410:119;;;14448:79;;:::i;:::-;14410:119;14568:1;14593:53;14638:7;14629:6;14618:9;14614:22;14593:53;:::i;:::-;14583:63;;14539:117;14695:2;14721:50;14763:7;14754:6;14743:9;14739:22;14721:50;:::i;:::-;14711:60;;14666:115;14320:468;;;;;:::o;14807:552::-;14864:8;14874:6;14924:3;14917:4;14909:6;14905:17;14901:27;14891:122;;14932:79;;:::i;:::-;14891:122;15045:6;15032:20;15022:30;;15075:18;15067:6;15064:30;15061:117;;;15097:79;;:::i;:::-;15061:117;15211:4;15203:6;15199:17;15187:29;;15265:3;15257:4;15249:6;15245:17;15235:8;15231:32;15228:41;15225:128;;;15272:79;;:::i;:::-;15225:128;14807:552;;;;;:::o;15365:963::-;15462:6;15470;15478;15486;15494;15543:3;15531:9;15522:7;15518:23;15514:33;15511:120;;;15550:79;;:::i;:::-;15511:120;15670:1;15695:53;15740:7;15731:6;15720:9;15716:22;15695:53;:::i;:::-;15685:63;;15641:117;15797:2;15823:53;15868:7;15859:6;15848:9;15844:22;15823:53;:::i;:::-;15813:63;;15768:118;15925:2;15951:53;15996:7;15987:6;15976:9;15972:22;15951:53;:::i;:::-;15941:63;;15896:118;16081:2;16070:9;16066:18;16053:32;16112:18;16104:6;16101:30;16098:117;;;16134:79;;:::i;:::-;16098:117;16247:64;16303:7;16294:6;16283:9;16279:22;16247:64;:::i;:::-;16229:82;;;;16024:297;15365:963;;;;;;;;:::o;16334:93::-;16370:7;16410:10;16403:5;16399:22;16388:33;;16334:93;;;:::o;16433:115::-;16518:23;16535:5;16518:23;:::i;:::-;16513:3;16506:36;16433:115;;:::o;16554:218::-;16645:4;16683:2;16672:9;16668:18;16660:26;;16696:69;16762:1;16751:9;16747:17;16738:6;16696:69;:::i;:::-;16554:218;;;;:::o;16778:474::-;16846:6;16854;16903:2;16891:9;16882:7;16878:23;16874:32;16871:119;;;16909:79;;:::i;:::-;16871:119;17029:1;17054:53;17099:7;17090:6;17079:9;17075:22;17054:53;:::i;:::-;17044:63;;17000:117;17156:2;17182:53;17227:7;17218:6;17207:9;17203:22;17182:53;:::i;:::-;17172:63;;17127:118;16778:474;;;;;:::o;17258:138::-;17339:32;17365:5;17339:32;:::i;:::-;17332:5;17329:43;17319:71;;17386:1;17383;17376:12;17319:71;17258:138;:::o;17402:155::-;17456:5;17494:6;17481:20;17472:29;;17510:41;17545:5;17510:41;:::i;:::-;17402:155;;;;:::o;17563:345::-;17630:6;17679:2;17667:9;17658:7;17654:23;17650:32;17647:119;;;17685:79;;:::i;:::-;17647:119;17805:1;17830:61;17883:7;17874:6;17863:9;17859:22;17830:61;:::i;:::-;17820:71;;17776:125;17563:345;;;;:::o;17914:166::-;18054:18;18050:1;18042:6;18038:14;18031:42;17914:166;:::o;18086:366::-;18228:3;18249:67;18313:2;18308:3;18249:67;:::i;:::-;18242:74;;18325:93;18414:3;18325:93;:::i;:::-;18443:2;18438:3;18434:12;18427:19;;18086:366;;;:::o;18458:419::-;18624:4;18662:2;18651:9;18647:18;18639:26;;18711:9;18705:4;18701:20;18697:1;18686:9;18682:17;18675:47;18739:131;18865:4;18739:131;:::i;:::-;18731:139;;18458:419;;;:::o;18883:162::-;19023:14;19019:1;19011:6;19007:14;19000:38;18883:162;:::o;19051:366::-;19193:3;19214:67;19278:2;19273:3;19214:67;:::i;:::-;19207:74;;19290:93;19379:3;19290:93;:::i;:::-;19408:2;19403:3;19399:12;19392:19;;19051:366;;;:::o;19423:419::-;19589:4;19627:2;19616:9;19612:18;19604:26;;19676:9;19670:4;19666:20;19662:1;19651:9;19647:17;19640:47;19704:131;19830:4;19704:131;:::i;:::-;19696:139;;19423:419;;;:::o;19848:180::-;19896:77;19893:1;19886:88;19993:4;19990:1;19983:15;20017:4;20014:1;20007:15;20034:193;20073:3;20092:19;20109:1;20092:19;:::i;:::-;20087:24;;20125:19;20142:1;20125:19;:::i;:::-;20120:24;;20167:1;20164;20160:9;20153:16;;20190:6;20185:3;20182:15;20179:41;;;20200:18;;:::i;:::-;20179:41;20034:193;;;;:::o;20233:173::-;20373:25;20369:1;20361:6;20357:14;20350:49;20233:173;:::o;20412:366::-;20554:3;20575:67;20639:2;20634:3;20575:67;:::i;:::-;20568:74;;20651:93;20740:3;20651:93;:::i;:::-;20769:2;20764:3;20760:12;20753:19;;20412:366;;;:::o;20784:419::-;20950:4;20988:2;20977:9;20973:18;20965:26;;21037:9;21031:4;21027:20;21023:1;21012:9;21008:17;21001:47;21065:131;21191:4;21065:131;:::i;:::-;21057:139;;20784:419;;;:::o;21209:328::-;21328:4;21366:2;21355:9;21351:18;21343:26;;21379:71;21447:1;21436:9;21432:17;21423:6;21379:71;:::i;:::-;21460:70;21526:2;21515:9;21511:18;21502:6;21460:70;:::i;:::-;21209:328;;;;;:::o;21543:171::-;21581:3;21604:23;21621:5;21604:23;:::i;:::-;21595:32;;21649:6;21642:5;21639:17;21636:43;;21659:18;;:::i;:::-;21636:43;21706:1;21699:5;21695:13;21688:20;;21543:171;;;:::o;21720:191::-;21758:4;21778:18;21794:1;21778:18;:::i;:::-;21773:23;;21810:18;21826:1;21810:18;:::i;:::-;21805:23;;21852:1;21849;21845:9;21837:17;;21876:4;21870;21867:14;21864:40;;;21884:18;;:::i;:::-;21864:40;21720:191;;;;:::o;21917:180::-;21965:77;21962:1;21955:88;22062:4;22059:1;22052:15;22086:4;22083:1;22076:15;22103:320;22147:6;22184:1;22178:4;22174:12;22164:22;;22231:1;22225:4;22221:12;22252:18;22242:81;;22308:4;22300:6;22296:17;22286:27;;22242:81;22370:2;22362:6;22359:14;22339:18;22336:38;22333:84;;22389:18;;:::i;:::-;22333:84;22154:269;22103:320;;;:::o;22429:194::-;22469:4;22489:20;22507:1;22489:20;:::i;:::-;22484:25;;22523:20;22541:1;22523:20;:::i;:::-;22518:25;;22567:1;22564;22560:9;22552:17;;22591:1;22585:4;22582:11;22579:37;;;22596:18;;:::i;:::-;22579:37;22429:194;;;;:::o;22629:177::-;22769:29;22765:1;22757:6;22753:14;22746:53;22629:177;:::o;22812:366::-;22954:3;22975:67;23039:2;23034:3;22975:67;:::i;:::-;22968:74;;23051:93;23140:3;23051:93;:::i;:::-;23169:2;23164:3;23160:12;23153:19;;22812:366;;;:::o;23184:419::-;23350:4;23388:2;23377:9;23373:18;23365:26;;23437:9;23431:4;23427:20;23423:1;23412:9;23408:17;23401:47;23465:131;23591:4;23465:131;:::i;:::-;23457:139;;23184:419;;;:::o;23609:191::-;23649:3;23668:20;23686:1;23668:20;:::i;:::-;23663:25;;23702:20;23720:1;23702:20;:::i;:::-;23697:25;;23745:1;23742;23738:9;23731:16;;23766:3;23763:1;23760:10;23757:36;;;23773:18;;:::i;:::-;23757:36;23609:191;;;;:::o;23806:169::-;23946:21;23942:1;23934:6;23930:14;23923:45;23806:169;:::o;23981:366::-;24123:3;24144:67;24208:2;24203:3;24144:67;:::i;:::-;24137:74;;24220:93;24309:3;24220:93;:::i;:::-;24338:2;24333:3;24329:12;24322:19;;23981:366;;;:::o;24353:419::-;24519:4;24557:2;24546:9;24542:18;24534:26;;24606:9;24600:4;24596:20;24592:1;24581:9;24577:17;24570:47;24634:131;24760:4;24634:131;:::i;:::-;24626:139;;24353:419;;;:::o;24778:188::-;24816:3;24835:18;24851:1;24835:18;:::i;:::-;24830:23;;24867:18;24883:1;24867:18;:::i;:::-;24862:23;;24908:1;24905;24901:9;24894:16;;24931:4;24926:3;24923:13;24920:39;;;24939:18;;:::i;:::-;24920:39;24778:188;;;;:::o;24972:141::-;25021:4;25044:3;25036:11;;25067:3;25064:1;25057:14;25101:4;25098:1;25088:18;25080:26;;24972:141;;;:::o;25119:93::-;25156:6;25203:2;25198;25191:5;25187:14;25183:23;25173:33;;25119:93;;;:::o;25218:107::-;25262:8;25312:5;25306:4;25302:16;25281:37;;25218:107;;;;:::o;25331:393::-;25400:6;25450:1;25438:10;25434:18;25473:97;25503:66;25492:9;25473:97;:::i;:::-;25591:39;25621:8;25610:9;25591:39;:::i;:::-;25579:51;;25663:4;25659:9;25652:5;25648:21;25639:30;;25712:4;25702:8;25698:19;25691:5;25688:30;25678:40;;25407:317;;25331:393;;;;;:::o;25730:60::-;25758:3;25779:5;25772:12;;25730:60;;;:::o;25796:142::-;25846:9;25879:53;25897:34;25906:24;25924:5;25906:24;:::i;:::-;25897:34;:::i;:::-;25879:53;:::i;:::-;25866:66;;25796:142;;;:::o;25944:75::-;25987:3;26008:5;26001:12;;25944:75;;;:::o;26025:269::-;26135:39;26166:7;26135:39;:::i;:::-;26196:91;26245:41;26269:16;26245:41;:::i;:::-;26237:6;26230:4;26224:11;26196:91;:::i;:::-;26190:4;26183:105;26101:193;26025:269;;;:::o;26300:73::-;26345:3;26300:73;:::o;26379:189::-;26456:32;;:::i;:::-;26497:65;26555:6;26547;26541:4;26497:65;:::i;:::-;26432:136;26379:189;;:::o;26574:186::-;26634:120;26651:3;26644:5;26641:14;26634:120;;;26705:39;26742:1;26735:5;26705:39;:::i;:::-;26678:1;26671:5;26667:13;26658:22;;26634:120;;;26574:186;;:::o;26766:543::-;26867:2;26862:3;26859:11;26856:446;;;26901:38;26933:5;26901:38;:::i;:::-;26985:29;27003:10;26985:29;:::i;:::-;26975:8;26971:44;27168:2;27156:10;27153:18;27150:49;;;27189:8;27174:23;;27150:49;27212:80;27268:22;27286:3;27268:22;:::i;:::-;27258:8;27254:37;27241:11;27212:80;:::i;:::-;26871:431;;26856:446;26766:543;;;:::o;27315:117::-;27369:8;27419:5;27413:4;27409:16;27388:37;;27315:117;;;;:::o;27438:169::-;27482:6;27515:51;27563:1;27559:6;27551:5;27548:1;27544:13;27515:51;:::i;:::-;27511:56;27596:4;27590;27586:15;27576:25;;27489:118;27438:169;;;;:::o;27612:295::-;27688:4;27834:29;27859:3;27853:4;27834:29;:::i;:::-;27826:37;;27896:3;27893:1;27889:11;27883:4;27880:21;27872:29;;27612:295;;;;:::o;27912:1395::-;28029:37;28062:3;28029:37;:::i;:::-;28131:18;28123:6;28120:30;28117:56;;;28153:18;;:::i;:::-;28117:56;28197:38;28229:4;28223:11;28197:38;:::i;:::-;28282:67;28342:6;28334;28328:4;28282:67;:::i;:::-;28376:1;28400:4;28387:17;;28432:2;28424:6;28421:14;28449:1;28444:618;;;;29106:1;29123:6;29120:77;;;29172:9;29167:3;29163:19;29157:26;29148:35;;29120:77;29223:67;29283:6;29276:5;29223:67;:::i;:::-;29217:4;29210:81;29079:222;28414:887;;28444:618;28496:4;28492:9;28484:6;28480:22;28530:37;28562:4;28530:37;:::i;:::-;28589:1;28603:208;28617:7;28614:1;28611:14;28603:208;;;28696:9;28691:3;28687:19;28681:26;28673:6;28666:42;28747:1;28739:6;28735:14;28725:24;;28794:2;28783:9;28779:18;28766:31;;28640:4;28637:1;28633:12;28628:17;;28603:208;;;28839:6;28830:7;28827:19;28824:179;;;28897:9;28892:3;28888:19;28882:26;28940:48;28982:4;28974:6;28970:17;28959:9;28940:48;:::i;:::-;28932:6;28925:64;28847:156;28824:179;29049:1;29045;29037:6;29033:14;29029:22;29023:4;29016:36;28451:611;;;28414:887;;28004:1303;;;27912:1395;;:::o;29313:169::-;29453:21;29449:1;29441:6;29437:14;29430:45;29313:169;:::o;29488:366::-;29630:3;29651:67;29715:2;29710:3;29651:67;:::i;:::-;29644:74;;29727:93;29816:3;29727:93;:::i;:::-;29845:2;29840:3;29836:12;29829:19;;29488:366;;;:::o;29860:419::-;30026:4;30064:2;30053:9;30049:18;30041:26;;30113:9;30107:4;30103:20;30099:1;30088:9;30084:17;30077:47;30141:131;30267:4;30141:131;:::i;:::-;30133:139;;29860:419;;;:::o;30285:160::-;30425:12;30421:1;30413:6;30409:14;30402:36;30285:160;:::o;30451:366::-;30593:3;30614:67;30678:2;30673:3;30614:67;:::i;:::-;30607:74;;30690:93;30779:3;30690:93;:::i;:::-;30808:2;30803:3;30799:12;30792:19;;30451:366;;;:::o;30823:419::-;30989:4;31027:2;31016:9;31012:18;31004:26;;31076:9;31070:4;31066:20;31062:1;31051:9;31047:17;31040:47;31104:131;31230:4;31104:131;:::i;:::-;31096:139;;30823:419;;;:::o;31248:176::-;31388:28;31384:1;31376:6;31372:14;31365:52;31248:176;:::o;31430:366::-;31572:3;31593:67;31657:2;31652:3;31593:67;:::i;:::-;31586:74;;31669:93;31758:3;31669:93;:::i;:::-;31787:2;31782:3;31778:12;31771:19;;31430:366;;;:::o;31802:419::-;31968:4;32006:2;31995:9;31991:18;31983:26;;32055:9;32049:4;32045:20;32041:1;32030:9;32026:17;32019:47;32083:131;32209:4;32083:131;:::i;:::-;32075:139;;31802:419;;;:::o;32227:166::-;32367:18;32363:1;32355:6;32351:14;32344:42;32227:166;:::o;32399:366::-;32541:3;32562:67;32626:2;32621:3;32562:67;:::i;:::-;32555:74;;32638:93;32727:3;32638:93;:::i;:::-;32756:2;32751:3;32747:12;32740:19;;32399:366;;;:::o;32771:419::-;32937:4;32975:2;32964:9;32960:18;32952:26;;33024:9;33018:4;33014:20;33010:1;32999:9;32995:17;32988:47;33052:131;33178:4;33052:131;:::i;:::-;33044:139;;32771:419;;;:::o;33196:173::-;33336:25;33332:1;33324:6;33320:14;33313:49;33196:173;:::o;33375:366::-;33517:3;33538:67;33602:2;33597:3;33538:67;:::i;:::-;33531:74;;33614:93;33703:3;33614:93;:::i;:::-;33732:2;33727:3;33723:12;33716:19;;33375:366;;;:::o;33747:419::-;33913:4;33951:2;33940:9;33936:18;33928:26;;34000:9;33994:4;33990:20;33986:1;33975:9;33971:17;33964:47;34028:131;34154:4;34028:131;:::i;:::-;34020:139;;33747:419;;;:::o;34172:180::-;34220:77;34217:1;34210:88;34317:4;34314:1;34307:15;34341:4;34338:1;34331:15;34358:113;34424:6;34458:5;34452:12;34442:22;;34358:113;;;:::o;34477:183::-;34575:11;34609:6;34604:3;34597:19;34649:4;34644:3;34640:14;34625:29;;34477:183;;;;:::o;34666:131::-;34732:4;34755:3;34747:11;;34785:4;34780:3;34776:14;34768:22;;34666:131;;;:::o;34803:105::-;34878:23;34895:5;34878:23;:::i;:::-;34873:3;34866:36;34803:105;;:::o;34914:175::-;34981:10;35002:44;35042:3;35034:6;35002:44;:::i;:::-;35078:4;35073:3;35069:14;35055:28;;34914:175;;;;:::o;35095:112::-;35164:4;35196;35191:3;35187:14;35179:22;;35095:112;;;:::o;35241:724::-;35358:3;35387:53;35434:5;35387:53;:::i;:::-;35456:85;35534:6;35529:3;35456:85;:::i;:::-;35449:92;;35565:55;35614:5;35565:55;:::i;:::-;35643:7;35674:1;35659:281;35684:6;35681:1;35678:13;35659:281;;;35760:6;35754:13;35787:61;35844:3;35829:13;35787:61;:::i;:::-;35780:68;;35871:59;35923:6;35871:59;:::i;:::-;35861:69;;35719:221;35706:1;35703;35699:9;35694:14;;35659:281;;;35663:14;35956:3;35949:10;;35363:602;;;35241:724;;;;:::o;35971:479::-;36140:4;36178:2;36167:9;36163:18;36155:26;;36191:71;36259:1;36248:9;36244:17;36235:6;36191:71;:::i;:::-;36309:9;36303:4;36299:20;36294:2;36283:9;36279:18;36272:48;36337:106;36438:4;36429:6;36337:106;:::i;:::-;36329:114;;35971:479;;;;;:::o;36456:169::-;36596:21;36592:1;36584:6;36580:14;36573:45;36456:169;:::o;36631:366::-;36773:3;36794:67;36858:2;36853:3;36794:67;:::i;:::-;36787:74;;36870:93;36959:3;36870:93;:::i;:::-;36988:2;36983:3;36979:12;36972:19;;36631:366;;;:::o;37003:419::-;37169:4;37207:2;37196:9;37192:18;37184:26;;37256:9;37250:4;37246:20;37242:1;37231:9;37227:17;37220:47;37284:131;37410:4;37284:131;:::i;:::-;37276:139;;37003:419;;;:::o;37428:176::-;37568:28;37564:1;37556:6;37552:14;37545:52;37428:176;:::o;37610:366::-;37752:3;37773:67;37837:2;37832:3;37773:67;:::i;:::-;37766:74;;37849:93;37938:3;37849:93;:::i;:::-;37967:2;37962:3;37958:12;37951:19;;37610:366;;;:::o;37982:419::-;38148:4;38186:2;38175:9;38171:18;38163:26;;38235:9;38229:4;38225:20;38221:1;38210:9;38206:17;38199:47;38263:131;38389:4;38263:131;:::i;:::-;38255:139;;37982:419;;;:::o;38407:229::-;38547:34;38543:1;38535:6;38531:14;38524:58;38616:12;38611:2;38603:6;38599:15;38592:37;38407:229;:::o;38642:366::-;38784:3;38805:67;38869:2;38864:3;38805:67;:::i;:::-;38798:74;;38881:93;38970:3;38881:93;:::i;:::-;38999:2;38994:3;38990:12;38983:19;;38642:366;;;:::o;39014:419::-;39180:4;39218:2;39207:9;39203:18;39195:26;;39267:9;39261:4;39257:20;39253:1;39242:9;39238:17;39231:47;39295:131;39421:4;39295:131;:::i;:::-;39287:139;;39014:419;;;:::o;39439:168::-;39579:20;39575:1;39567:6;39563:14;39556:44;39439:168;:::o;39613:366::-;39755:3;39776:67;39840:2;39835:3;39776:67;:::i;:::-;39769:74;;39852:93;39941:3;39852:93;:::i;:::-;39970:2;39965:3;39961:12;39954:19;;39613:366;;;:::o;39985:419::-;40151:4;40189:2;40178:9;40174:18;40166:26;;40238:9;40232:4;40228:20;40224:1;40213:9;40209:17;40202:47;40266:131;40392:4;40266:131;:::i;:::-;40258:139;;39985:419;;;:::o;40410:175::-;40550:27;40546:1;40538:6;40534:14;40527:51;40410:175;:::o;40591:366::-;40733:3;40754:67;40818:2;40813:3;40754:67;:::i;:::-;40747:74;;40830:93;40919:3;40830:93;:::i;:::-;40948:2;40943:3;40939:12;40932:19;;40591:366;;;:::o;40963:419::-;41129:4;41167:2;41156:9;41152:18;41144:26;;41216:9;41210:4;41206:20;41202:1;41191:9;41187:17;41180:47;41244:131;41370:4;41244:131;:::i;:::-;41236:139;;40963:419;;;:::o;41388:162::-;41528:14;41524:1;41516:6;41512:14;41505:38;41388:162;:::o;41556:366::-;41698:3;41719:67;41783:2;41778:3;41719:67;:::i;:::-;41712:74;;41795:93;41884:3;41795:93;:::i;:::-;41913:2;41908:3;41904:12;41897:19;;41556:366;;;:::o;41928:419::-;42094:4;42132:2;42121:9;42117:18;42109:26;;42181:9;42175:4;42171:20;42167:1;42156:9;42152:17;42145:47;42209:131;42335:4;42209:131;:::i;:::-;42201:139;;41928:419;;;:::o;42353:148::-;42455:11;42492:3;42477:18;;42353:148;;;;:::o;42507:390::-;42613:3;42641:39;42674:5;42641:39;:::i;:::-;42696:89;42778:6;42773:3;42696:89;:::i;:::-;42689:96;;42794:65;42852:6;42847:3;42840:4;42833:5;42829:16;42794:65;:::i;:::-;42884:6;42879:3;42875:16;42868:23;;42617:280;42507:390;;;;:::o;42903:435::-;43083:3;43105:95;43196:3;43187:6;43105:95;:::i;:::-;43098:102;;43217:95;43308:3;43299:6;43217:95;:::i;:::-;43210:102;;43329:3;43322:10;;42903:435;;;;;:::o;43344:79::-;43383:7;43412:5;43401:16;;43344:79;;;:::o;43429:157::-;43534:45;43554:24;43572:5;43554:24;:::i;:::-;43534:45;:::i;:::-;43529:3;43522:58;43429:157;;:::o;43592:397::-;43732:3;43747:75;43818:3;43809:6;43747:75;:::i;:::-;43847:2;43842:3;43838:12;43831:19;;43860:75;43931:3;43922:6;43860:75;:::i;:::-;43960:2;43955:3;43951:12;43944:19;;43980:3;43973:10;;43592:397;;;;;:::o;43995:171::-;44034:3;44057:24;44075:5;44057:24;:::i;:::-;44048:33;;44103:4;44096:5;44093:15;44090:41;;44111:18;;:::i;:::-;44090:41;44158:1;44151:5;44147:13;44140:20;;43995:171;;;:::o;44172:180::-;44220:77;44217:1;44210:88;44317:4;44314:1;44307:15;44341:4;44338:1;44331:15;44358:197;44397:3;44416:19;44433:1;44416:19;:::i;:::-;44411:24;;44449:19;44466:1;44449:19;:::i;:::-;44444:24;;44491:1;44488;44484:9;44477:16;;44514:10;44509:3;44506:19;44503:45;;;44528:18;;:::i;:::-;44503:45;44358:197;;;;:::o
Swarm Source
ipfs://e90b78fd1e48f9522ce04e38979dd9b18bffed2f6a6e775afd6152c433fa7509
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.