Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
Overview
Max Total Supply
2,706 ECN
Holders
613
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
5 ECNLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
ElchaiCarClubCardNFT
Compiler Version
v0.8.7+commit.e28d00a7
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-01-29 */ // SPDX-License-Identifier: MIT // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: erc721a/contracts/IERC721A.sol // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); } // File: erc721a/contracts/ERC721A.sol // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 1; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr) if (curr < _currentIndex) { uint256 packed = _packedOwnerships[curr]; // If not burned. if (packed & _BITMASK_BURNED == 0) { // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `curr` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) public payable virtual override { address owner = ownerOf(tokenId); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned. } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 toMasked; uint256 end = startTokenId + quantity; // Use assembly to loop and emit the `Transfer` event for gas savings. // The duplicated `log4` removes an extra check and reduces stack juggling. // The assembly, together with the surrounding Solidity code, have been // delicately arranged to nudge the compiler into producing optimized opcodes. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. startTokenId // `tokenId`. ) // The `iszero(eq(,))` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. // The compiler will optimize the `iszero` away for performance. for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } if (toMasked == 0) revert MintToZeroAddress(); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } } // File: ElchaiCarClubCardNFT.sol pragma solidity ^0.8.7; contract ElchaiCarClubCardNFT is ERC721A, Ownable { using Strings for uint256; //declares the maximum amount of tokens that can be minted uint256 private max_nft_supply = 10000; //maximum amount of mints allowed per person uint256 public max_nft_per_wallet = 5; //amount of mints that each address has executed mapping(address => uint256) public mintsPerAddress; //dictates if sale is paused or not bool public saleIsActive = false; //initial part of the URI for the metadata string public baseTokenURI; //the amount of reserved mints that have currently been executed by creator and giveaways uint private _reservedMints = 0; //the maximum amount of reserved mints allowed for creator and giveaways uint private maxReservedMints = 6400; // extention string public baseURLExtention = ".json"; // terms and conditions URL string public termsAndConditionURL = "https://elchaicarclub.com/nft/card-nft"; constructor(string memory _uri) ERC721A("Elchai Card NFT", "ECN") { baseTokenURI =_uri; } //reserved NFTs for creator function reservedMint(uint256 numberOfNFT, address recipient) public onlyOwner { require( totalSupply()+ numberOfNFT <= max_nft_supply, "Reserve nft would exceed max supply of NFTs"); _safeMint(recipient, numberOfNFT); mintsPerAddress[recipient] += numberOfNFT; _reservedMints +=_reservedMints; } // public minting function mint(uint256 numberOfNFT) public { require(saleIsActive, "Public Sale in not open yet!"); require(totalSupply() + numberOfNFT <= max_nft_supply - maxReservedMints, "Not enough NFTs left to mint.."); require(balanceOf(msg.sender) + numberOfNFT <= max_nft_per_wallet, "Purchase exceeds max allowed per wallet"); _safeMint(msg.sender, numberOfNFT); mintsPerAddress[msg.sender] += numberOfNFT; } function tokenURI(uint256 tokenId_) public view virtual override returns (string memory) { require(_exists(tokenId_), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId_.toString(), baseURLExtention)) : ""; } function setMaxReservedMints(uint256 _newReserveNFT) public onlyOwner { maxReservedMints = _newReserveNFT; } function freezeMinting() public onlyOwner { max_nft_supply = totalSupply(); } //se the current account balance function accountBalance() public onlyOwner view returns(uint) { return address(this).balance; } //retrieve all funds recieved from minting function withdraw() public onlyOwner { uint256 balance = accountBalance(); require(balance > 0, 'No Funds to withdraw, Balance is 0'); _withdraw(payable(address(this)), balance); } //send the percentage of funds to a shareholder´s wallet function _withdraw(address payable account, uint256 amount) internal { (bool sent, ) = account.call{value: amount}(""); require(sent, "Failed to send Ether"); } //update terms and conditions URL function setTermsAndConditionURL(string memory _termsAndConditionURL) public onlyOwner { termsAndConditionURL = _termsAndConditionURL; } //change baseURI in case needed for IPFS function setBaseURI(string memory baseURI) public onlyOwner { baseTokenURI = baseURI; } // change sale state function pause() public onlyOwner { saleIsActive = !saleIsActive; } function isPaused() public view returns(bool) { return saleIsActive; } //visualize baseURI function _baseURI() internal view virtual override returns (string memory) { return baseTokenURI; } // change sale state function nftsAvailabelForFreeMint() external view returns(uint256) { return (max_nft_supply - maxReservedMints - totalSupply()); } //in case somebody accidentaly sends funds or transaction to contract receive() payable external {} fallback() payable external { revert(); } function getMintsPerAddress(address _userAddr) external view returns(uint) { return mintsPerAddress[_userAddr]; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"accountBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURLExtention","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freezeMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddr","type":"address"}],"name":"getMintsPerAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"max_nft_per_wallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfNFT","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintsPerAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftsAvailabelForFreeMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfNFT","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"reservedMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newReserveNFT","type":"uint256"}],"name":"setMaxReservedMints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_termsAndConditionURL","type":"string"}],"name":"setTermsAndConditionURL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"termsAndConditionURL","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040526127106009556005600a556000600c60006101000a81548160ff0219169083151502179055506000600e55611900600f556040518060400160405280600581526020017f2e6a736f6e0000000000000000000000000000000000000000000000000000008152506010908051906020019062000082929190620002b5565b506040518060600160405280602681526020016200390d6026913960119080519060200190620000b4929190620002b5565b50348015620000c257600080fd5b5060405162003933380380620039338339818101604052810190620000e89190620003e3565b6040518060400160405280600f81526020017f456c636861692043617264204e465400000000000000000000000000000000008152506040518060400160405280600381526020017f45434e000000000000000000000000000000000000000000000000000000000081525081600290805190602001906200016c929190620002b5565b50806003908051906020019062000185929190620002b5565b5062000196620001de60201b60201c565b6000819055505050620001be620001b2620001e760201b60201c565b620001ef60201b60201c565b80600d9080519060200190620001d6929190620002b5565b5050620005b8565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620002c390620004c9565b90600052602060002090601f016020900481019282620002e7576000855562000333565b82601f106200030257805160ff191683800117855562000333565b8280016001018555821562000333579182015b828111156200033257825182559160200191906001019062000315565b5b50905062000342919062000346565b5090565b5b808211156200036157600081600090555060010162000347565b5090565b60006200037c62000376846200045d565b62000434565b9050828152602081018484840111156200039b576200039a62000598565b5b620003a884828562000493565b509392505050565b600082601f830112620003c857620003c762000593565b5b8151620003da84826020860162000365565b91505092915050565b600060208284031215620003fc57620003fb620005a2565b5b600082015167ffffffffffffffff8111156200041d576200041c6200059d565b5b6200042b84828501620003b0565b91505092915050565b60006200044062000453565b90506200044e8282620004ff565b919050565b6000604051905090565b600067ffffffffffffffff8211156200047b576200047a62000564565b5b6200048682620005a7565b9050602081019050919050565b60005b83811015620004b357808201518184015260208101905062000496565b83811115620004c3576000848401525b50505050565b60006002820490506001821680620004e257607f821691505b60208210811415620004f957620004f862000535565b5b50919050565b6200050a82620005a7565b810181811067ffffffffffffffff821117156200052c576200052b62000564565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b61334580620005c86000396000f3fe6080604052600436106102085760003560e01c80638da5cb5b11610118578063c2b03670116100a0578063eb8d24441161006f578063eb8d244414610706578063f0a9e05614610731578063f2fde38b1461075c578063f71e7e2814610785578063fae96571146107ae5761020f565b8063c2b0367014610638578063c87b56dd14610661578063d547cfb71461069e578063e985e9c5146106c95761020f565b8063a22cb465116100e7578063a22cb46514610586578063b0a1c1c4146105af578063b187bd26146105da578063b88d4fde14610605578063c013f30f146106215761020f565b80638da5cb5b146104dc57806390d325851461050757806395d89b4114610532578063a0712d681461055d5761020f565b8063349654dc1161019b57806355f804b31161016a57806355f804b31461040b5780636352211e1461043457806370a0823114610471578063715018a6146104ae5780638456cb59146104c55761020f565b8063349654dc146103825780633ccfd60b146103ad57806342842e0e146103c45780635470b32e146103e05761020f565b806318160ddd116101d757806318160ddd146102d557806318df64031461030057806323b872dd146103295780633023eba6146103455761020f565b806301ffc9a71461021457806306fdde0314610251578063081812fc1461027c578063095ea7b3146102b95761020f565b3661020f57005b600080fd5b34801561022057600080fd5b5061023b60048036038101906102369190612731565b6107eb565b6040516102489190612b9b565b60405180910390f35b34801561025d57600080fd5b5061026661087d565b6040516102739190612bb6565b60405180910390f35b34801561028857600080fd5b506102a3600480360381019061029e91906127d4565b61090f565b6040516102b09190612b34565b60405180910390f35b6102d360048036038101906102ce91906126f1565b61098e565b005b3480156102e157600080fd5b506102ea610ad2565b6040516102f79190612cf8565b60405180910390f35b34801561030c57600080fd5b5061032760048036038101906103229190612801565b610ae9565b005b610343600480360381019061033e91906125db565b610bc7565b005b34801561035157600080fd5b5061036c6004803603810190610367919061256e565b610eec565b6040516103799190612cf8565b60405180910390f35b34801561038e57600080fd5b50610397610f04565b6040516103a49190612cf8565b60405180910390f35b3480156103b957600080fd5b506103c2610f2d565b005b6103de60048036038101906103d991906125db565b610f91565b005b3480156103ec57600080fd5b506103f5610fb1565b6040516104029190612bb6565b60405180910390f35b34801561041757600080fd5b50610432600480360381019061042d919061278b565b61103f565b005b34801561044057600080fd5b5061045b600480360381019061045691906127d4565b611061565b6040516104689190612b34565b60405180910390f35b34801561047d57600080fd5b506104986004803603810190610493919061256e565b611073565b6040516104a59190612cf8565b60405180910390f35b3480156104ba57600080fd5b506104c361112c565b005b3480156104d157600080fd5b506104da611140565b005b3480156104e857600080fd5b506104f1611174565b6040516104fe9190612b34565b60405180910390f35b34801561051357600080fd5b5061051c61119e565b6040516105299190612bb6565b60405180910390f35b34801561053e57600080fd5b5061054761122c565b6040516105549190612bb6565b60405180910390f35b34801561056957600080fd5b50610584600480360381019061057f91906127d4565b6112be565b005b34801561059257600080fd5b506105ad60048036038101906105a891906126b1565b61142c565b005b3480156105bb57600080fd5b506105c4611537565b6040516105d19190612cf8565b60405180910390f35b3480156105e657600080fd5b506105ef611547565b6040516105fc9190612b9b565b60405180910390f35b61061f600480360381019061061a919061262e565b61155e565b005b34801561062d57600080fd5b506106366115d1565b005b34801561064457600080fd5b5061065f600480360381019061065a91906127d4565b6115e9565b005b34801561066d57600080fd5b50610688600480360381019061068391906127d4565b6115fb565b6040516106959190612bb6565b60405180910390f35b3480156106aa57600080fd5b506106b36116a5565b6040516106c09190612bb6565b60405180910390f35b3480156106d557600080fd5b506106f060048036038101906106eb919061259b565b611733565b6040516106fd9190612b9b565b60405180910390f35b34801561071257600080fd5b5061071b6117c7565b6040516107289190612b9b565b60405180910390f35b34801561073d57600080fd5b506107466117da565b6040516107539190612cf8565b60405180910390f35b34801561076857600080fd5b50610783600480360381019061077e919061256e565b6117e0565b005b34801561079157600080fd5b506107ac60048036038101906107a7919061278b565b611864565b005b3480156107ba57600080fd5b506107d560048036038101906107d0919061256e565b611886565b6040516107e29190612cf8565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061084657506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108765750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461088c90612f3d565b80601f01602080910402602001604051908101604052809291908181526020018280546108b890612f3d565b80156109055780601f106108da57610100808354040283529160200191610905565b820191906000526020600020905b8154815290600101906020018083116108e857829003601f168201915b5050505050905090565b600061091a826118cf565b610950576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061099982611061565b90508073ffffffffffffffffffffffffffffffffffffffff166109ba61192e565b73ffffffffffffffffffffffffffffffffffffffff1614610a1d576109e6816109e161192e565b611733565b610a1c576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610adc611936565b6001546000540303905090565b610af161193f565b60095482610afd610ad2565b610b079190612dfd565b1115610b48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3f90612c38565b60405180910390fd5b610b5281836119bd565b81600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610ba19190612dfd565b92505081905550600e54600e6000828254610bbc9190612dfd565b925050819055505050565b6000610bd2826119db565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c39576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610c4584611aa9565b91509150610c5b8187610c5661192e565b611ad0565b610ca757610c7086610c6b61192e565b611733565b610ca6576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610d0e576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d1b8686866001611b14565b8015610d2657600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610df485610dd0888887611b1a565b7c020000000000000000000000000000000000000000000000000000000017611b42565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084161415610e7c576000600185019050600060046000838152602001908152602001600020541415610e7a576000548114610e79578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610ee48686866001611b6d565b505050505050565b600b6020528060005260406000206000915090505481565b6000610f0e610ad2565b600f54600954610f1e9190612e53565b610f289190612e53565b905090565b610f3561193f565b6000610f3f611537565b905060008111610f84576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7b90612cb8565b60405180910390fd5b610f8e3082611b73565b50565b610fac8383836040518060200160405280600081525061155e565b505050565b60108054610fbe90612f3d565b80601f0160208091040260200160405190810160405280929190818152602001828054610fea90612f3d565b80156110375780601f1061100c57610100808354040283529160200191611037565b820191906000526020600020905b81548152906001019060200180831161101a57829003601f168201915b505050505081565b61104761193f565b80600d908051906020019061105d929190612382565b5050565b600061106c826119db565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156110db576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61113461193f565b61113e6000611c24565b565b61114861193f565b600c60009054906101000a900460ff1615600c60006101000a81548160ff021916908315150217905550565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b601180546111ab90612f3d565b80601f01602080910402602001604051908101604052809291908181526020018280546111d790612f3d565b80156112245780601f106111f957610100808354040283529160200191611224565b820191906000526020600020905b81548152906001019060200180831161120757829003601f168201915b505050505081565b60606003805461123b90612f3d565b80601f016020809104026020016040519081016040528092919081815260200182805461126790612f3d565b80156112b45780601f10611289576101008083540402835291602001916112b4565b820191906000526020600020905b81548152906001019060200180831161129757829003601f168201915b5050505050905090565b600c60009054906101000a900460ff1661130d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130490612c58565b60405180910390fd5b600f5460095461131d9190612e53565b81611326610ad2565b6113309190612dfd565b1115611371576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136890612c18565b60405180910390fd5b600a548161137e33611073565b6113889190612dfd565b11156113c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c090612cd8565b60405180910390fd5b6113d333826119bd565b80600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546114229190612dfd565b9250508190555050565b806007600061143961192e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166114e661192e565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161152b9190612b9b565b60405180910390a35050565b600061154161193f565b47905090565b6000600c60009054906101000a900460ff16905090565b611569848484610bc7565b60008373ffffffffffffffffffffffffffffffffffffffff163b146115cb5761159484848484611cea565b6115ca576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6115d961193f565b6115e1610ad2565b600981905550565b6115f161193f565b80600f8190555050565b6060611606826118cf565b611645576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161163c90612c98565b60405180910390fd5b600061164f611e4a565b9050600081511161166f576040518060200160405280600081525061169d565b8061167984611edc565b601060405160200161168d93929190612aee565b6040516020818303038152906040525b915050919050565b600d80546116b290612f3d565b80601f01602080910402602001604051908101604052809291908181526020018280546116de90612f3d565b801561172b5780601f106117005761010080835404028352916020019161172b565b820191906000526020600020905b81548152906001019060200180831161170e57829003601f168201915b505050505081565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600c60009054906101000a900460ff1681565b600a5481565b6117e861193f565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611858576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161184f90612bd8565b60405180910390fd5b61186181611c24565b50565b61186c61193f565b8060119080519060200190611882929190612382565b5050565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000816118da611936565b111580156118e9575060005482105b8015611927575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b611947611fb4565b73ffffffffffffffffffffffffffffffffffffffff16611965611174565b73ffffffffffffffffffffffffffffffffffffffff16146119bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119b290612c78565b60405180910390fd5b565b6119d7828260405180602001604052806000815250611fbc565b5050565b600080829050806119ea611936565b11611a7257600054811015611a715760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082161415611a6f575b6000811415611a65576004600083600190039350838152602001908152602001600020549050611a3a565b8092505050611aa4565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611b31868684612059565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b60008273ffffffffffffffffffffffffffffffffffffffff1682604051611b9990612b1f565b60006040518083038185875af1925050503d8060008114611bd6576040519150601f19603f3d011682016040523d82523d6000602084013e611bdb565b606091505b5050905080611c1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c1690612bf8565b60405180910390fd5b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611d1061192e565b8786866040518563ffffffff1660e01b8152600401611d329493929190612b4f565b602060405180830381600087803b158015611d4c57600080fd5b505af1925050508015611d7d57506040513d601f19601f82011682018060405250810190611d7a919061275e565b60015b611df7573d8060008114611dad576040519150601f19603f3d011682016040523d82523d6000602084013e611db2565b606091505b50600081511415611def576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600d8054611e5990612f3d565b80601f0160208091040260200160405190810160405280929190818152602001828054611e8590612f3d565b8015611ed25780601f10611ea757610100808354040283529160200191611ed2565b820191906000526020600020905b815481529060010190602001808311611eb557829003601f168201915b5050505050905090565b606060006001611eeb84612062565b01905060008167ffffffffffffffff811115611f0a57611f0961302d565b5b6040519080825280601f01601f191660200182016040528015611f3c5781602001600182028036833780820191505090505b509050600082602001820190505b600115611fa9578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611f9357611f92612fcf565b5b0494506000851415611fa457611fa9565b611f4a565b819350505050919050565b600033905090565b611fc683836121b5565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461205457600080549050600083820390505b6120066000868380600101945086611cea565b61203c576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110611ff357816000541461205157600080fd5b50505b505050565b60009392505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106120c0577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816120b6576120b5612fcf565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106120fd576d04ee2d6d415b85acef810000000083816120f3576120f2612fcf565b5b0492506020810190505b662386f26fc10000831061212c57662386f26fc10000838161212257612121612fcf565b5b0492506010810190505b6305f5e1008310612155576305f5e100838161214b5761214a612fcf565b5b0492506008810190505b612710831061217a5761271083816121705761216f612fcf565b5b0492506004810190505b6064831061219d576064838161219357612192612fcf565b5b0492506002810190505b600a83106121ac576001810190505b80915050919050565b60008054905060008214156121f6576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122036000848385611b14565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061227a8361226b6000866000611b1a565b61227485612372565b17611b42565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461231b57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001810190506122e0565b506000821415612357576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061236d6000848385611b6d565b505050565b60006001821460e11b9050919050565b82805461238e90612f3d565b90600052602060002090601f0160209004810192826123b057600085556123f7565b82601f106123c957805160ff19168380011785556123f7565b828001600101855582156123f7579182015b828111156123f65782518255916020019190600101906123db565b5b5090506124049190612408565b5090565b5b80821115612421576000816000905550600101612409565b5090565b600061243861243384612d38565b612d13565b90508281526020810184848401111561245457612453613061565b5b61245f848285612efb565b509392505050565b600061247a61247584612d69565b612d13565b90508281526020810184848401111561249657612495613061565b5b6124a1848285612efb565b509392505050565b6000813590506124b8816132b3565b92915050565b6000813590506124cd816132ca565b92915050565b6000813590506124e2816132e1565b92915050565b6000815190506124f7816132e1565b92915050565b600082601f8301126125125761251161305c565b5b8135612522848260208601612425565b91505092915050565b600082601f8301126125405761253f61305c565b5b8135612550848260208601612467565b91505092915050565b600081359050612568816132f8565b92915050565b6000602082840312156125845761258361306b565b5b6000612592848285016124a9565b91505092915050565b600080604083850312156125b2576125b161306b565b5b60006125c0858286016124a9565b92505060206125d1858286016124a9565b9150509250929050565b6000806000606084860312156125f4576125f361306b565b5b6000612602868287016124a9565b9350506020612613868287016124a9565b925050604061262486828701612559565b9150509250925092565b600080600080608085870312156126485761264761306b565b5b6000612656878288016124a9565b9450506020612667878288016124a9565b935050604061267887828801612559565b925050606085013567ffffffffffffffff81111561269957612698613066565b5b6126a5878288016124fd565b91505092959194509250565b600080604083850312156126c8576126c761306b565b5b60006126d6858286016124a9565b92505060206126e7858286016124be565b9150509250929050565b600080604083850312156127085761270761306b565b5b6000612716858286016124a9565b925050602061272785828601612559565b9150509250929050565b6000602082840312156127475761274661306b565b5b6000612755848285016124d3565b91505092915050565b6000602082840312156127745761277361306b565b5b6000612782848285016124e8565b91505092915050565b6000602082840312156127a1576127a061306b565b5b600082013567ffffffffffffffff8111156127bf576127be613066565b5b6127cb8482850161252b565b91505092915050565b6000602082840312156127ea576127e961306b565b5b60006127f884828501612559565b91505092915050565b600080604083850312156128185761281761306b565b5b600061282685828601612559565b9250506020612837858286016124a9565b9150509250929050565b61284a81612e87565b82525050565b61285981612e99565b82525050565b600061286a82612daf565b6128748185612dc5565b9350612884818560208601612f0a565b61288d81613070565b840191505092915050565b60006128a382612dba565b6128ad8185612de1565b93506128bd818560208601612f0a565b6128c681613070565b840191505092915050565b60006128dc82612dba565b6128e68185612df2565b93506128f6818560208601612f0a565b80840191505092915050565b6000815461290f81612f3d565b6129198186612df2565b94506001821660008114612934576001811461294557612978565b60ff19831686528186019350612978565b61294e85612d9a565b60005b8381101561297057815481890152600182019150602081019050612951565b838801955050505b50505092915050565b600061298e602683612de1565b915061299982613081565b604082019050919050565b60006129b1601483612de1565b91506129bc826130d0565b602082019050919050565b60006129d4601e83612de1565b91506129df826130f9565b602082019050919050565b60006129f7602b83612de1565b9150612a0282613122565b604082019050919050565b6000612a1a601c83612de1565b9150612a2582613171565b602082019050919050565b6000612a3d602083612de1565b9150612a488261319a565b602082019050919050565b6000612a60602f83612de1565b9150612a6b826131c3565b604082019050919050565b6000612a83600083612dd6565b9150612a8e82613212565b600082019050919050565b6000612aa6602283612de1565b9150612ab182613215565b604082019050919050565b6000612ac9602783612de1565b9150612ad482613264565b604082019050919050565b612ae881612ef1565b82525050565b6000612afa82866128d1565b9150612b0682856128d1565b9150612b128284612902565b9150819050949350505050565b6000612b2a82612a76565b9150819050919050565b6000602082019050612b496000830184612841565b92915050565b6000608082019050612b646000830187612841565b612b716020830186612841565b612b7e6040830185612adf565b8181036060830152612b90818461285f565b905095945050505050565b6000602082019050612bb06000830184612850565b92915050565b60006020820190508181036000830152612bd08184612898565b905092915050565b60006020820190508181036000830152612bf181612981565b9050919050565b60006020820190508181036000830152612c11816129a4565b9050919050565b60006020820190508181036000830152612c31816129c7565b9050919050565b60006020820190508181036000830152612c51816129ea565b9050919050565b60006020820190508181036000830152612c7181612a0d565b9050919050565b60006020820190508181036000830152612c9181612a30565b9050919050565b60006020820190508181036000830152612cb181612a53565b9050919050565b60006020820190508181036000830152612cd181612a99565b9050919050565b60006020820190508181036000830152612cf181612abc565b9050919050565b6000602082019050612d0d6000830184612adf565b92915050565b6000612d1d612d2e565b9050612d298282612f6f565b919050565b6000604051905090565b600067ffffffffffffffff821115612d5357612d5261302d565b5b612d5c82613070565b9050602081019050919050565b600067ffffffffffffffff821115612d8457612d8361302d565b5b612d8d82613070565b9050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612e0882612ef1565b9150612e1383612ef1565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612e4857612e47612fa0565b5b828201905092915050565b6000612e5e82612ef1565b9150612e6983612ef1565b925082821015612e7c57612e7b612fa0565b5b828203905092915050565b6000612e9282612ed1565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612f28578082015181840152602081019050612f0d565b83811115612f37576000848401525b50505050565b60006002820490506001821680612f5557607f821691505b60208210811415612f6957612f68612ffe565b5b50919050565b612f7882613070565b810181811067ffffffffffffffff82111715612f9757612f9661302d565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b7f4e6f7420656e6f756768204e465473206c65667420746f206d696e742e2e0000600082015250565b7f52657365727665206e667420776f756c6420657863656564206d61782073757060008201527f706c79206f66204e465473000000000000000000000000000000000000000000602082015250565b7f5075626c69632053616c6520696e206e6f74206f70656e207965742100000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b50565b7f4e6f2046756e647320746f2077697468647261772c2042616c616e636520697360008201527f2030000000000000000000000000000000000000000000000000000000000000602082015250565b7f50757263686173652065786365656473206d617820616c6c6f7765642070657260008201527f2077616c6c657400000000000000000000000000000000000000000000000000602082015250565b6132bc81612e87565b81146132c757600080fd5b50565b6132d381612e99565b81146132de57600080fd5b50565b6132ea81612ea5565b81146132f557600080fd5b50565b61330181612ef1565b811461330c57600080fd5b5056fea2646970667358221220da5b9cf395a9f1e9621dfeaf4afedd0a85718d51e8900563535f264abf44245d64736f6c6343000807003368747470733a2f2f656c63686169636172636c75622e636f6d2f6e66742f636172642d6e66740000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005968747470733a2f2f656c63686169636172636c75622e6d7970696e6174612e636c6f75642f697066732f516d5575516f4c774c6956755a71726269336732367150714667646f634458744e4a5546357156464843313751342f00000000000000
Deployed Bytecode
0x6080604052600436106102085760003560e01c80638da5cb5b11610118578063c2b03670116100a0578063eb8d24441161006f578063eb8d244414610706578063f0a9e05614610731578063f2fde38b1461075c578063f71e7e2814610785578063fae96571146107ae5761020f565b8063c2b0367014610638578063c87b56dd14610661578063d547cfb71461069e578063e985e9c5146106c95761020f565b8063a22cb465116100e7578063a22cb46514610586578063b0a1c1c4146105af578063b187bd26146105da578063b88d4fde14610605578063c013f30f146106215761020f565b80638da5cb5b146104dc57806390d325851461050757806395d89b4114610532578063a0712d681461055d5761020f565b8063349654dc1161019b57806355f804b31161016a57806355f804b31461040b5780636352211e1461043457806370a0823114610471578063715018a6146104ae5780638456cb59146104c55761020f565b8063349654dc146103825780633ccfd60b146103ad57806342842e0e146103c45780635470b32e146103e05761020f565b806318160ddd116101d757806318160ddd146102d557806318df64031461030057806323b872dd146103295780633023eba6146103455761020f565b806301ffc9a71461021457806306fdde0314610251578063081812fc1461027c578063095ea7b3146102b95761020f565b3661020f57005b600080fd5b34801561022057600080fd5b5061023b60048036038101906102369190612731565b6107eb565b6040516102489190612b9b565b60405180910390f35b34801561025d57600080fd5b5061026661087d565b6040516102739190612bb6565b60405180910390f35b34801561028857600080fd5b506102a3600480360381019061029e91906127d4565b61090f565b6040516102b09190612b34565b60405180910390f35b6102d360048036038101906102ce91906126f1565b61098e565b005b3480156102e157600080fd5b506102ea610ad2565b6040516102f79190612cf8565b60405180910390f35b34801561030c57600080fd5b5061032760048036038101906103229190612801565b610ae9565b005b610343600480360381019061033e91906125db565b610bc7565b005b34801561035157600080fd5b5061036c6004803603810190610367919061256e565b610eec565b6040516103799190612cf8565b60405180910390f35b34801561038e57600080fd5b50610397610f04565b6040516103a49190612cf8565b60405180910390f35b3480156103b957600080fd5b506103c2610f2d565b005b6103de60048036038101906103d991906125db565b610f91565b005b3480156103ec57600080fd5b506103f5610fb1565b6040516104029190612bb6565b60405180910390f35b34801561041757600080fd5b50610432600480360381019061042d919061278b565b61103f565b005b34801561044057600080fd5b5061045b600480360381019061045691906127d4565b611061565b6040516104689190612b34565b60405180910390f35b34801561047d57600080fd5b506104986004803603810190610493919061256e565b611073565b6040516104a59190612cf8565b60405180910390f35b3480156104ba57600080fd5b506104c361112c565b005b3480156104d157600080fd5b506104da611140565b005b3480156104e857600080fd5b506104f1611174565b6040516104fe9190612b34565b60405180910390f35b34801561051357600080fd5b5061051c61119e565b6040516105299190612bb6565b60405180910390f35b34801561053e57600080fd5b5061054761122c565b6040516105549190612bb6565b60405180910390f35b34801561056957600080fd5b50610584600480360381019061057f91906127d4565b6112be565b005b34801561059257600080fd5b506105ad60048036038101906105a891906126b1565b61142c565b005b3480156105bb57600080fd5b506105c4611537565b6040516105d19190612cf8565b60405180910390f35b3480156105e657600080fd5b506105ef611547565b6040516105fc9190612b9b565b60405180910390f35b61061f600480360381019061061a919061262e565b61155e565b005b34801561062d57600080fd5b506106366115d1565b005b34801561064457600080fd5b5061065f600480360381019061065a91906127d4565b6115e9565b005b34801561066d57600080fd5b50610688600480360381019061068391906127d4565b6115fb565b6040516106959190612bb6565b60405180910390f35b3480156106aa57600080fd5b506106b36116a5565b6040516106c09190612bb6565b60405180910390f35b3480156106d557600080fd5b506106f060048036038101906106eb919061259b565b611733565b6040516106fd9190612b9b565b60405180910390f35b34801561071257600080fd5b5061071b6117c7565b6040516107289190612b9b565b60405180910390f35b34801561073d57600080fd5b506107466117da565b6040516107539190612cf8565b60405180910390f35b34801561076857600080fd5b50610783600480360381019061077e919061256e565b6117e0565b005b34801561079157600080fd5b506107ac60048036038101906107a7919061278b565b611864565b005b3480156107ba57600080fd5b506107d560048036038101906107d0919061256e565b611886565b6040516107e29190612cf8565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061084657506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108765750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461088c90612f3d565b80601f01602080910402602001604051908101604052809291908181526020018280546108b890612f3d565b80156109055780601f106108da57610100808354040283529160200191610905565b820191906000526020600020905b8154815290600101906020018083116108e857829003601f168201915b5050505050905090565b600061091a826118cf565b610950576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061099982611061565b90508073ffffffffffffffffffffffffffffffffffffffff166109ba61192e565b73ffffffffffffffffffffffffffffffffffffffff1614610a1d576109e6816109e161192e565b611733565b610a1c576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610adc611936565b6001546000540303905090565b610af161193f565b60095482610afd610ad2565b610b079190612dfd565b1115610b48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3f90612c38565b60405180910390fd5b610b5281836119bd565b81600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610ba19190612dfd565b92505081905550600e54600e6000828254610bbc9190612dfd565b925050819055505050565b6000610bd2826119db565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c39576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610c4584611aa9565b91509150610c5b8187610c5661192e565b611ad0565b610ca757610c7086610c6b61192e565b611733565b610ca6576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610d0e576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d1b8686866001611b14565b8015610d2657600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610df485610dd0888887611b1a565b7c020000000000000000000000000000000000000000000000000000000017611b42565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084161415610e7c576000600185019050600060046000838152602001908152602001600020541415610e7a576000548114610e79578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610ee48686866001611b6d565b505050505050565b600b6020528060005260406000206000915090505481565b6000610f0e610ad2565b600f54600954610f1e9190612e53565b610f289190612e53565b905090565b610f3561193f565b6000610f3f611537565b905060008111610f84576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7b90612cb8565b60405180910390fd5b610f8e3082611b73565b50565b610fac8383836040518060200160405280600081525061155e565b505050565b60108054610fbe90612f3d565b80601f0160208091040260200160405190810160405280929190818152602001828054610fea90612f3d565b80156110375780601f1061100c57610100808354040283529160200191611037565b820191906000526020600020905b81548152906001019060200180831161101a57829003601f168201915b505050505081565b61104761193f565b80600d908051906020019061105d929190612382565b5050565b600061106c826119db565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156110db576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61113461193f565b61113e6000611c24565b565b61114861193f565b600c60009054906101000a900460ff1615600c60006101000a81548160ff021916908315150217905550565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b601180546111ab90612f3d565b80601f01602080910402602001604051908101604052809291908181526020018280546111d790612f3d565b80156112245780601f106111f957610100808354040283529160200191611224565b820191906000526020600020905b81548152906001019060200180831161120757829003601f168201915b505050505081565b60606003805461123b90612f3d565b80601f016020809104026020016040519081016040528092919081815260200182805461126790612f3d565b80156112b45780601f10611289576101008083540402835291602001916112b4565b820191906000526020600020905b81548152906001019060200180831161129757829003601f168201915b5050505050905090565b600c60009054906101000a900460ff1661130d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130490612c58565b60405180910390fd5b600f5460095461131d9190612e53565b81611326610ad2565b6113309190612dfd565b1115611371576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136890612c18565b60405180910390fd5b600a548161137e33611073565b6113889190612dfd565b11156113c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c090612cd8565b60405180910390fd5b6113d333826119bd565b80600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546114229190612dfd565b9250508190555050565b806007600061143961192e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166114e661192e565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161152b9190612b9b565b60405180910390a35050565b600061154161193f565b47905090565b6000600c60009054906101000a900460ff16905090565b611569848484610bc7565b60008373ffffffffffffffffffffffffffffffffffffffff163b146115cb5761159484848484611cea565b6115ca576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6115d961193f565b6115e1610ad2565b600981905550565b6115f161193f565b80600f8190555050565b6060611606826118cf565b611645576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161163c90612c98565b60405180910390fd5b600061164f611e4a565b9050600081511161166f576040518060200160405280600081525061169d565b8061167984611edc565b601060405160200161168d93929190612aee565b6040516020818303038152906040525b915050919050565b600d80546116b290612f3d565b80601f01602080910402602001604051908101604052809291908181526020018280546116de90612f3d565b801561172b5780601f106117005761010080835404028352916020019161172b565b820191906000526020600020905b81548152906001019060200180831161170e57829003601f168201915b505050505081565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600c60009054906101000a900460ff1681565b600a5481565b6117e861193f565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611858576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161184f90612bd8565b60405180910390fd5b61186181611c24565b50565b61186c61193f565b8060119080519060200190611882929190612382565b5050565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000816118da611936565b111580156118e9575060005482105b8015611927575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b611947611fb4565b73ffffffffffffffffffffffffffffffffffffffff16611965611174565b73ffffffffffffffffffffffffffffffffffffffff16146119bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119b290612c78565b60405180910390fd5b565b6119d7828260405180602001604052806000815250611fbc565b5050565b600080829050806119ea611936565b11611a7257600054811015611a715760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082161415611a6f575b6000811415611a65576004600083600190039350838152602001908152602001600020549050611a3a565b8092505050611aa4565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611b31868684612059565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b60008273ffffffffffffffffffffffffffffffffffffffff1682604051611b9990612b1f565b60006040518083038185875af1925050503d8060008114611bd6576040519150601f19603f3d011682016040523d82523d6000602084013e611bdb565b606091505b5050905080611c1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c1690612bf8565b60405180910390fd5b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611d1061192e565b8786866040518563ffffffff1660e01b8152600401611d329493929190612b4f565b602060405180830381600087803b158015611d4c57600080fd5b505af1925050508015611d7d57506040513d601f19601f82011682018060405250810190611d7a919061275e565b60015b611df7573d8060008114611dad576040519150601f19603f3d011682016040523d82523d6000602084013e611db2565b606091505b50600081511415611def576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600d8054611e5990612f3d565b80601f0160208091040260200160405190810160405280929190818152602001828054611e8590612f3d565b8015611ed25780601f10611ea757610100808354040283529160200191611ed2565b820191906000526020600020905b815481529060010190602001808311611eb557829003601f168201915b5050505050905090565b606060006001611eeb84612062565b01905060008167ffffffffffffffff811115611f0a57611f0961302d565b5b6040519080825280601f01601f191660200182016040528015611f3c5781602001600182028036833780820191505090505b509050600082602001820190505b600115611fa9578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611f9357611f92612fcf565b5b0494506000851415611fa457611fa9565b611f4a565b819350505050919050565b600033905090565b611fc683836121b5565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461205457600080549050600083820390505b6120066000868380600101945086611cea565b61203c576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110611ff357816000541461205157600080fd5b50505b505050565b60009392505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106120c0577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816120b6576120b5612fcf565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106120fd576d04ee2d6d415b85acef810000000083816120f3576120f2612fcf565b5b0492506020810190505b662386f26fc10000831061212c57662386f26fc10000838161212257612121612fcf565b5b0492506010810190505b6305f5e1008310612155576305f5e100838161214b5761214a612fcf565b5b0492506008810190505b612710831061217a5761271083816121705761216f612fcf565b5b0492506004810190505b6064831061219d576064838161219357612192612fcf565b5b0492506002810190505b600a83106121ac576001810190505b80915050919050565b60008054905060008214156121f6576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122036000848385611b14565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061227a8361226b6000866000611b1a565b61227485612372565b17611b42565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461231b57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001810190506122e0565b506000821415612357576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061236d6000848385611b6d565b505050565b60006001821460e11b9050919050565b82805461238e90612f3d565b90600052602060002090601f0160209004810192826123b057600085556123f7565b82601f106123c957805160ff19168380011785556123f7565b828001600101855582156123f7579182015b828111156123f65782518255916020019190600101906123db565b5b5090506124049190612408565b5090565b5b80821115612421576000816000905550600101612409565b5090565b600061243861243384612d38565b612d13565b90508281526020810184848401111561245457612453613061565b5b61245f848285612efb565b509392505050565b600061247a61247584612d69565b612d13565b90508281526020810184848401111561249657612495613061565b5b6124a1848285612efb565b509392505050565b6000813590506124b8816132b3565b92915050565b6000813590506124cd816132ca565b92915050565b6000813590506124e2816132e1565b92915050565b6000815190506124f7816132e1565b92915050565b600082601f8301126125125761251161305c565b5b8135612522848260208601612425565b91505092915050565b600082601f8301126125405761253f61305c565b5b8135612550848260208601612467565b91505092915050565b600081359050612568816132f8565b92915050565b6000602082840312156125845761258361306b565b5b6000612592848285016124a9565b91505092915050565b600080604083850312156125b2576125b161306b565b5b60006125c0858286016124a9565b92505060206125d1858286016124a9565b9150509250929050565b6000806000606084860312156125f4576125f361306b565b5b6000612602868287016124a9565b9350506020612613868287016124a9565b925050604061262486828701612559565b9150509250925092565b600080600080608085870312156126485761264761306b565b5b6000612656878288016124a9565b9450506020612667878288016124a9565b935050604061267887828801612559565b925050606085013567ffffffffffffffff81111561269957612698613066565b5b6126a5878288016124fd565b91505092959194509250565b600080604083850312156126c8576126c761306b565b5b60006126d6858286016124a9565b92505060206126e7858286016124be565b9150509250929050565b600080604083850312156127085761270761306b565b5b6000612716858286016124a9565b925050602061272785828601612559565b9150509250929050565b6000602082840312156127475761274661306b565b5b6000612755848285016124d3565b91505092915050565b6000602082840312156127745761277361306b565b5b6000612782848285016124e8565b91505092915050565b6000602082840312156127a1576127a061306b565b5b600082013567ffffffffffffffff8111156127bf576127be613066565b5b6127cb8482850161252b565b91505092915050565b6000602082840312156127ea576127e961306b565b5b60006127f884828501612559565b91505092915050565b600080604083850312156128185761281761306b565b5b600061282685828601612559565b9250506020612837858286016124a9565b9150509250929050565b61284a81612e87565b82525050565b61285981612e99565b82525050565b600061286a82612daf565b6128748185612dc5565b9350612884818560208601612f0a565b61288d81613070565b840191505092915050565b60006128a382612dba565b6128ad8185612de1565b93506128bd818560208601612f0a565b6128c681613070565b840191505092915050565b60006128dc82612dba565b6128e68185612df2565b93506128f6818560208601612f0a565b80840191505092915050565b6000815461290f81612f3d565b6129198186612df2565b94506001821660008114612934576001811461294557612978565b60ff19831686528186019350612978565b61294e85612d9a565b60005b8381101561297057815481890152600182019150602081019050612951565b838801955050505b50505092915050565b600061298e602683612de1565b915061299982613081565b604082019050919050565b60006129b1601483612de1565b91506129bc826130d0565b602082019050919050565b60006129d4601e83612de1565b91506129df826130f9565b602082019050919050565b60006129f7602b83612de1565b9150612a0282613122565b604082019050919050565b6000612a1a601c83612de1565b9150612a2582613171565b602082019050919050565b6000612a3d602083612de1565b9150612a488261319a565b602082019050919050565b6000612a60602f83612de1565b9150612a6b826131c3565b604082019050919050565b6000612a83600083612dd6565b9150612a8e82613212565b600082019050919050565b6000612aa6602283612de1565b9150612ab182613215565b604082019050919050565b6000612ac9602783612de1565b9150612ad482613264565b604082019050919050565b612ae881612ef1565b82525050565b6000612afa82866128d1565b9150612b0682856128d1565b9150612b128284612902565b9150819050949350505050565b6000612b2a82612a76565b9150819050919050565b6000602082019050612b496000830184612841565b92915050565b6000608082019050612b646000830187612841565b612b716020830186612841565b612b7e6040830185612adf565b8181036060830152612b90818461285f565b905095945050505050565b6000602082019050612bb06000830184612850565b92915050565b60006020820190508181036000830152612bd08184612898565b905092915050565b60006020820190508181036000830152612bf181612981565b9050919050565b60006020820190508181036000830152612c11816129a4565b9050919050565b60006020820190508181036000830152612c31816129c7565b9050919050565b60006020820190508181036000830152612c51816129ea565b9050919050565b60006020820190508181036000830152612c7181612a0d565b9050919050565b60006020820190508181036000830152612c9181612a30565b9050919050565b60006020820190508181036000830152612cb181612a53565b9050919050565b60006020820190508181036000830152612cd181612a99565b9050919050565b60006020820190508181036000830152612cf181612abc565b9050919050565b6000602082019050612d0d6000830184612adf565b92915050565b6000612d1d612d2e565b9050612d298282612f6f565b919050565b6000604051905090565b600067ffffffffffffffff821115612d5357612d5261302d565b5b612d5c82613070565b9050602081019050919050565b600067ffffffffffffffff821115612d8457612d8361302d565b5b612d8d82613070565b9050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612e0882612ef1565b9150612e1383612ef1565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612e4857612e47612fa0565b5b828201905092915050565b6000612e5e82612ef1565b9150612e6983612ef1565b925082821015612e7c57612e7b612fa0565b5b828203905092915050565b6000612e9282612ed1565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612f28578082015181840152602081019050612f0d565b83811115612f37576000848401525b50505050565b60006002820490506001821680612f5557607f821691505b60208210811415612f6957612f68612ffe565b5b50919050565b612f7882613070565b810181811067ffffffffffffffff82111715612f9757612f9661302d565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b7f4e6f7420656e6f756768204e465473206c65667420746f206d696e742e2e0000600082015250565b7f52657365727665206e667420776f756c6420657863656564206d61782073757060008201527f706c79206f66204e465473000000000000000000000000000000000000000000602082015250565b7f5075626c69632053616c6520696e206e6f74206f70656e207965742100000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b50565b7f4e6f2046756e647320746f2077697468647261772c2042616c616e636520697360008201527f2030000000000000000000000000000000000000000000000000000000000000602082015250565b7f50757263686173652065786365656473206d617820616c6c6f7765642070657260008201527f2077616c6c657400000000000000000000000000000000000000000000000000602082015250565b6132bc81612e87565b81146132c757600080fd5b50565b6132d381612e99565b81146132de57600080fd5b50565b6132ea81612ea5565b81146132f557600080fd5b50565b61330181612ef1565b811461330c57600080fd5b5056fea2646970667358221220da5b9cf395a9f1e9621dfeaf4afedd0a85718d51e8900563535f264abf44245d64736f6c63430008070033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005968747470733a2f2f656c63686169636172636c75622e6d7970696e6174612e636c6f75642f697066732f516d5575516f4c774c6956755a71726269336732367150714667646f634458744e4a5546357156464843313751342f00000000000000
-----Decoded View---------------
Arg [0] : _uri (string): https://elchaicarclub.mypinata.cloud/ipfs/QmUuQoLwLiVuZqrbi3g26qPqFgdocDXtNJUF5qVFHC17Q4/
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000059
Arg [2] : 68747470733a2f2f656c63686169636172636c75622e6d7970696e6174612e63
Arg [3] : 6c6f75642f697066732f516d5575516f4c774c6956755a717262693367323671
Arg [4] : 50714667646f634458744e4a5546357156464843313751342f00000000000000
Deployed Bytecode Sourcemap
70330:4464:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74640:8;;;37231:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38133:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44624:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44057:408;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;33884:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71500:338;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;48263:2825;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70682:50;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74339:144;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73126:213;;;;;;;;;;;;;:::i;:::-;;51184:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71186:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73850:101;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;39526:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35068:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18010:103;;;;;;;;;;;;;:::i;:::-;;73985:81;;;;;;;;;;;;;:::i;:::-;;17362:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71268:77;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38309:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71869:450;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;45182:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72961:109;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74075:84;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51975:407;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72820:91;;;;;;;;;;;;;:::i;:::-;;72690:122;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72327:353;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70871:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45573:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70782:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70582:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18268:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73646:150;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74664:127;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37231:639;37316:4;37655:10;37640:25;;:11;:25;;;;:102;;;;37732:10;37717:25;;:11;:25;;;;37640:102;:179;;;;37809:10;37794:25;;:11;:25;;;;37640:179;37620:199;;37231:639;;;:::o;38133:100::-;38187:13;38220:5;38213:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38133:100;:::o;44624:218::-;44700:7;44725:16;44733:7;44725;:16::i;:::-;44720:64;;44750:34;;;;;;;;;;;;;;44720:64;44804:15;:24;44820:7;44804:24;;;;;;;;;;;:30;;;;;;;;;;;;44797:37;;44624:218;;;:::o;44057:408::-;44146:13;44162:16;44170:7;44162;:16::i;:::-;44146:32;;44218:5;44195:28;;:19;:17;:19::i;:::-;:28;;;44191:175;;44243:44;44260:5;44267:19;:17;:19::i;:::-;44243:16;:44::i;:::-;44238:128;;44315:35;;;;;;;;;;;;;;44238:128;44191:175;44411:2;44378:15;:24;44394:7;44378:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;44449:7;44445:2;44429:28;;44438:5;44429:28;;;;;;;;;;;;44135:330;44057:408;;:::o;33884:323::-;33945:7;34173:15;:13;:15::i;:::-;34158:12;;34142:13;;:28;:46;34135:53;;33884:323;:::o;71500:338::-;17248:13;:11;:13::i;:::-;71630:14:::1;;71615:11;71600:13;:11;:13::i;:::-;:26;;;;:::i;:::-;:44;;71591:101;;;;;;;;;;;;:::i;:::-;;;;;;;;;71703:33;71713:9;71724:11;71703:9;:33::i;:::-;71777:11;71747:15;:26;71763:9;71747:26;;;;;;;;;;;;;;;;:41;;;;;;;:::i;:::-;;;;;;;;71816:14;;71799;;:31;;;;;;;:::i;:::-;;;;;;;;71500:338:::0;;:::o;48263:2825::-;48405:27;48435;48454:7;48435:18;:27::i;:::-;48405:57;;48520:4;48479:45;;48495:19;48479:45;;;48475:86;;48533:28;;;;;;;;;;;;;;48475:86;48575:27;48604:23;48631:35;48658:7;48631:26;:35::i;:::-;48574:92;;;;48766:68;48791:15;48808:4;48814:19;:17;:19::i;:::-;48766:24;:68::i;:::-;48761:180;;48854:43;48871:4;48877:19;:17;:19::i;:::-;48854:16;:43::i;:::-;48849:92;;48906:35;;;;;;;;;;;;;;48849:92;48761:180;48972:1;48958:16;;:2;:16;;;48954:52;;;48983:23;;;;;;;;;;;;;;48954:52;49019:43;49041:4;49047:2;49051:7;49060:1;49019:21;:43::i;:::-;49155:15;49152:160;;;49295:1;49274:19;49267:30;49152:160;49692:18;:24;49711:4;49692:24;;;;;;;;;;;;;;;;49690:26;;;;;;;;;;;;49761:18;:22;49780:2;49761:22;;;;;;;;;;;;;;;;49759:24;;;;;;;;;;;50083:146;50120:2;50169:45;50184:4;50190:2;50194:19;50169:14;:45::i;:::-;30283:8;50141:73;50083:18;:146::i;:::-;50054:17;:26;50072:7;50054:26;;;;;;;;;;;:175;;;;50400:1;30283:8;50349:19;:47;:52;50345:627;;;50422:19;50454:1;50444:7;:11;50422:33;;50611:1;50577:17;:30;50595:11;50577:30;;;;;;;;;;;;:35;50573:384;;;50715:13;;50700:11;:28;50696:242;;50895:19;50862:17;:30;50880:11;50862:30;;;;;;;;;;;:52;;;;50696:242;50573:384;50403:569;50345:627;51019:7;51015:2;51000:27;;51009:4;51000:27;;;;;;;;;;;;51038:42;51059:4;51065:2;51069:7;51078:1;51038:20;:42::i;:::-;48394:2694;;;48263:2825;;;:::o;70682:50::-;;;;;;;;;;;;;;;;;:::o;74339:144::-;74397:7;74461:13;:11;:13::i;:::-;74442:16;;74425:14;;:33;;;;:::i;:::-;:49;;;;:::i;:::-;74417:58;;74339:144;:::o;73126:213::-;17248:13;:11;:13::i;:::-;73174:15:::1;73192:16;:14;:16::i;:::-;73174:34;;73237:1;73227:7;:11;73219:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;73288:42;73314:4;73322:7;73288:9;:42::i;:::-;73163:176;73126:213::o:0;51184:193::-;51330:39;51347:4;51353:2;51357:7;51330:39;;;;;;;;;;;;:16;:39::i;:::-;51184:193;;;:::o;71186:40::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;73850:101::-;17248:13;:11;:13::i;:::-;73936:7:::1;73921:12;:22;;;;;;;;;;;;:::i;:::-;;73850:101:::0;:::o;39526:152::-;39598:7;39641:27;39660:7;39641:18;:27::i;:::-;39618:52;;39526:152;;;:::o;35068:233::-;35140:7;35181:1;35164:19;;:5;:19;;;35160:60;;;35192:28;;;;;;;;;;;;;;35160:60;29227:13;35238:18;:25;35257:5;35238:25;;;;;;;;;;;;;;;;:55;35231:62;;35068:233;;;:::o;18010:103::-;17248:13;:11;:13::i;:::-;18075:30:::1;18102:1;18075:18;:30::i;:::-;18010:103::o:0;73985:81::-;17248:13;:11;:13::i;:::-;74046:12:::1;;;;;;;;;;;74045:13;74030:12;;:28;;;;;;;;;;;;;;;;;;73985:81::o:0;17362:87::-;17408:7;17435:6;;;;;;;;;;;17428:13;;17362:87;:::o;71268:77::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;38309:104::-;38365:13;38398:7;38391:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38309:104;:::o;71869:450::-;71930:12;;;;;;;;;;;71922:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;72042:16;;72025:14;;:33;;;;:::i;:::-;72010:11;71994:13;:11;:13::i;:::-;:27;;;;:::i;:::-;:64;;71986:107;;;;;;;;;;;;:::i;:::-;;;;;;;;;72151:18;;72136:11;72112:21;72122:10;72112:9;:21::i;:::-;:35;;;;:::i;:::-;:57;;72104:109;;;;;;;;;;;;:::i;:::-;;;;;;;;;72224:34;72234:10;72246:11;72224:9;:34::i;:::-;72300:11;72269:15;:27;72285:10;72269:27;;;;;;;;;;;;;;;;:42;;;;;;;:::i;:::-;;;;;;;;71869:450;:::o;45182:234::-;45329:8;45277:18;:39;45296:19;:17;:19::i;:::-;45277:39;;;;;;;;;;;;;;;:49;45317:8;45277:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;45389:8;45353:55;;45368:19;:17;:19::i;:::-;45353:55;;;45399:8;45353:55;;;;;;:::i;:::-;;;;;;;;45182:234;;:::o;72961:109::-;73017:4;17248:13;:11;:13::i;:::-;73041:21:::1;73034:28;;72961:109:::0;:::o;74075:84::-;74115:4;74139:12;;;;;;;;;;;74132:19;;74075:84;:::o;51975:407::-;52150:31;52163:4;52169:2;52173:7;52150:12;:31::i;:::-;52214:1;52196:2;:14;;;:19;52192:183;;52235:56;52266:4;52272:2;52276:7;52285:5;52235:30;:56::i;:::-;52230:145;;52319:40;;;;;;;;;;;;;;52230:145;52192:183;51975:407;;;;:::o;72820:91::-;17248:13;:11;:13::i;:::-;72890::::1;:11;:13::i;:::-;72873:14;:30;;;;72820:91::o:0;72690:122::-;17248:13;:11;:13::i;:::-;72790:14:::1;72771:16;:33;;;;72690:122:::0;:::o;72327:353::-;72401:13;72435:17;72443:8;72435:7;:17::i;:::-;72427:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;72515:21;72539:10;:8;:10::i;:::-;72515:34;;72591:1;72573:7;72567:21;:25;:105;;;;;;;;;;;;;;;;;72619:7;72628:19;:8;:17;:19::i;:::-;72649:16;72602:64;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;72567:105;72560:112;;;72327:353;;;:::o;70871:26::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;45573:164::-;45670:4;45694:18;:25;45713:5;45694:25;;;;;;;;;;;;;;;:35;45720:8;45694:35;;;;;;;;;;;;;;;;;;;;;;;;;45687:42;;45573:164;;;;:::o;70782:32::-;;;;;;;;;;;;;:::o;70582:37::-;;;;:::o;18268:201::-;17248:13;:11;:13::i;:::-;18377:1:::1;18357:22;;:8;:22;;;;18349:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;18433:28;18452:8;18433:18;:28::i;:::-;18268:201:::0;:::o;73646:150::-;17248:13;:11;:13::i;:::-;73767:21:::1;73744:20;:44;;;;;;;;;;;;:::i;:::-;;73646:150:::0;:::o;74664:127::-;74733:4;74757:15;:26;74773:9;74757:26;;;;;;;;;;;;;;;;74750:33;;74664:127;;;:::o;45995:282::-;46060:4;46116:7;46097:15;:13;:15::i;:::-;:26;;:66;;;;;46150:13;;46140:7;:23;46097:66;:153;;;;;46249:1;30003:8;46201:17;:26;46219:7;46201:26;;;;;;;;;;;;:44;:49;46097:153;46077:173;;45995:282;;;:::o;68303:105::-;68363:7;68390:10;68383:17;;68303:105;:::o;33400:92::-;33456:7;33483:1;33476:8;;33400:92;:::o;17527:132::-;17602:12;:10;:12::i;:::-;17591:23;;:7;:5;:7::i;:::-;:23;;;17583:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;17527:132::o;62135:112::-;62212:27;62222:2;62226:8;62212:27;;;;;;;;;;;;:9;:27::i;:::-;62135:112;;:::o;40681:1275::-;40748:7;40768:12;40783:7;40768:22;;40851:4;40832:15;:13;:15::i;:::-;:23;40828:1061;;40885:13;;40878:4;:20;40874:1015;;;40923:14;40940:17;:23;40958:4;40940:23;;;;;;;;;;;;40923:40;;41057:1;30003:8;41029:6;:24;:29;41025:845;;;41694:113;41711:1;41701:6;:11;41694:113;;;41754:17;:25;41772:6;;;;;;;41754:25;;;;;;;;;;;;41745:34;;41694:113;;;41840:6;41833:13;;;;;;41025:845;40900:989;40874:1015;40828:1061;41917:31;;;;;;;;;;;;;;40681:1275;;;;:::o;47158:485::-;47260:27;47289:23;47330:38;47371:15;:24;47387:7;47371:24;;;;;;;;;;;47330:65;;47548:18;47525:41;;47605:19;47599:26;47580:45;;47510:126;47158:485;;;:::o;46386:659::-;46535:11;46700:16;46693:5;46689:28;46680:37;;46860:16;46849:9;46845:32;46832:45;;47010:15;46999:9;46996:30;46988:5;46977:9;46974:20;46971:56;46961:66;;46386:659;;;;;:::o;53044:159::-;;;;;:::o;67612:311::-;67747:7;67767:16;30407:3;67793:19;:41;;67767:68;;30407:3;67861:31;67872:4;67878:2;67882:9;67861:10;:31::i;:::-;67853:40;;:62;;67846:69;;;67612:311;;;;;:::o;42504:450::-;42584:14;42752:16;42745:5;42741:28;42732:37;;42929:5;42915:11;42890:23;42886:41;42883:52;42876:5;42873:63;42863:73;;42504:450;;;;:::o;53868:158::-;;;;;:::o;73414:183::-;73495:9;73510:7;:12;;73530:6;73510:31;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73494:47;;;73560:4;73552:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;73483:114;73414:183;;:::o;18629:191::-;18703:16;18722:6;;;;;;;;;;;18703:25;;18748:8;18739:6;;:17;;;;;;;;;;;;;;;;;;18803:8;18772:40;;18793:8;18772:40;;;;;;;;;;;;18692:128;18629:191;:::o;54466:716::-;54629:4;54675:2;54650:45;;;54696:19;:17;:19::i;:::-;54717:4;54723:7;54732:5;54650:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;54646:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54950:1;54933:6;:13;:18;54929:235;;;54979:40;;;;;;;;;;;;;;54929:235;55122:6;55116:13;55107:6;55103:2;55099:15;55092:38;54646:529;54819:54;;;54809:64;;;:6;:64;;;;54802:71;;;54466:716;;;;;;:::o;74192:113::-;74252:13;74285:12;74278:19;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74192:113;:::o;13340:716::-;13396:13;13447:14;13484:1;13464:17;13475:5;13464:10;:17::i;:::-;:21;13447:38;;13500:20;13534:6;13523:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13500:41;;13556:11;13685:6;13681:2;13677:15;13669:6;13665:28;13658:35;;13722:288;13729:4;13722:288;;;13754:5;;;;;;;;13896:8;13891:2;13884:5;13880:14;13875:30;13870:3;13862:44;13952:2;13943:11;;;;;;:::i;:::-;;;;;13986:1;13977:5;:10;13973:21;;;13989:5;;13973:21;13722:288;;;14031:6;14024:13;;;;;13340:716;;;:::o;15913:98::-;15966:7;15993:10;15986:17;;15913:98;:::o;61362:689::-;61493:19;61499:2;61503:8;61493:5;:19::i;:::-;61572:1;61554:2;:14;;;:19;61550:483;;61594:11;61608:13;;61594:27;;61640:13;61662:8;61656:3;:14;61640:30;;61689:233;61720:62;61759:1;61763:2;61767:7;;;;;;61776:5;61720:30;:62::i;:::-;61715:167;;61818:40;;;;;;;;;;;;;;61715:167;61917:3;61909:5;:11;61689:233;;62004:3;61987:13;;:20;61983:34;;62009:8;;;61983:34;61575:458;;61550:483;61362:689;;;:::o;67313:147::-;67450:6;67313:147;;;;;:::o;10206:922::-;10259:7;10279:14;10296:1;10279:18;;10346:6;10337:5;:15;10333:102;;10382:6;10373:15;;;;;;:::i;:::-;;;;;10417:2;10407:12;;;;10333:102;10462:6;10453:5;:15;10449:102;;10498:6;10489:15;;;;;;:::i;:::-;;;;;10533:2;10523:12;;;;10449:102;10578:6;10569:5;:15;10565:102;;10614:6;10605:15;;;;;;:::i;:::-;;;;;10649:2;10639:12;;;;10565:102;10694:5;10685;:14;10681:99;;10729:5;10720:14;;;;;;:::i;:::-;;;;;10763:1;10753:11;;;;10681:99;10807:5;10798;:14;10794:99;;10842:5;10833:14;;;;;;:::i;:::-;;;;;10876:1;10866:11;;;;10794:99;10920:5;10911;:14;10907:99;;10955:5;10946:14;;;;;;:::i;:::-;;;;;10989:1;10979:11;;;;10907:99;11033:5;11024;:14;11020:66;;11069:1;11059:11;;;;11020:66;11114:6;11107:13;;;10206:922;;;:::o;55644:2966::-;55717:20;55740:13;;55717:36;;55780:1;55768:8;:13;55764:44;;;55790:18;;;;;;;;;;;;;;55764:44;55821:61;55851:1;55855:2;55859:12;55873:8;55821:21;:61::i;:::-;56365:1;29365:2;56335:1;:26;;56334:32;56322:8;:45;56296:18;:22;56315:2;56296:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;56644:139;56681:2;56735:33;56758:1;56762:2;56766:1;56735:14;:33::i;:::-;56702:30;56723:8;56702:20;:30::i;:::-;:66;56644:18;:139::i;:::-;56610:17;:31;56628:12;56610:31;;;;;;;;;;;:173;;;;56800:16;56831:11;56860:8;56845:12;:23;56831:37;;57381:16;57377:2;57373:25;57361:37;;57753:12;57713:8;57672:1;57610:25;57551:1;57490;57463:335;58124:1;58110:12;58106:20;58064:346;58165:3;58156:7;58153:16;58064:346;;58383:7;58373:8;58370:1;58343:25;58340:1;58337;58332:59;58218:1;58209:7;58205:15;58194:26;;58064:346;;;58068:77;58455:1;58443:8;:13;58439:45;;;58465:19;;;;;;;;;;;;;;58439:45;58517:3;58501:13;:19;;;;56070:2462;;58542:60;58571:1;58575:2;58579:12;58593:8;58542:20;:60::i;:::-;55706:2904;55644:2966;;:::o;43056:324::-;43126:14;43359:1;43349:8;43346:15;43320:24;43316:46;43306:56;;43056:324;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:410:1:-;84:5;109:65;125:48;166:6;125:48;:::i;:::-;109:65;:::i;:::-;100:74;;197:6;190:5;183:21;235:4;228:5;224:16;273:3;264:6;259:3;255:16;252:25;249:112;;;280:79;;:::i;:::-;249:112;370:41;404:6;399:3;394;370:41;:::i;:::-;90:327;7:410;;;;;:::o;423:412::-;501:5;526:66;542:49;584:6;542:49;:::i;:::-;526:66;:::i;:::-;517:75;;615:6;608:5;601:21;653:4;646:5;642:16;691:3;682:6;677:3;673:16;670:25;667:112;;;698:79;;:::i;:::-;667:112;788:41;822:6;817:3;812;788:41;:::i;:::-;507:328;423:412;;;;;:::o;841:139::-;887:5;925:6;912:20;903:29;;941:33;968:5;941:33;:::i;:::-;841:139;;;;:::o;986:133::-;1029:5;1067:6;1054:20;1045:29;;1083:30;1107:5;1083:30;:::i;:::-;986:133;;;;:::o;1125:137::-;1170:5;1208:6;1195:20;1186:29;;1224:32;1250:5;1224:32;:::i;:::-;1125:137;;;;:::o;1268:141::-;1324:5;1355:6;1349:13;1340:22;;1371:32;1397:5;1371:32;:::i;:::-;1268:141;;;;:::o;1428:338::-;1483:5;1532:3;1525:4;1517:6;1513:17;1509:27;1499:122;;1540:79;;:::i;:::-;1499:122;1657:6;1644:20;1682:78;1756:3;1748:6;1741:4;1733:6;1729:17;1682:78;:::i;:::-;1673:87;;1489:277;1428:338;;;;:::o;1786:340::-;1842:5;1891:3;1884:4;1876:6;1872:17;1868:27;1858:122;;1899:79;;:::i;:::-;1858:122;2016:6;2003:20;2041:79;2116:3;2108:6;2101:4;2093:6;2089:17;2041:79;:::i;:::-;2032:88;;1848:278;1786:340;;;;:::o;2132:139::-;2178:5;2216:6;2203:20;2194:29;;2232:33;2259:5;2232:33;:::i;:::-;2132:139;;;;:::o;2277:329::-;2336:6;2385:2;2373:9;2364:7;2360:23;2356:32;2353:119;;;2391:79;;:::i;:::-;2353:119;2511:1;2536:53;2581:7;2572:6;2561:9;2557:22;2536:53;:::i;:::-;2526:63;;2482:117;2277:329;;;;:::o;2612:474::-;2680:6;2688;2737:2;2725:9;2716:7;2712:23;2708:32;2705:119;;;2743:79;;:::i;:::-;2705:119;2863:1;2888:53;2933:7;2924:6;2913:9;2909:22;2888:53;:::i;:::-;2878:63;;2834:117;2990:2;3016:53;3061:7;3052:6;3041:9;3037:22;3016:53;:::i;:::-;3006:63;;2961:118;2612:474;;;;;:::o;3092:619::-;3169:6;3177;3185;3234:2;3222:9;3213:7;3209:23;3205:32;3202:119;;;3240:79;;:::i;:::-;3202:119;3360:1;3385:53;3430:7;3421:6;3410:9;3406:22;3385:53;:::i;:::-;3375:63;;3331:117;3487:2;3513:53;3558:7;3549:6;3538:9;3534:22;3513:53;:::i;:::-;3503:63;;3458:118;3615:2;3641:53;3686:7;3677:6;3666:9;3662:22;3641:53;:::i;:::-;3631:63;;3586:118;3092:619;;;;;:::o;3717:943::-;3812:6;3820;3828;3836;3885:3;3873:9;3864:7;3860:23;3856:33;3853:120;;;3892:79;;:::i;:::-;3853:120;4012:1;4037:53;4082:7;4073:6;4062:9;4058:22;4037:53;:::i;:::-;4027:63;;3983:117;4139:2;4165:53;4210:7;4201:6;4190:9;4186:22;4165:53;:::i;:::-;4155:63;;4110:118;4267:2;4293:53;4338:7;4329:6;4318:9;4314:22;4293:53;:::i;:::-;4283:63;;4238:118;4423:2;4412:9;4408:18;4395:32;4454:18;4446:6;4443:30;4440:117;;;4476:79;;:::i;:::-;4440:117;4581:62;4635:7;4626:6;4615:9;4611:22;4581:62;:::i;:::-;4571:72;;4366:287;3717:943;;;;;;;:::o;4666:468::-;4731:6;4739;4788:2;4776:9;4767:7;4763:23;4759:32;4756:119;;;4794:79;;:::i;:::-;4756:119;4914:1;4939:53;4984:7;4975:6;4964:9;4960:22;4939:53;:::i;:::-;4929:63;;4885:117;5041:2;5067:50;5109:7;5100:6;5089:9;5085:22;5067:50;:::i;:::-;5057:60;;5012:115;4666:468;;;;;:::o;5140:474::-;5208:6;5216;5265:2;5253:9;5244:7;5240:23;5236:32;5233:119;;;5271:79;;:::i;:::-;5233:119;5391:1;5416:53;5461:7;5452:6;5441:9;5437:22;5416:53;:::i;:::-;5406:63;;5362:117;5518:2;5544:53;5589:7;5580:6;5569:9;5565:22;5544:53;:::i;:::-;5534:63;;5489:118;5140:474;;;;;:::o;5620:327::-;5678:6;5727:2;5715:9;5706:7;5702:23;5698:32;5695:119;;;5733:79;;:::i;:::-;5695:119;5853:1;5878:52;5922:7;5913:6;5902:9;5898:22;5878:52;:::i;:::-;5868:62;;5824:116;5620:327;;;;:::o;5953:349::-;6022:6;6071:2;6059:9;6050:7;6046:23;6042:32;6039:119;;;6077:79;;:::i;:::-;6039:119;6197:1;6222:63;6277:7;6268:6;6257:9;6253:22;6222:63;:::i;:::-;6212:73;;6168:127;5953:349;;;;:::o;6308:509::-;6377:6;6426:2;6414:9;6405:7;6401:23;6397:32;6394:119;;;6432:79;;:::i;:::-;6394:119;6580:1;6569:9;6565:17;6552:31;6610:18;6602:6;6599:30;6596:117;;;6632:79;;:::i;:::-;6596:117;6737:63;6792:7;6783:6;6772:9;6768:22;6737:63;:::i;:::-;6727:73;;6523:287;6308:509;;;;:::o;6823:329::-;6882:6;6931:2;6919:9;6910:7;6906:23;6902:32;6899:119;;;6937:79;;:::i;:::-;6899:119;7057:1;7082:53;7127:7;7118:6;7107:9;7103:22;7082:53;:::i;:::-;7072:63;;7028:117;6823:329;;;;:::o;7158:474::-;7226:6;7234;7283:2;7271:9;7262:7;7258:23;7254:32;7251:119;;;7289:79;;:::i;:::-;7251:119;7409:1;7434:53;7479:7;7470:6;7459:9;7455:22;7434:53;:::i;:::-;7424:63;;7380:117;7536:2;7562:53;7607:7;7598:6;7587:9;7583:22;7562:53;:::i;:::-;7552:63;;7507:118;7158:474;;;;;:::o;7638:118::-;7725:24;7743:5;7725:24;:::i;:::-;7720:3;7713:37;7638:118;;:::o;7762:109::-;7843:21;7858:5;7843:21;:::i;:::-;7838:3;7831:34;7762:109;;:::o;7877:360::-;7963:3;7991:38;8023:5;7991:38;:::i;:::-;8045:70;8108:6;8103:3;8045:70;:::i;:::-;8038:77;;8124:52;8169:6;8164:3;8157:4;8150:5;8146:16;8124:52;:::i;:::-;8201:29;8223:6;8201:29;:::i;:::-;8196:3;8192:39;8185:46;;7967:270;7877:360;;;;:::o;8243:364::-;8331:3;8359:39;8392:5;8359:39;:::i;:::-;8414:71;8478:6;8473:3;8414:71;:::i;:::-;8407:78;;8494:52;8539:6;8534:3;8527:4;8520:5;8516:16;8494:52;:::i;:::-;8571:29;8593:6;8571:29;:::i;:::-;8566:3;8562:39;8555:46;;8335:272;8243:364;;;;:::o;8613:377::-;8719:3;8747:39;8780:5;8747:39;:::i;:::-;8802:89;8884:6;8879:3;8802:89;:::i;:::-;8795:96;;8900:52;8945:6;8940:3;8933:4;8926:5;8922:16;8900:52;:::i;:::-;8977:6;8972:3;8968:16;8961:23;;8723:267;8613:377;;;;:::o;9020:845::-;9123:3;9160:5;9154:12;9189:36;9215:9;9189:36;:::i;:::-;9241:89;9323:6;9318:3;9241:89;:::i;:::-;9234:96;;9361:1;9350:9;9346:17;9377:1;9372:137;;;;9523:1;9518:341;;;;9339:520;;9372:137;9456:4;9452:9;9441;9437:25;9432:3;9425:38;9492:6;9487:3;9483:16;9476:23;;9372:137;;9518:341;9585:38;9617:5;9585:38;:::i;:::-;9645:1;9659:154;9673:6;9670:1;9667:13;9659:154;;;9747:7;9741:14;9737:1;9732:3;9728:11;9721:35;9797:1;9788:7;9784:15;9773:26;;9695:4;9692:1;9688:12;9683:17;;9659:154;;;9842:6;9837:3;9833:16;9826:23;;9525:334;;9339:520;;9127:738;;9020:845;;;;:::o;9871:366::-;10013:3;10034:67;10098:2;10093:3;10034:67;:::i;:::-;10027:74;;10110:93;10199:3;10110:93;:::i;:::-;10228:2;10223:3;10219:12;10212:19;;9871:366;;;:::o;10243:::-;10385:3;10406:67;10470:2;10465:3;10406:67;:::i;:::-;10399:74;;10482:93;10571:3;10482:93;:::i;:::-;10600:2;10595:3;10591:12;10584:19;;10243:366;;;:::o;10615:::-;10757:3;10778:67;10842:2;10837:3;10778:67;:::i;:::-;10771:74;;10854:93;10943:3;10854:93;:::i;:::-;10972:2;10967:3;10963:12;10956:19;;10615:366;;;:::o;10987:::-;11129:3;11150:67;11214:2;11209:3;11150:67;:::i;:::-;11143:74;;11226:93;11315:3;11226:93;:::i;:::-;11344:2;11339:3;11335:12;11328:19;;10987:366;;;:::o;11359:::-;11501:3;11522:67;11586:2;11581:3;11522:67;:::i;:::-;11515:74;;11598:93;11687:3;11598:93;:::i;:::-;11716:2;11711:3;11707:12;11700:19;;11359:366;;;:::o;11731:::-;11873:3;11894:67;11958:2;11953:3;11894:67;:::i;:::-;11887:74;;11970:93;12059:3;11970:93;:::i;:::-;12088:2;12083:3;12079:12;12072:19;;11731:366;;;:::o;12103:::-;12245:3;12266:67;12330:2;12325:3;12266:67;:::i;:::-;12259:74;;12342:93;12431:3;12342:93;:::i;:::-;12460:2;12455:3;12451:12;12444:19;;12103:366;;;:::o;12475:398::-;12634:3;12655:83;12736:1;12731:3;12655:83;:::i;:::-;12648:90;;12747:93;12836:3;12747:93;:::i;:::-;12865:1;12860:3;12856:11;12849:18;;12475:398;;;:::o;12879:366::-;13021:3;13042:67;13106:2;13101:3;13042:67;:::i;:::-;13035:74;;13118:93;13207:3;13118:93;:::i;:::-;13236:2;13231:3;13227:12;13220:19;;12879:366;;;:::o;13251:::-;13393:3;13414:67;13478:2;13473:3;13414:67;:::i;:::-;13407:74;;13490:93;13579:3;13490:93;:::i;:::-;13608:2;13603:3;13599:12;13592:19;;13251:366;;;:::o;13623:118::-;13710:24;13728:5;13710:24;:::i;:::-;13705:3;13698:37;13623:118;;:::o;13747:589::-;13972:3;13994:95;14085:3;14076:6;13994:95;:::i;:::-;13987:102;;14106:95;14197:3;14188:6;14106:95;:::i;:::-;14099:102;;14218:92;14306:3;14297:6;14218:92;:::i;:::-;14211:99;;14327:3;14320:10;;13747:589;;;;;;:::o;14342:379::-;14526:3;14548:147;14691:3;14548:147;:::i;:::-;14541:154;;14712:3;14705:10;;14342:379;;;:::o;14727:222::-;14820:4;14858:2;14847:9;14843:18;14835:26;;14871:71;14939:1;14928:9;14924:17;14915:6;14871:71;:::i;:::-;14727:222;;;;:::o;14955:640::-;15150:4;15188:3;15177:9;15173:19;15165:27;;15202:71;15270:1;15259:9;15255:17;15246:6;15202:71;:::i;:::-;15283:72;15351:2;15340:9;15336:18;15327:6;15283:72;:::i;:::-;15365;15433:2;15422:9;15418:18;15409:6;15365:72;:::i;:::-;15484:9;15478:4;15474:20;15469:2;15458:9;15454:18;15447:48;15512:76;15583:4;15574:6;15512:76;:::i;:::-;15504:84;;14955:640;;;;;;;:::o;15601:210::-;15688:4;15726:2;15715:9;15711:18;15703:26;;15739:65;15801:1;15790:9;15786:17;15777:6;15739:65;:::i;:::-;15601:210;;;;:::o;15817:313::-;15930:4;15968:2;15957:9;15953:18;15945:26;;16017:9;16011:4;16007:20;16003:1;15992:9;15988:17;15981:47;16045:78;16118:4;16109:6;16045:78;:::i;:::-;16037:86;;15817:313;;;;:::o;16136:419::-;16302:4;16340:2;16329:9;16325:18;16317:26;;16389:9;16383:4;16379:20;16375:1;16364:9;16360:17;16353:47;16417:131;16543:4;16417:131;:::i;:::-;16409:139;;16136:419;;;:::o;16561:::-;16727:4;16765:2;16754:9;16750:18;16742:26;;16814:9;16808:4;16804:20;16800:1;16789:9;16785:17;16778:47;16842:131;16968:4;16842:131;:::i;:::-;16834:139;;16561:419;;;:::o;16986:::-;17152:4;17190:2;17179:9;17175:18;17167:26;;17239:9;17233:4;17229:20;17225:1;17214:9;17210:17;17203:47;17267:131;17393:4;17267:131;:::i;:::-;17259:139;;16986:419;;;:::o;17411:::-;17577:4;17615:2;17604:9;17600:18;17592:26;;17664:9;17658:4;17654:20;17650:1;17639:9;17635:17;17628:47;17692:131;17818:4;17692:131;:::i;:::-;17684:139;;17411:419;;;:::o;17836:::-;18002:4;18040:2;18029:9;18025:18;18017:26;;18089:9;18083:4;18079:20;18075:1;18064:9;18060:17;18053:47;18117:131;18243:4;18117:131;:::i;:::-;18109:139;;17836:419;;;:::o;18261:::-;18427:4;18465:2;18454:9;18450:18;18442:26;;18514:9;18508:4;18504:20;18500:1;18489:9;18485:17;18478:47;18542:131;18668:4;18542:131;:::i;:::-;18534:139;;18261:419;;;:::o;18686:::-;18852:4;18890:2;18879:9;18875:18;18867:26;;18939:9;18933:4;18929:20;18925:1;18914:9;18910:17;18903:47;18967:131;19093:4;18967:131;:::i;:::-;18959:139;;18686:419;;;:::o;19111:::-;19277:4;19315:2;19304:9;19300:18;19292:26;;19364:9;19358:4;19354:20;19350:1;19339:9;19335:17;19328:47;19392:131;19518:4;19392:131;:::i;:::-;19384:139;;19111:419;;;:::o;19536:::-;19702:4;19740:2;19729:9;19725:18;19717:26;;19789:9;19783:4;19779:20;19775:1;19764:9;19760:17;19753:47;19817:131;19943:4;19817:131;:::i;:::-;19809:139;;19536:419;;;:::o;19961:222::-;20054:4;20092:2;20081:9;20077:18;20069:26;;20105:71;20173:1;20162:9;20158:17;20149:6;20105:71;:::i;:::-;19961:222;;;;:::o;20189:129::-;20223:6;20250:20;;:::i;:::-;20240:30;;20279:33;20307:4;20299:6;20279:33;:::i;:::-;20189:129;;;:::o;20324:75::-;20357:6;20390:2;20384:9;20374:19;;20324:75;:::o;20405:307::-;20466:4;20556:18;20548:6;20545:30;20542:56;;;20578:18;;:::i;:::-;20542:56;20616:29;20638:6;20616:29;:::i;:::-;20608:37;;20700:4;20694;20690:15;20682:23;;20405:307;;;:::o;20718:308::-;20780:4;20870:18;20862:6;20859:30;20856:56;;;20892:18;;:::i;:::-;20856:56;20930:29;20952:6;20930:29;:::i;:::-;20922:37;;21014:4;21008;21004:15;20996:23;;20718:308;;;:::o;21032:141::-;21081:4;21104:3;21096:11;;21127:3;21124:1;21117:14;21161:4;21158:1;21148:18;21140:26;;21032:141;;;:::o;21179:98::-;21230:6;21264:5;21258:12;21248:22;;21179:98;;;:::o;21283:99::-;21335:6;21369:5;21363:12;21353:22;;21283:99;;;:::o;21388:168::-;21471:11;21505:6;21500:3;21493:19;21545:4;21540:3;21536:14;21521:29;;21388:168;;;;:::o;21562:147::-;21663:11;21700:3;21685:18;;21562:147;;;;:::o;21715:169::-;21799:11;21833:6;21828:3;21821:19;21873:4;21868:3;21864:14;21849:29;;21715:169;;;;:::o;21890:148::-;21992:11;22029:3;22014:18;;21890:148;;;;:::o;22044:305::-;22084:3;22103:20;22121:1;22103:20;:::i;:::-;22098:25;;22137:20;22155:1;22137:20;:::i;:::-;22132:25;;22291:1;22223:66;22219:74;22216:1;22213:81;22210:107;;;22297:18;;:::i;:::-;22210:107;22341:1;22338;22334:9;22327:16;;22044:305;;;;:::o;22355:191::-;22395:4;22415:20;22433:1;22415:20;:::i;:::-;22410:25;;22449:20;22467:1;22449:20;:::i;:::-;22444:25;;22488:1;22485;22482:8;22479:34;;;22493:18;;:::i;:::-;22479:34;22538:1;22535;22531:9;22523:17;;22355:191;;;;:::o;22552:96::-;22589:7;22618:24;22636:5;22618:24;:::i;:::-;22607:35;;22552:96;;;:::o;22654:90::-;22688:7;22731:5;22724:13;22717:21;22706:32;;22654:90;;;:::o;22750:149::-;22786:7;22826:66;22819:5;22815:78;22804:89;;22750:149;;;:::o;22905:126::-;22942:7;22982:42;22975:5;22971:54;22960:65;;22905:126;;;:::o;23037:77::-;23074:7;23103:5;23092:16;;23037:77;;;:::o;23120:154::-;23204:6;23199:3;23194;23181:30;23266:1;23257:6;23252:3;23248:16;23241:27;23120:154;;;:::o;23280:307::-;23348:1;23358:113;23372:6;23369:1;23366:13;23358:113;;;23457:1;23452:3;23448:11;23442:18;23438:1;23433:3;23429:11;23422:39;23394:2;23391:1;23387:10;23382:15;;23358:113;;;23489:6;23486:1;23483:13;23480:101;;;23569:1;23560:6;23555:3;23551:16;23544:27;23480:101;23329:258;23280:307;;;:::o;23593:320::-;23637:6;23674:1;23668:4;23664:12;23654:22;;23721:1;23715:4;23711:12;23742:18;23732:81;;23798:4;23790:6;23786:17;23776:27;;23732:81;23860:2;23852:6;23849:14;23829:18;23826:38;23823:84;;;23879:18;;:::i;:::-;23823:84;23644:269;23593:320;;;:::o;23919:281::-;24002:27;24024:4;24002:27;:::i;:::-;23994:6;23990:40;24132:6;24120:10;24117:22;24096:18;24084:10;24081:34;24078:62;24075:88;;;24143:18;;:::i;:::-;24075:88;24183:10;24179:2;24172:22;23962:238;23919:281;;:::o;24206:180::-;24254:77;24251:1;24244:88;24351:4;24348:1;24341:15;24375:4;24372:1;24365:15;24392:180;24440:77;24437:1;24430:88;24537:4;24534:1;24527:15;24561:4;24558:1;24551:15;24578:180;24626:77;24623:1;24616:88;24723:4;24720:1;24713:15;24747:4;24744:1;24737:15;24764:180;24812:77;24809:1;24802:88;24909:4;24906:1;24899:15;24933:4;24930:1;24923:15;24950:117;25059:1;25056;25049:12;25073:117;25182:1;25179;25172:12;25196:117;25305:1;25302;25295:12;25319:117;25428:1;25425;25418:12;25442:102;25483:6;25534:2;25530:7;25525:2;25518:5;25514:14;25510:28;25500:38;;25442:102;;;:::o;25550:225::-;25690:34;25686:1;25678:6;25674:14;25667:58;25759:8;25754:2;25746:6;25742:15;25735:33;25550:225;:::o;25781:170::-;25921:22;25917:1;25909:6;25905:14;25898:46;25781:170;:::o;25957:180::-;26097:32;26093:1;26085:6;26081:14;26074:56;25957:180;:::o;26143:230::-;26283:34;26279:1;26271:6;26267:14;26260:58;26352:13;26347:2;26339:6;26335:15;26328:38;26143:230;:::o;26379:178::-;26519:30;26515:1;26507:6;26503:14;26496:54;26379:178;:::o;26563:182::-;26703:34;26699:1;26691:6;26687:14;26680:58;26563:182;:::o;26751:234::-;26891:34;26887:1;26879:6;26875:14;26868:58;26960:17;26955:2;26947:6;26943:15;26936:42;26751:234;:::o;26991:114::-;;:::o;27111:221::-;27251:34;27247:1;27239:6;27235:14;27228:58;27320:4;27315:2;27307:6;27303:15;27296:29;27111:221;:::o;27338:226::-;27478:34;27474:1;27466:6;27462:14;27455:58;27547:9;27542:2;27534:6;27530:15;27523:34;27338:226;:::o;27570:122::-;27643:24;27661:5;27643:24;:::i;:::-;27636:5;27633:35;27623:63;;27682:1;27679;27672:12;27623:63;27570:122;:::o;27698:116::-;27768:21;27783:5;27768:21;:::i;:::-;27761:5;27758:32;27748:60;;27804:1;27801;27794:12;27748:60;27698:116;:::o;27820:120::-;27892:23;27909:5;27892:23;:::i;:::-;27885:5;27882:34;27872:62;;27930:1;27927;27920:12;27872:62;27820:120;:::o;27946:122::-;28019:24;28037:5;28019:24;:::i;:::-;28012:5;28009:35;27999:63;;28058:1;28055;28048:12;27999:63;27946:122;:::o
Swarm Source
ipfs://da5b9cf395a9f1e9621dfeaf4afedd0a85718d51e8900563535f264abf44245d
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.