ERC-721
Overview
Max Total Supply
396 Nebula
Holders
228
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 NebulaLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Nebula
Compiler Version
v0.8.7+commit.e28d00a7
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-11-03 */ // File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The proofs can be generated using the JavaScript library * https://github.com/miguelmota/merkletreejs[merkletreejs]. * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled. * * See `test/utils/cryptography/MerkleProof.test.js` for some examples. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} * * _Available since v4.7._ */ function verifyCalldata( bytes32[] calldata proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} * * _Available since v4.7._ */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * _Available since v4.7._ */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * _Available since v4.7._ */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`, * consuming from one or the other at each step according to the instructions given by * `proofFlags`. * * _Available since v4.7._ */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof} * * _Available since v4.7._ */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } } // File: @openzeppelin/contracts/security/ReentrancyGuard.sol // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_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) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @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] = _HEX_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 0; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr) if (curr < _currentIndex) { uint256 packed = _packedOwnerships[curr]; // If not burned. if (packed & _BITMASK_BURNED == 0) { // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `curr` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) public payable virtual override { address owner = ownerOf(tokenId); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned. } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 toMasked; uint256 end = startTokenId + quantity; // Use assembly to loop and emit the `Transfer` event for gas savings. // The duplicated `log4` removes an extra check and reduces stack juggling. // The assembly, together with the surrounding Solidity code, have been // delicately arranged to nudge the compiler into producing optimized opcodes. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. startTokenId // `tokenId`. ) // The `iszero(eq(,))` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. // The compiler will optimize the `iszero` away for performance. for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } if (toMasked == 0) revert MintToZeroAddress(); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } } // File: contracts/1_Storage.sol pragma solidity >=0.8.0; /** * @dev contract module which defines Cannaverse NFT Collection * and all the interactions it uses */ contract Nebula is ERC721A, Ownable { struct Phase { uint256 editions; uint256 price; } //@dev Attributes for NFT configuration string internal baseURI; uint256 public maxSupply = 888; uint256 public maxMintableAmount = 1; mapping(uint256 => string) private _tokenURIs; bytes32 public merkleRoot; mapping(uint256 => Phase) public phaseToPrice; bool public isWhitelist = true; /** * @dev Create an instance of Couch Heroes contract */ constructor() ERC721A("Nebula", "Nebula") { phaseToPrice[1] = Phase(444, 0 ether); phaseToPrice[2] = Phase(666, 0.035 ether); phaseToPrice[3] = Phase(maxSupply, 0.055 ether); } /** * @dev check mint conditions * @param _amount amount of NFTs to mint * @param _proof merkle proof */ modifier checkMintConditions(uint256 _amount, bytes32[] memory _proof) { require(msg.value == getCost(_amount), "Invalid ETH amount"); require(totalSupply() + _amount <= maxSupply, "Sold out"); if (totalSupply() + _amount < phaseToPrice[2].editions) { if (isWhitelist) require(_verify(_leaf(msg.sender), _proof), "Not whitelisted"); require( _numberMinted(msg.sender) + _amount <= maxMintableAmount, "Exceed max mintable" ); } _; } /** * @dev toggle whitelist */ function toggleWhitelist() external onlyOwner { isWhitelist = !isWhitelist; } /** * @dev update phase price * @param _phaseNumber phase number * @param _editions editions * @param _price price */ function updatePhase( uint256 _phaseNumber, uint256 _editions, uint256 _price ) external onlyOwner { phaseToPrice[_phaseNumber] = Phase(_editions, _price); } /** * @dev set max supply * @param _maxSupply max supply */ function setMaxSupply(uint256 _maxSupply) external onlyOwner { maxSupply = _maxSupply; phaseToPrice[3].editions = maxSupply; } /** * @dev get cost of minting * @param _amount amount of NFTs to mint */ function getCost(uint256 _amount) public view returns (uint256) { uint256 supply = totalSupply() + _amount; uint256 phase; for (uint256 i = 1; i <= 3; i++) { if (supply <= phaseToPrice[i].editions) { phase = i; break; } } return phaseToPrice[phase].price * _amount; } /** * @dev Mint NFTs * @param _amount Amount of NFTs to mint */ function devMint(uint256 _amount) external onlyOwner { _safeMint(msg.sender, _amount); } function _startTokenId() internal view virtual override returns (uint256) { return 1; } /** * @dev set merkle root * @param _merkleRoot merkle root */ function setMerkleRoot(bytes32 _merkleRoot) external onlyOwner { merkleRoot = _merkleRoot; } /** * @dev verify if a leaf is in a merkle tree * @param _owner address of the owner */ function _leaf(address _owner) internal pure returns (bytes32) { return keccak256(abi.encodePacked(_owner)); } /** * @dev Verify if an address is whitelisted * @param leaf address to verify * @param proof merkle proof */ function _verify(bytes32 leaf, bytes32[] memory proof) internal view returns (bool) { return MerkleProof.verify(proof, merkleRoot, leaf); } /** * @dev get base URI for NFT metadata */ function _baseURI() internal view virtual override returns (string memory) { return baseURI; } /** * @dev mint NFTs * @param _amount amount of NFTs to mint * @param _proof merkle proof */ function mint(uint256 _amount, bytes32[] memory _proof) external payable checkMintConditions(_amount, _proof) { _safeMint(msg.sender, _amount); } /** * @dev change metadata uri * @param _newBaseURI new URI for metadata */ function setBaseURI(string memory _newBaseURI) external onlyOwner { baseURI = _newBaseURI; } /** * @dev Get token URI * @param tokenId ID of the token to retrieve */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "URI query for nonexistent token"); if (bytes(_tokenURIs[tokenId]).length == 0) { string memory currentBaseURI = _baseURI(); return bytes(currentBaseURI).length > 0 ? string( abi.encodePacked( currentBaseURI, Strings.toString(tokenId), ".json" ) ) : ""; } else return _tokenURIs[tokenId]; } /** * @dev wihdraw ETH from contract */ function withdraw() external onlyOwner { payable(owner()).transfer(address(this).balance); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"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"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"devMint","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":"uint256","name":"_amount","type":"uint256"}],"name":"getCost","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":"isWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintableAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"phaseToPrice","outputs":[{"internalType":"uint256","name":"editions","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","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":"toggleWhitelist","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"uint256","name":"_phaseNumber","type":"uint256"},{"internalType":"uint256","name":"_editions","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"updatePhase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052610378600a556001600b556001600f60006101000a81548160ff0219169083151502179055503480156200003757600080fd5b506040518060400160405280600681526020017f4e6562756c6100000000000000000000000000000000000000000000000000008152506040518060400160405280600681526020017f4e6562756c6100000000000000000000000000000000000000000000000000008152508160029080519060200190620000bc929190620002c0565b508060039080519060200190620000d5929190620002c0565b50620000e6620001e960201b60201c565b60008190555050506200010e62000102620001f260201b60201c565b620001fa60201b60201c565b60405180604001604052806101bc81526020016000815250600e6000600181526020019081526020016000206000820151816000015560208201518160010155905050604051806040016040528061029a8152602001667c585087238000815250600e60006002815260200190815260200160002060008201518160000155602082015181600101559050506040518060400160405280600a54815260200166c3663566a58000815250600e6000600381526020019081526020016000206000820151816000015560208201518160010155905050620003d5565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620002ce9062000370565b90600052602060002090601f016020900481019282620002f257600085556200033e565b82601f106200030d57805160ff19168380011785556200033e565b828001600101855582156200033e579182015b828111156200033d57825182559160200191906001019062000320565b5b5090506200034d919062000351565b5090565b5b808211156200036c57600081600090555060010162000352565b5090565b600060028204905060018216806200038957607f821691505b60208210811415620003a0576200039f620003a6565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b61329280620003e56000396000f3fe6080604052600436106101d85760003560e01c80636f8b44b011610102578063b88d4fde11610095578063d5abeb0111610064578063d5abeb0114610654578063e985e9c51461067f578063ece04c76146106bc578063f2fde38b146106e5576101d8565b8063b88d4fde146105b4578063ba41b0c6146105d0578063c87b56dd146105ec578063cba7539314610629576101d8565b80637e15144b116100d15780637e15144b1461051e5780638da5cb5b1461053557806395d89b4114610560578063a22cb4651461058b576101d8565b80636f8b44b01461047857806370a08231146104a1578063715018a6146104de5780637cb64759146104f5576101d8565b8063375a069a1161017a57806355f804b31161014957806355f804b3146103975780635a4dd47d146103c05780636352211e146103fd5780636d1a523b1461043a576101d8565b8063375a069a146103105780633ccfd60b146103395780634146ed0a1461035057806342842e0e1461037b576101d8565b8063095ea7b3116101b6578063095ea7b31461028257806318160ddd1461029e57806323b872dd146102c95780632eb4a7ab146102e5576101d8565b806301ffc9a7146101dd57806306fdde031461021a578063081812fc14610245575b600080fd5b3480156101e957600080fd5b5061020460048036038101906101ff91906125d3565b61070e565b6040516102119190612a11565b60405180910390f35b34801561022657600080fd5b5061022f6107a0565b60405161023c9190612a47565b60405180910390f35b34801561025157600080fd5b5061026c60048036038101906102679190612676565b610832565b60405161027991906129aa565b60405180910390f35b61029c60048036038101906102979190612566565b6108b1565b005b3480156102aa57600080fd5b506102b36109f5565b6040516102c09190612b49565b60405180910390f35b6102e360048036038101906102de9190612450565b610a0c565b005b3480156102f157600080fd5b506102fa610d31565b6040516103079190612a2c565b60405180910390f35b34801561031c57600080fd5b5061033760048036038101906103329190612676565b610d37565b005b34801561034557600080fd5b5061034e610d4c565b005b34801561035c57600080fd5b50610365610da4565b6040516103729190612a11565b60405180910390f35b61039560048036038101906103909190612450565b610db7565b005b3480156103a357600080fd5b506103be60048036038101906103b9919061262d565b610dd7565b005b3480156103cc57600080fd5b506103e760048036038101906103e29190612676565b610df9565b6040516103f49190612b49565b60405180910390f35b34801561040957600080fd5b50610424600480360381019061041f9190612676565b610e85565b60405161043191906129aa565b60405180910390f35b34801561044657600080fd5b50610461600480360381019061045c9190612676565b610e97565b60405161046f929190612b64565b60405180910390f35b34801561048457600080fd5b5061049f600480360381019061049a9190612676565b610ebb565b005b3480156104ad57600080fd5b506104c860048036038101906104c391906123e3565b610eeb565b6040516104d59190612b49565b60405180910390f35b3480156104ea57600080fd5b506104f3610fa4565b005b34801561050157600080fd5b5061051c600480360381019061051791906125a6565b610fb8565b005b34801561052a57600080fd5b50610533610fca565b005b34801561054157600080fd5b5061054a610ffe565b60405161055791906129aa565b60405180910390f35b34801561056c57600080fd5b50610575611028565b6040516105829190612a47565b60405180910390f35b34801561059757600080fd5b506105b260048036038101906105ad9190612526565b6110ba565b005b6105ce60048036038101906105c991906124a3565b6111c5565b005b6105ea60048036038101906105e591906126a3565b611238565b005b3480156105f857600080fd5b50610613600480360381019061060e9190612676565b6113dc565b6040516106209190612a47565b60405180910390f35b34801561063557600080fd5b5061063e61154f565b60405161064b9190612b49565b60405180910390f35b34801561066057600080fd5b50610669611555565b6040516106769190612b49565b60405180910390f35b34801561068b57600080fd5b506106a660048036038101906106a19190612410565b61155b565b6040516106b39190612a11565b60405180910390f35b3480156106c857600080fd5b506106e360048036038101906106de91906126ff565b6115ef565b005b3480156106f157600080fd5b5061070c600480360381019061070791906123e3565b61163b565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061076957506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107995750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6060600280546107af90612e58565b80601f01602080910402602001604051908101604052809291908181526020018280546107db90612e58565b80156108285780601f106107fd57610100808354040283529160200191610828565b820191906000526020600020905b81548152906001019060200180831161080b57829003601f168201915b5050505050905090565b600061083d826116bf565b610873576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006108bc82610e85565b90508073ffffffffffffffffffffffffffffffffffffffff166108dd61171e565b73ffffffffffffffffffffffffffffffffffffffff1614610940576109098161090461171e565b61155b565b61093f576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006109ff611726565b6001546000540303905090565b6000610a178261172f565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a7e576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610a8a846117fd565b91509150610aa08187610a9b61171e565b611824565b610aec57610ab586610ab061171e565b61155b565b610aeb576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610b53576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b608686866001611868565b8015610b6b57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610c3985610c1588888761186e565b7c020000000000000000000000000000000000000000000000000000000017611896565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084161415610cc1576000600185019050600060046000838152602001908152602001600020541415610cbf576000548114610cbe578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610d2986868660016118c1565b505050505050565b600d5481565b610d3f6118c7565b610d493382611945565b50565b610d546118c7565b610d5c610ffe565b73ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610da1573d6000803e3d6000fd5b50565b600f60009054906101000a900460ff1681565b610dd2838383604051806020016040528060008152506111c5565b505050565b610ddf6118c7565b8060099080519060200190610df5929190612144565b5050565b60008082610e056109f5565b610e0f9190612c83565b9050600080600190505b60038111610e5957600e6000828152602001908152602001600020600001548311610e4657809150610e59565b8080610e5190612ebb565b915050610e19565b5083600e600083815260200190815260200160002060010154610e7c9190612d0a565b92505050919050565b6000610e908261172f565b9050919050565b600e6020528060005260406000206000915090508060000154908060010154905082565b610ec36118c7565b80600a81905550600a54600e6000600381526020019081526020016000206000018190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f53576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b610fac6118c7565b610fb66000611963565b565b610fc06118c7565b80600d8190555050565b610fd26118c7565b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606003805461103790612e58565b80601f016020809104026020016040519081016040528092919081815260200182805461106390612e58565b80156110b05780601f10611085576101008083540402835291602001916110b0565b820191906000526020600020905b81548152906001019060200180831161109357829003601f168201915b5050505050905090565b80600760006110c761171e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661117461171e565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516111b99190612a11565b60405180910390a35050565b6111d0848484610a0c565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611232576111fb84848484611a29565b611231576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b818161124382610df9565b3414611284576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127b90612ae9565b60405180910390fd5b600a54826112906109f5565b61129a9190612c83565b11156112db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d290612b29565b60405180910390fd5b600e60006002815260200190815260200160002060000154826112fc6109f5565b6113069190612c83565b10156113cc57600f60009054906101000a900460ff16156113735761133361132d33611b89565b82611bb9565b611372576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136990612ac9565b60405180910390fd5b5b600b548261138033611bd0565b61138a9190612c83565b11156113cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c290612aa9565b60405180910390fd5b5b6113d63385611945565b50505050565b60606113e7826116bf565b611426576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141d90612a69565b60405180910390fd5b6000600c6000848152602001908152602001600020805461144690612e58565b905014156114ab576000611458611c27565b9050600081511161147857604051806020016040528060008152506114a3565b8061148284611cb9565b60405160200161149392919061297b565b6040516020818303038152906040525b91505061154a565b600c600083815260200190815260200160002080546114c990612e58565b80601f01602080910402602001604051908101604052809291908181526020018280546114f590612e58565b80156115425780601f1061151757610100808354040283529160200191611542565b820191906000526020600020905b81548152906001019060200180831161152557829003601f168201915b505050505090505b919050565b600b5481565b600a5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6115f76118c7565b604051806040016040528083815260200182815250600e60008581526020019081526020016000206000820151816000015560208201518160010155905050505050565b6116436118c7565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156116b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116aa90612a89565b60405180910390fd5b6116bc81611963565b50565b6000816116ca611726565b111580156116d9575060005482105b8015611717575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b6000808290508061173e611726565b116117c6576000548110156117c55760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821614156117c3575b60008114156117b957600460008360019003935083815260200190815260200160002054905061178e565b80925050506117f8565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611885868684611e1a565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6118cf611e23565b73ffffffffffffffffffffffffffffffffffffffff166118ed610ffe565b73ffffffffffffffffffffffffffffffffffffffff1614611943576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193a90612b09565b60405180910390fd5b565b61195f828260405180602001604052806000815250611e2b565b5050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611a4f61171e565b8786866040518563ffffffff1660e01b8152600401611a7194939291906129c5565b602060405180830381600087803b158015611a8b57600080fd5b505af1925050508015611abc57506040513d601f19601f82011682018060405250810190611ab99190612600565b60015b611b36573d8060008114611aec576040519150601f19603f3d011682016040523d82523d6000602084013e611af1565b606091505b50600081511415611b2e576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600081604051602001611b9c9190612960565b604051602081830303815290604052805190602001209050919050565b6000611bc882600d5485611ec8565b905092915050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b606060098054611c3690612e58565b80601f0160208091040260200160405190810160405280929190818152602001828054611c6290612e58565b8015611caf5780601f10611c8457610100808354040283529160200191611caf565b820191906000526020600020905b815481529060010190602001808311611c9257829003601f168201915b5050505050905090565b60606000821415611d01576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611e15565b600082905060005b60008214611d33578080611d1c90612ebb565b915050600a82611d2c9190612cd9565b9150611d09565b60008167ffffffffffffffff811115611d4f57611d4e613015565b5b6040519080825280601f01601f191660200182016040528015611d815781602001600182028036833780820191505090505b5090505b60008514611e0e57600182611d9a9190612d64565b9150600a85611da99190612f28565b6030611db59190612c83565b60f81b818381518110611dcb57611dca612fe6565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85611e079190612cd9565b9450611d85565b8093505050505b919050565b60009392505050565b600033905090565b611e358383611edf565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611ec357600080549050600083820390505b611e756000868380600101945086611a29565b611eab576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110611e62578160005414611ec057600080fd5b50505b505050565b600082611ed5858461209c565b1490509392505050565b6000805490506000821415611f20576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f2d6000848385611868565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611fa483611f95600086600061186e565b611f9e856120f2565b17611896565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461204557808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460018101905061200a565b506000821415612081576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061209760008483856118c1565b505050565b60008082905060005b84518110156120e7576120d2828683815181106120c5576120c4612fe6565b5b6020026020010151612102565b915080806120df90612ebb565b9150506120a5565b508091505092915050565b60006001821460e11b9050919050565b600081831061211a57612115828461212d565b612125565b612124838361212d565b5b905092915050565b600082600052816020526040600020905092915050565b82805461215090612e58565b90600052602060002090601f01602090048101928261217257600085556121b9565b82601f1061218b57805160ff19168380011785556121b9565b828001600101855582156121b9579182015b828111156121b857825182559160200191906001019061219d565b5b5090506121c691906121ca565b5090565b5b808211156121e35760008160009055506001016121cb565b5090565b60006121fa6121f584612bb2565b612b8d565b9050808382526020820190508285602086028201111561221d5761221c613049565b5b60005b8581101561224d57816122338882612333565b845260208401935060208301925050600181019050612220565b5050509392505050565b600061226a61226584612bde565b612b8d565b9050828152602081018484840111156122865761228561304e565b5b612291848285612e16565b509392505050565b60006122ac6122a784612c0f565b612b8d565b9050828152602081018484840111156122c8576122c761304e565b5b6122d3848285612e16565b509392505050565b6000813590506122ea816131e9565b92915050565b600082601f83011261230557612304613044565b5b81356123158482602086016121e7565b91505092915050565b60008135905061232d81613200565b92915050565b60008135905061234281613217565b92915050565b6000813590506123578161322e565b92915050565b60008151905061236c8161322e565b92915050565b600082601f83011261238757612386613044565b5b8135612397848260208601612257565b91505092915050565b600082601f8301126123b5576123b4613044565b5b81356123c5848260208601612299565b91505092915050565b6000813590506123dd81613245565b92915050565b6000602082840312156123f9576123f8613058565b5b6000612407848285016122db565b91505092915050565b6000806040838503121561242757612426613058565b5b6000612435858286016122db565b9250506020612446858286016122db565b9150509250929050565b60008060006060848603121561246957612468613058565b5b6000612477868287016122db565b9350506020612488868287016122db565b9250506040612499868287016123ce565b9150509250925092565b600080600080608085870312156124bd576124bc613058565b5b60006124cb878288016122db565b94505060206124dc878288016122db565b93505060406124ed878288016123ce565b925050606085013567ffffffffffffffff81111561250e5761250d613053565b5b61251a87828801612372565b91505092959194509250565b6000806040838503121561253d5761253c613058565b5b600061254b858286016122db565b925050602061255c8582860161231e565b9150509250929050565b6000806040838503121561257d5761257c613058565b5b600061258b858286016122db565b925050602061259c858286016123ce565b9150509250929050565b6000602082840312156125bc576125bb613058565b5b60006125ca84828501612333565b91505092915050565b6000602082840312156125e9576125e8613058565b5b60006125f784828501612348565b91505092915050565b60006020828403121561261657612615613058565b5b60006126248482850161235d565b91505092915050565b60006020828403121561264357612642613058565b5b600082013567ffffffffffffffff81111561266157612660613053565b5b61266d848285016123a0565b91505092915050565b60006020828403121561268c5761268b613058565b5b600061269a848285016123ce565b91505092915050565b600080604083850312156126ba576126b9613058565b5b60006126c8858286016123ce565b925050602083013567ffffffffffffffff8111156126e9576126e8613053565b5b6126f5858286016122f0565b9150509250929050565b60008060006060848603121561271857612717613058565b5b6000612726868287016123ce565b9350506020612737868287016123ce565b9250506040612748868287016123ce565b9150509250925092565b61275b81612d98565b82525050565b61277261276d82612d98565b612f04565b82525050565b61278181612daa565b82525050565b61279081612db6565b82525050565b60006127a182612c40565b6127ab8185612c56565b93506127bb818560208601612e25565b6127c48161305d565b840191505092915050565b60006127da82612c4b565b6127e48185612c67565b93506127f4818560208601612e25565b6127fd8161305d565b840191505092915050565b600061281382612c4b565b61281d8185612c78565b935061282d818560208601612e25565b80840191505092915050565b6000612846601f83612c67565b91506128518261307b565b602082019050919050565b6000612869602683612c67565b9150612874826130a4565b604082019050919050565b600061288c601383612c67565b9150612897826130f3565b602082019050919050565b60006128af600f83612c67565b91506128ba8261311c565b602082019050919050565b60006128d2601283612c67565b91506128dd82613145565b602082019050919050565b60006128f5600583612c78565b91506129008261316e565b600582019050919050565b6000612918602083612c67565b915061292382613197565b602082019050919050565b600061293b600883612c67565b9150612946826131c0565b602082019050919050565b61295a81612e0c565b82525050565b600061296c8284612761565b60148201915081905092915050565b60006129878285612808565b91506129938284612808565b915061299e826128e8565b91508190509392505050565b60006020820190506129bf6000830184612752565b92915050565b60006080820190506129da6000830187612752565b6129e76020830186612752565b6129f46040830185612951565b8181036060830152612a068184612796565b905095945050505050565b6000602082019050612a266000830184612778565b92915050565b6000602082019050612a416000830184612787565b92915050565b60006020820190508181036000830152612a6181846127cf565b905092915050565b60006020820190508181036000830152612a8281612839565b9050919050565b60006020820190508181036000830152612aa28161285c565b9050919050565b60006020820190508181036000830152612ac28161287f565b9050919050565b60006020820190508181036000830152612ae2816128a2565b9050919050565b60006020820190508181036000830152612b02816128c5565b9050919050565b60006020820190508181036000830152612b228161290b565b9050919050565b60006020820190508181036000830152612b428161292e565b9050919050565b6000602082019050612b5e6000830184612951565b92915050565b6000604082019050612b796000830185612951565b612b866020830184612951565b9392505050565b6000612b97612ba8565b9050612ba38282612e8a565b919050565b6000604051905090565b600067ffffffffffffffff821115612bcd57612bcc613015565b5b602082029050602081019050919050565b600067ffffffffffffffff821115612bf957612bf8613015565b5b612c028261305d565b9050602081019050919050565b600067ffffffffffffffff821115612c2a57612c29613015565b5b612c338261305d565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000612c8e82612e0c565b9150612c9983612e0c565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612cce57612ccd612f59565b5b828201905092915050565b6000612ce482612e0c565b9150612cef83612e0c565b925082612cff57612cfe612f88565b5b828204905092915050565b6000612d1582612e0c565b9150612d2083612e0c565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612d5957612d58612f59565b5b828202905092915050565b6000612d6f82612e0c565b9150612d7a83612e0c565b925082821015612d8d57612d8c612f59565b5b828203905092915050565b6000612da382612dec565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612e43578082015181840152602081019050612e28565b83811115612e52576000848401525b50505050565b60006002820490506001821680612e7057607f821691505b60208210811415612e8457612e83612fb7565b5b50919050565b612e938261305d565b810181811067ffffffffffffffff82111715612eb257612eb1613015565b5b80604052505050565b6000612ec682612e0c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612ef957612ef8612f59565b5b600182019050919050565b6000612f0f82612f16565b9050919050565b6000612f218261306e565b9050919050565b6000612f3382612e0c565b9150612f3e83612e0c565b925082612f4e57612f4d612f88565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e00600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f457863656564206d6178206d696e7461626c6500000000000000000000000000600082015250565b7f4e6f742077686974656c69737465640000000000000000000000000000000000600082015250565b7f496e76616c69642045544820616d6f756e740000000000000000000000000000600082015250565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f536f6c64206f7574000000000000000000000000000000000000000000000000600082015250565b6131f281612d98565b81146131fd57600080fd5b50565b61320981612daa565b811461321457600080fd5b50565b61322081612db6565b811461322b57600080fd5b50565b61323781612dc0565b811461324257600080fd5b50565b61324e81612e0c565b811461325957600080fd5b5056fea2646970667358221220642bbc12dc7de3f7f07b677eb3bc63d3683ec6b2630e550f1cb180294d764c5164736f6c63430008070033
Deployed Bytecode
0x6080604052600436106101d85760003560e01c80636f8b44b011610102578063b88d4fde11610095578063d5abeb0111610064578063d5abeb0114610654578063e985e9c51461067f578063ece04c76146106bc578063f2fde38b146106e5576101d8565b8063b88d4fde146105b4578063ba41b0c6146105d0578063c87b56dd146105ec578063cba7539314610629576101d8565b80637e15144b116100d15780637e15144b1461051e5780638da5cb5b1461053557806395d89b4114610560578063a22cb4651461058b576101d8565b80636f8b44b01461047857806370a08231146104a1578063715018a6146104de5780637cb64759146104f5576101d8565b8063375a069a1161017a57806355f804b31161014957806355f804b3146103975780635a4dd47d146103c05780636352211e146103fd5780636d1a523b1461043a576101d8565b8063375a069a146103105780633ccfd60b146103395780634146ed0a1461035057806342842e0e1461037b576101d8565b8063095ea7b3116101b6578063095ea7b31461028257806318160ddd1461029e57806323b872dd146102c95780632eb4a7ab146102e5576101d8565b806301ffc9a7146101dd57806306fdde031461021a578063081812fc14610245575b600080fd5b3480156101e957600080fd5b5061020460048036038101906101ff91906125d3565b61070e565b6040516102119190612a11565b60405180910390f35b34801561022657600080fd5b5061022f6107a0565b60405161023c9190612a47565b60405180910390f35b34801561025157600080fd5b5061026c60048036038101906102679190612676565b610832565b60405161027991906129aa565b60405180910390f35b61029c60048036038101906102979190612566565b6108b1565b005b3480156102aa57600080fd5b506102b36109f5565b6040516102c09190612b49565b60405180910390f35b6102e360048036038101906102de9190612450565b610a0c565b005b3480156102f157600080fd5b506102fa610d31565b6040516103079190612a2c565b60405180910390f35b34801561031c57600080fd5b5061033760048036038101906103329190612676565b610d37565b005b34801561034557600080fd5b5061034e610d4c565b005b34801561035c57600080fd5b50610365610da4565b6040516103729190612a11565b60405180910390f35b61039560048036038101906103909190612450565b610db7565b005b3480156103a357600080fd5b506103be60048036038101906103b9919061262d565b610dd7565b005b3480156103cc57600080fd5b506103e760048036038101906103e29190612676565b610df9565b6040516103f49190612b49565b60405180910390f35b34801561040957600080fd5b50610424600480360381019061041f9190612676565b610e85565b60405161043191906129aa565b60405180910390f35b34801561044657600080fd5b50610461600480360381019061045c9190612676565b610e97565b60405161046f929190612b64565b60405180910390f35b34801561048457600080fd5b5061049f600480360381019061049a9190612676565b610ebb565b005b3480156104ad57600080fd5b506104c860048036038101906104c391906123e3565b610eeb565b6040516104d59190612b49565b60405180910390f35b3480156104ea57600080fd5b506104f3610fa4565b005b34801561050157600080fd5b5061051c600480360381019061051791906125a6565b610fb8565b005b34801561052a57600080fd5b50610533610fca565b005b34801561054157600080fd5b5061054a610ffe565b60405161055791906129aa565b60405180910390f35b34801561056c57600080fd5b50610575611028565b6040516105829190612a47565b60405180910390f35b34801561059757600080fd5b506105b260048036038101906105ad9190612526565b6110ba565b005b6105ce60048036038101906105c991906124a3565b6111c5565b005b6105ea60048036038101906105e591906126a3565b611238565b005b3480156105f857600080fd5b50610613600480360381019061060e9190612676565b6113dc565b6040516106209190612a47565b60405180910390f35b34801561063557600080fd5b5061063e61154f565b60405161064b9190612b49565b60405180910390f35b34801561066057600080fd5b50610669611555565b6040516106769190612b49565b60405180910390f35b34801561068b57600080fd5b506106a660048036038101906106a19190612410565b61155b565b6040516106b39190612a11565b60405180910390f35b3480156106c857600080fd5b506106e360048036038101906106de91906126ff565b6115ef565b005b3480156106f157600080fd5b5061070c600480360381019061070791906123e3565b61163b565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061076957506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107995750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6060600280546107af90612e58565b80601f01602080910402602001604051908101604052809291908181526020018280546107db90612e58565b80156108285780601f106107fd57610100808354040283529160200191610828565b820191906000526020600020905b81548152906001019060200180831161080b57829003601f168201915b5050505050905090565b600061083d826116bf565b610873576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006108bc82610e85565b90508073ffffffffffffffffffffffffffffffffffffffff166108dd61171e565b73ffffffffffffffffffffffffffffffffffffffff1614610940576109098161090461171e565b61155b565b61093f576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006109ff611726565b6001546000540303905090565b6000610a178261172f565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a7e576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610a8a846117fd565b91509150610aa08187610a9b61171e565b611824565b610aec57610ab586610ab061171e565b61155b565b610aeb576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610b53576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b608686866001611868565b8015610b6b57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610c3985610c1588888761186e565b7c020000000000000000000000000000000000000000000000000000000017611896565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084161415610cc1576000600185019050600060046000838152602001908152602001600020541415610cbf576000548114610cbe578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610d2986868660016118c1565b505050505050565b600d5481565b610d3f6118c7565b610d493382611945565b50565b610d546118c7565b610d5c610ffe565b73ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610da1573d6000803e3d6000fd5b50565b600f60009054906101000a900460ff1681565b610dd2838383604051806020016040528060008152506111c5565b505050565b610ddf6118c7565b8060099080519060200190610df5929190612144565b5050565b60008082610e056109f5565b610e0f9190612c83565b9050600080600190505b60038111610e5957600e6000828152602001908152602001600020600001548311610e4657809150610e59565b8080610e5190612ebb565b915050610e19565b5083600e600083815260200190815260200160002060010154610e7c9190612d0a565b92505050919050565b6000610e908261172f565b9050919050565b600e6020528060005260406000206000915090508060000154908060010154905082565b610ec36118c7565b80600a81905550600a54600e6000600381526020019081526020016000206000018190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f53576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b610fac6118c7565b610fb66000611963565b565b610fc06118c7565b80600d8190555050565b610fd26118c7565b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606003805461103790612e58565b80601f016020809104026020016040519081016040528092919081815260200182805461106390612e58565b80156110b05780601f10611085576101008083540402835291602001916110b0565b820191906000526020600020905b81548152906001019060200180831161109357829003601f168201915b5050505050905090565b80600760006110c761171e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661117461171e565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516111b99190612a11565b60405180910390a35050565b6111d0848484610a0c565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611232576111fb84848484611a29565b611231576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b818161124382610df9565b3414611284576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127b90612ae9565b60405180910390fd5b600a54826112906109f5565b61129a9190612c83565b11156112db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d290612b29565b60405180910390fd5b600e60006002815260200190815260200160002060000154826112fc6109f5565b6113069190612c83565b10156113cc57600f60009054906101000a900460ff16156113735761133361132d33611b89565b82611bb9565b611372576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136990612ac9565b60405180910390fd5b5b600b548261138033611bd0565b61138a9190612c83565b11156113cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c290612aa9565b60405180910390fd5b5b6113d63385611945565b50505050565b60606113e7826116bf565b611426576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141d90612a69565b60405180910390fd5b6000600c6000848152602001908152602001600020805461144690612e58565b905014156114ab576000611458611c27565b9050600081511161147857604051806020016040528060008152506114a3565b8061148284611cb9565b60405160200161149392919061297b565b6040516020818303038152906040525b91505061154a565b600c600083815260200190815260200160002080546114c990612e58565b80601f01602080910402602001604051908101604052809291908181526020018280546114f590612e58565b80156115425780601f1061151757610100808354040283529160200191611542565b820191906000526020600020905b81548152906001019060200180831161152557829003601f168201915b505050505090505b919050565b600b5481565b600a5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6115f76118c7565b604051806040016040528083815260200182815250600e60008581526020019081526020016000206000820151816000015560208201518160010155905050505050565b6116436118c7565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156116b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116aa90612a89565b60405180910390fd5b6116bc81611963565b50565b6000816116ca611726565b111580156116d9575060005482105b8015611717575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b6000808290508061173e611726565b116117c6576000548110156117c55760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821614156117c3575b60008114156117b957600460008360019003935083815260200190815260200160002054905061178e565b80925050506117f8565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611885868684611e1a565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6118cf611e23565b73ffffffffffffffffffffffffffffffffffffffff166118ed610ffe565b73ffffffffffffffffffffffffffffffffffffffff1614611943576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193a90612b09565b60405180910390fd5b565b61195f828260405180602001604052806000815250611e2b565b5050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611a4f61171e565b8786866040518563ffffffff1660e01b8152600401611a7194939291906129c5565b602060405180830381600087803b158015611a8b57600080fd5b505af1925050508015611abc57506040513d601f19601f82011682018060405250810190611ab99190612600565b60015b611b36573d8060008114611aec576040519150601f19603f3d011682016040523d82523d6000602084013e611af1565b606091505b50600081511415611b2e576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600081604051602001611b9c9190612960565b604051602081830303815290604052805190602001209050919050565b6000611bc882600d5485611ec8565b905092915050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b606060098054611c3690612e58565b80601f0160208091040260200160405190810160405280929190818152602001828054611c6290612e58565b8015611caf5780601f10611c8457610100808354040283529160200191611caf565b820191906000526020600020905b815481529060010190602001808311611c9257829003601f168201915b5050505050905090565b60606000821415611d01576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611e15565b600082905060005b60008214611d33578080611d1c90612ebb565b915050600a82611d2c9190612cd9565b9150611d09565b60008167ffffffffffffffff811115611d4f57611d4e613015565b5b6040519080825280601f01601f191660200182016040528015611d815781602001600182028036833780820191505090505b5090505b60008514611e0e57600182611d9a9190612d64565b9150600a85611da99190612f28565b6030611db59190612c83565b60f81b818381518110611dcb57611dca612fe6565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85611e079190612cd9565b9450611d85565b8093505050505b919050565b60009392505050565b600033905090565b611e358383611edf565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611ec357600080549050600083820390505b611e756000868380600101945086611a29565b611eab576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110611e62578160005414611ec057600080fd5b50505b505050565b600082611ed5858461209c565b1490509392505050565b6000805490506000821415611f20576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f2d6000848385611868565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611fa483611f95600086600061186e565b611f9e856120f2565b17611896565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461204557808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460018101905061200a565b506000821415612081576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061209760008483856118c1565b505050565b60008082905060005b84518110156120e7576120d2828683815181106120c5576120c4612fe6565b5b6020026020010151612102565b915080806120df90612ebb565b9150506120a5565b508091505092915050565b60006001821460e11b9050919050565b600081831061211a57612115828461212d565b612125565b612124838361212d565b5b905092915050565b600082600052816020526040600020905092915050565b82805461215090612e58565b90600052602060002090601f01602090048101928261217257600085556121b9565b82601f1061218b57805160ff19168380011785556121b9565b828001600101855582156121b9579182015b828111156121b857825182559160200191906001019061219d565b5b5090506121c691906121ca565b5090565b5b808211156121e35760008160009055506001016121cb565b5090565b60006121fa6121f584612bb2565b612b8d565b9050808382526020820190508285602086028201111561221d5761221c613049565b5b60005b8581101561224d57816122338882612333565b845260208401935060208301925050600181019050612220565b5050509392505050565b600061226a61226584612bde565b612b8d565b9050828152602081018484840111156122865761228561304e565b5b612291848285612e16565b509392505050565b60006122ac6122a784612c0f565b612b8d565b9050828152602081018484840111156122c8576122c761304e565b5b6122d3848285612e16565b509392505050565b6000813590506122ea816131e9565b92915050565b600082601f83011261230557612304613044565b5b81356123158482602086016121e7565b91505092915050565b60008135905061232d81613200565b92915050565b60008135905061234281613217565b92915050565b6000813590506123578161322e565b92915050565b60008151905061236c8161322e565b92915050565b600082601f83011261238757612386613044565b5b8135612397848260208601612257565b91505092915050565b600082601f8301126123b5576123b4613044565b5b81356123c5848260208601612299565b91505092915050565b6000813590506123dd81613245565b92915050565b6000602082840312156123f9576123f8613058565b5b6000612407848285016122db565b91505092915050565b6000806040838503121561242757612426613058565b5b6000612435858286016122db565b9250506020612446858286016122db565b9150509250929050565b60008060006060848603121561246957612468613058565b5b6000612477868287016122db565b9350506020612488868287016122db565b9250506040612499868287016123ce565b9150509250925092565b600080600080608085870312156124bd576124bc613058565b5b60006124cb878288016122db565b94505060206124dc878288016122db565b93505060406124ed878288016123ce565b925050606085013567ffffffffffffffff81111561250e5761250d613053565b5b61251a87828801612372565b91505092959194509250565b6000806040838503121561253d5761253c613058565b5b600061254b858286016122db565b925050602061255c8582860161231e565b9150509250929050565b6000806040838503121561257d5761257c613058565b5b600061258b858286016122db565b925050602061259c858286016123ce565b9150509250929050565b6000602082840312156125bc576125bb613058565b5b60006125ca84828501612333565b91505092915050565b6000602082840312156125e9576125e8613058565b5b60006125f784828501612348565b91505092915050565b60006020828403121561261657612615613058565b5b60006126248482850161235d565b91505092915050565b60006020828403121561264357612642613058565b5b600082013567ffffffffffffffff81111561266157612660613053565b5b61266d848285016123a0565b91505092915050565b60006020828403121561268c5761268b613058565b5b600061269a848285016123ce565b91505092915050565b600080604083850312156126ba576126b9613058565b5b60006126c8858286016123ce565b925050602083013567ffffffffffffffff8111156126e9576126e8613053565b5b6126f5858286016122f0565b9150509250929050565b60008060006060848603121561271857612717613058565b5b6000612726868287016123ce565b9350506020612737868287016123ce565b9250506040612748868287016123ce565b9150509250925092565b61275b81612d98565b82525050565b61277261276d82612d98565b612f04565b82525050565b61278181612daa565b82525050565b61279081612db6565b82525050565b60006127a182612c40565b6127ab8185612c56565b93506127bb818560208601612e25565b6127c48161305d565b840191505092915050565b60006127da82612c4b565b6127e48185612c67565b93506127f4818560208601612e25565b6127fd8161305d565b840191505092915050565b600061281382612c4b565b61281d8185612c78565b935061282d818560208601612e25565b80840191505092915050565b6000612846601f83612c67565b91506128518261307b565b602082019050919050565b6000612869602683612c67565b9150612874826130a4565b604082019050919050565b600061288c601383612c67565b9150612897826130f3565b602082019050919050565b60006128af600f83612c67565b91506128ba8261311c565b602082019050919050565b60006128d2601283612c67565b91506128dd82613145565b602082019050919050565b60006128f5600583612c78565b91506129008261316e565b600582019050919050565b6000612918602083612c67565b915061292382613197565b602082019050919050565b600061293b600883612c67565b9150612946826131c0565b602082019050919050565b61295a81612e0c565b82525050565b600061296c8284612761565b60148201915081905092915050565b60006129878285612808565b91506129938284612808565b915061299e826128e8565b91508190509392505050565b60006020820190506129bf6000830184612752565b92915050565b60006080820190506129da6000830187612752565b6129e76020830186612752565b6129f46040830185612951565b8181036060830152612a068184612796565b905095945050505050565b6000602082019050612a266000830184612778565b92915050565b6000602082019050612a416000830184612787565b92915050565b60006020820190508181036000830152612a6181846127cf565b905092915050565b60006020820190508181036000830152612a8281612839565b9050919050565b60006020820190508181036000830152612aa28161285c565b9050919050565b60006020820190508181036000830152612ac28161287f565b9050919050565b60006020820190508181036000830152612ae2816128a2565b9050919050565b60006020820190508181036000830152612b02816128c5565b9050919050565b60006020820190508181036000830152612b228161290b565b9050919050565b60006020820190508181036000830152612b428161292e565b9050919050565b6000602082019050612b5e6000830184612951565b92915050565b6000604082019050612b796000830185612951565b612b866020830184612951565b9392505050565b6000612b97612ba8565b9050612ba38282612e8a565b919050565b6000604051905090565b600067ffffffffffffffff821115612bcd57612bcc613015565b5b602082029050602081019050919050565b600067ffffffffffffffff821115612bf957612bf8613015565b5b612c028261305d565b9050602081019050919050565b600067ffffffffffffffff821115612c2a57612c29613015565b5b612c338261305d565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000612c8e82612e0c565b9150612c9983612e0c565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612cce57612ccd612f59565b5b828201905092915050565b6000612ce482612e0c565b9150612cef83612e0c565b925082612cff57612cfe612f88565b5b828204905092915050565b6000612d1582612e0c565b9150612d2083612e0c565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612d5957612d58612f59565b5b828202905092915050565b6000612d6f82612e0c565b9150612d7a83612e0c565b925082821015612d8d57612d8c612f59565b5b828203905092915050565b6000612da382612dec565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612e43578082015181840152602081019050612e28565b83811115612e52576000848401525b50505050565b60006002820490506001821680612e7057607f821691505b60208210811415612e8457612e83612fb7565b5b50919050565b612e938261305d565b810181811067ffffffffffffffff82111715612eb257612eb1613015565b5b80604052505050565b6000612ec682612e0c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612ef957612ef8612f59565b5b600182019050919050565b6000612f0f82612f16565b9050919050565b6000612f218261306e565b9050919050565b6000612f3382612e0c565b9150612f3e83612e0c565b925082612f4e57612f4d612f88565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e00600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f457863656564206d6178206d696e7461626c6500000000000000000000000000600082015250565b7f4e6f742077686974656c69737465640000000000000000000000000000000000600082015250565b7f496e76616c69642045544820616d6f756e740000000000000000000000000000600082015250565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f536f6c64206f7574000000000000000000000000000000000000000000000000600082015250565b6131f281612d98565b81146131fd57600080fd5b50565b61320981612daa565b811461321457600080fd5b50565b61322081612db6565b811461322b57600080fd5b50565b61323781612dc0565b811461324257600080fd5b50565b61324e81612e0c565b811461325957600080fd5b5056fea2646970667358221220642bbc12dc7de3f7f07b677eb3bc63d3683ec6b2630e550f1cb180294d764c5164736f6c63430008070033
Deployed Bytecode Sourcemap
72080:5491:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38857:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39759:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46250:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45683:408;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35510:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49889:2825;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72410:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74863:102;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;77462:106;;;;;;;;;;;;;:::i;:::-;;72494:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52810:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76454:106;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74387:381;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41152:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72442:45;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;74133:149;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;36694:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19636:103;;;;;;;;;;;;;:::i;:::-;;75168:106;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73587:91;;;;;;;;;;;;;:::i;:::-;;18988:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39935:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46808:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53601:407;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76156:191;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76664:733;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72315:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72278:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47199:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73839:203;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;19894:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;38857:639;38942:4;39281:10;39266:25;;:11;:25;;;;:102;;;;39358:10;39343:25;;:11;:25;;;;39266:102;:179;;;;39435:10;39420:25;;:11;:25;;;;39266:179;39246:199;;38857:639;;;:::o;39759:100::-;39813:13;39846:5;39839:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39759:100;:::o;46250:218::-;46326:7;46351:16;46359:7;46351;:16::i;:::-;46346:64;;46376:34;;;;;;;;;;;;;;46346:64;46430:15;:24;46446:7;46430:24;;;;;;;;;;;:30;;;;;;;;;;;;46423:37;;46250:218;;;:::o;45683:408::-;45772:13;45788:16;45796:7;45788;:16::i;:::-;45772:32;;45844:5;45821:28;;:19;:17;:19::i;:::-;:28;;;45817:175;;45869:44;45886:5;45893:19;:17;:19::i;:::-;45869:16;:44::i;:::-;45864:128;;45941:35;;;;;;;;;;;;;;45864:128;45817:175;46037:2;46004:15;:24;46020:7;46004:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;46075:7;46071:2;46055:28;;46064:5;46055:28;;;;;;;;;;;;45761:330;45683:408;;:::o;35510:323::-;35571:7;35799:15;:13;:15::i;:::-;35784:12;;35768:13;;:28;:46;35761:53;;35510:323;:::o;49889:2825::-;50031:27;50061;50080:7;50061:18;:27::i;:::-;50031:57;;50146:4;50105:45;;50121:19;50105:45;;;50101:86;;50159:28;;;;;;;;;;;;;;50101:86;50201:27;50230:23;50257:35;50284:7;50257:26;:35::i;:::-;50200:92;;;;50392:68;50417:15;50434:4;50440:19;:17;:19::i;:::-;50392:24;:68::i;:::-;50387:180;;50480:43;50497:4;50503:19;:17;:19::i;:::-;50480:16;:43::i;:::-;50475:92;;50532:35;;;;;;;;;;;;;;50475:92;50387:180;50598:1;50584:16;;:2;:16;;;50580:52;;;50609:23;;;;;;;;;;;;;;50580:52;50645:43;50667:4;50673:2;50677:7;50686:1;50645:21;:43::i;:::-;50781:15;50778:160;;;50921:1;50900:19;50893:30;50778:160;51318:18;:24;51337:4;51318:24;;;;;;;;;;;;;;;;51316:26;;;;;;;;;;;;51387:18;:22;51406:2;51387:22;;;;;;;;;;;;;;;;51385:24;;;;;;;;;;;51709:146;51746:2;51795:45;51810:4;51816:2;51820:19;51795:14;:45::i;:::-;31909:8;51767:73;51709:18;:146::i;:::-;51680:17;:26;51698:7;51680:26;;;;;;;;;;;:175;;;;52026:1;31909:8;51975:19;:47;:52;51971:627;;;52048:19;52080:1;52070:7;:11;52048:33;;52237:1;52203:17;:30;52221:11;52203:30;;;;;;;;;;;;:35;52199:384;;;52341:13;;52326:11;:28;52322:242;;52521:19;52488:17;:30;52506:11;52488:30;;;;;;;;;;;:52;;;;52322:242;52199:384;52029:569;51971:627;52645:7;52641:2;52626:27;;52635:4;52626:27;;;;;;;;;;;;52664:42;52685:4;52691:2;52695:7;52704:1;52664:20;:42::i;:::-;50020:2694;;;49889:2825;;;:::o;72410:25::-;;;;:::o;74863:102::-;18874:13;:11;:13::i;:::-;74927:30:::1;74937:10;74949:7;74927:9;:30::i;:::-;74863:102:::0;:::o;77462:106::-;18874:13;:11;:13::i;:::-;77520:7:::1;:5;:7::i;:::-;77512:25;;:48;77538:21;77512:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;77462:106::o:0;72494:30::-;;;;;;;;;;;;;:::o;52810:193::-;52956:39;52973:4;52979:2;52983:7;52956:39;;;;;;;;;;;;:16;:39::i;:::-;52810:193;;;:::o;76454:106::-;18874:13;:11;:13::i;:::-;76541:11:::1;76531:7;:21;;;;;;;;;;;;:::i;:::-;;76454:106:::0;:::o;74387:381::-;74442:7;74462:14;74495:7;74479:13;:11;:13::i;:::-;:23;;;;:::i;:::-;74462:40;;74513:13;74544:9;74556:1;74544:13;;74539:167;74564:1;74559;:6;74539:167;;74601:12;:15;74614:1;74601:15;;;;;;;;;;;:24;;;74591:6;:34;74587:108;;74654:1;74646:9;;74674:5;;74587:108;74567:3;;;;;:::i;:::-;;;;74539:167;;;;74753:7;74725:12;:19;74738:5;74725:19;;;;;;;;;;;:25;;;:35;;;;:::i;:::-;74718:42;;;;74387:381;;;:::o;41152:152::-;41224:7;41267:27;41286:7;41267:18;:27::i;:::-;41244:52;;41152:152;;;:::o;72442:45::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;74133:149::-;18874:13;:11;:13::i;:::-;74217:10:::1;74205:9;:22;;;;74265:9;;74238:12;:15;74251:1;74238:15;;;;;;;;;;;:24;;:36;;;;74133:149:::0;:::o;36694:233::-;36766:7;36807:1;36790:19;;:5;:19;;;36786:60;;;36818:28;;;;;;;;;;;;;;36786:60;30853:13;36864:18;:25;36883:5;36864:25;;;;;;;;;;;;;;;;:55;36857:62;;36694:233;;;:::o;19636:103::-;18874:13;:11;:13::i;:::-;19701:30:::1;19728:1;19701:18;:30::i;:::-;19636:103::o:0;75168:106::-;18874:13;:11;:13::i;:::-;75255:11:::1;75242:10;:24;;;;75168:106:::0;:::o;73587:91::-;18874:13;:11;:13::i;:::-;73659:11:::1;;;;;;;;;;;73658:12;73644:11;;:26;;;;;;;;;;;;;;;;;;73587:91::o:0;18988:87::-;19034:7;19061:6;;;;;;;;;;;19054:13;;18988:87;:::o;39935:104::-;39991:13;40024:7;40017:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39935:104;:::o;46808:234::-;46955:8;46903:18;:39;46922:19;:17;:19::i;:::-;46903:39;;;;;;;;;;;;;;;:49;46943:8;46903:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;47015:8;46979:55;;46994:19;:17;:19::i;:::-;46979:55;;;47025:8;46979:55;;;;;;:::i;:::-;;;;;;;;46808:234;;:::o;53601:407::-;53776:31;53789:4;53795:2;53799:7;53776:12;:31::i;:::-;53840:1;53822:2;:14;;;:19;53818:183;;53861:56;53892:4;53898:2;53902:7;53911:5;53861:30;:56::i;:::-;53856:145;;53945:40;;;;;;;;;;;;;;53856:145;53818:183;53601:407;;;;:::o;76156:191::-;76276:7;76285:6;73061:16;73069:7;73061;:16::i;:::-;73048:9;:29;73040:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;73146:9;;73135:7;73119:13;:11;:13::i;:::-;:23;;;;:::i;:::-;:36;;73111:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;73209:12;:15;73222:1;73209:15;;;;;;;;;;;:24;;;73199:7;73183:13;:11;:13::i;:::-;:23;;;;:::i;:::-;:50;73179:333;;;73254:11;;;;;;;;;;;73250:96;;;73292:34;73300:17;73306:10;73300:5;:17::i;:::-;73319:6;73292:7;:34::i;:::-;73284:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;73250:96;73428:17;;73417:7;73389:25;73403:10;73389:13;:25::i;:::-;:35;;;;:::i;:::-;:56;;73363:137;;;;;;;;;;;;:::i;:::-;;;;;;;;;73179:333;76309:30:::1;76319:10;76331:7;76309:9;:30::i;:::-;76156:191:::0;;;;:::o;76664:733::-;76782:13;76821:16;76829:7;76821;:16::i;:::-;76813:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;76927:1;76896:10;:19;76907:7;76896:19;;;;;;;;;;;76890:33;;;;;:::i;:::-;;;:38;76886:503;;;76945:28;76976:10;:8;:10::i;:::-;76945:41;;77056:1;77031:14;77025:28;:32;:320;;;;;;;;;;;;;;;;;77161:14;77206:25;77223:7;77206:16;:25::i;:::-;77114:182;;;;;;;;;:::i;:::-;;;;;;;;;;;;;77025:320;77001:344;;;;;76886:503;77370:10;:19;77381:7;77370:19;;;;;;;;;;;77363:26;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76664:733;;;;:::o;72315:36::-;;;;:::o;72278:30::-;;;;:::o;47199:164::-;47296:4;47320:18;:25;47339:5;47320:25;;;;;;;;;;;;;;;:35;47346:8;47320:35;;;;;;;;;;;;;;;;;;;;;;;;;47313:42;;47199:164;;;;:::o;73839:203::-;18874:13;:11;:13::i;:::-;74010:24:::1;;;;;;;;74016:9;74010:24;;;;74027:6;74010:24;;::::0;73981:12:::1;:26;73994:12;73981:26;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;;73839:203:::0;;;:::o;19894:201::-;18874:13;:11;:13::i;:::-;20003:1:::1;19983:22;;:8;:22;;;;19975:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;20059:28;20078:8;20059:18;:28::i;:::-;19894:201:::0;:::o;47621:282::-;47686:4;47742:7;47723:15;:13;:15::i;:::-;:26;;:66;;;;;47776:13;;47766:7;:23;47723:66;:153;;;;;47875:1;31629:8;47827:17;:26;47845:7;47827:26;;;;;;;;;;;;:44;:49;47723:153;47703:173;;47621:282;;;:::o;69929:105::-;69989:7;70016:10;70009:17;;69929:105;:::o;74973:101::-;75038:7;75065:1;75058:8;;74973:101;:::o;42307:1275::-;42374:7;42394:12;42409:7;42394:22;;42477:4;42458:15;:13;:15::i;:::-;:23;42454:1061;;42511:13;;42504:4;:20;42500:1015;;;42549:14;42566:17;:23;42584:4;42566:23;;;;;;;;;;;;42549:40;;42683:1;31629:8;42655:6;:24;:29;42651:845;;;43320:113;43337:1;43327:6;:11;43320:113;;;43380:17;:25;43398:6;;;;;;;43380:25;;;;;;;;;;;;43371:34;;43320:113;;;43466:6;43459:13;;;;;;42651:845;42526:989;42500:1015;42454:1061;43543:31;;;;;;;;;;;;;;42307:1275;;;;:::o;48784:485::-;48886:27;48915:23;48956:38;48997:15;:24;49013:7;48997:24;;;;;;;;;;;48956:65;;49174:18;49151:41;;49231:19;49225:26;49206:45;;49136:126;48784:485;;;:::o;48012:659::-;48161:11;48326:16;48319:5;48315:28;48306:37;;48486:16;48475:9;48471:32;48458:45;;48636:15;48625:9;48622:30;48614:5;48603:9;48600:20;48597:56;48587:66;;48012:659;;;;;:::o;54670:159::-;;;;;:::o;69238:311::-;69373:7;69393:16;32033:3;69419:19;:41;;69393:68;;32033:3;69487:31;69498:4;69504:2;69508:9;69487:10;:31::i;:::-;69479:40;;:62;;69472:69;;;69238:311;;;;;:::o;44130:450::-;44210:14;44378:16;44371:5;44367:28;44358:37;;44555:5;44541:11;44516:23;44512:41;44509:52;44502:5;44499:63;44489:73;;44130:450;;;;:::o;55494:158::-;;;;;:::o;19153:132::-;19228:12;:10;:12::i;:::-;19217:23;;:7;:5;:7::i;:::-;:23;;;19209:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;19153:132::o;63761:112::-;63838:27;63848:2;63852:8;63838:27;;;;;;;;;;;;:9;:27::i;:::-;63761:112;;:::o;20255:191::-;20329:16;20348:6;;;;;;;;;;;20329:25;;20374:8;20365:6;;:17;;;;;;;;;;;;;;;;;;20429:8;20398:40;;20419:8;20398:40;;;;;;;;;;;;20318:128;20255:191;:::o;56092:716::-;56255:4;56301:2;56276:45;;;56322:19;:17;:19::i;:::-;56343:4;56349:7;56358:5;56276:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;56272:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56576:1;56559:6;:13;:18;56555:235;;;56605:40;;;;;;;;;;;;;;56555:235;56748:6;56742:13;56733:6;56729:2;56725:15;56718:38;56272:529;56445:54;;;56435:64;;;:6;:64;;;;56428:71;;;56092:716;;;;;;:::o;75393:124::-;75447:7;75501:6;75484:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;75474:35;;;;;;75467:42;;75393:124;;;:::o;75664:185::-;75769:4;75798:43;75817:5;75824:10;;75836:4;75798:18;:43::i;:::-;75791:50;;75664:185;;;;:::o;37009:178::-;37070:7;30853:13;30991:2;37098:18;:25;37117:5;37098:25;;;;;;;;;;;;;;;;:50;;37097:82;37090:89;;37009:178;;;:::o;75918:108::-;75978:13;76011:7;76004:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75918:108;:::o;14793:723::-;14849:13;15079:1;15070:5;:10;15066:53;;;15097:10;;;;;;;;;;;;;;;;;;;;;15066:53;15129:12;15144:5;15129:20;;15160:14;15185:78;15200:1;15192:4;:9;15185:78;;15218:8;;;;;:::i;:::-;;;;15249:2;15241:10;;;;;:::i;:::-;;;15185:78;;;15273:19;15305:6;15295:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15273:39;;15323:154;15339:1;15330:5;:10;15323:154;;15367:1;15357:11;;;;;:::i;:::-;;;15434:2;15426:5;:10;;;;:::i;:::-;15413:2;:24;;;;:::i;:::-;15400:39;;15383:6;15390;15383:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;15463:2;15454:11;;;;;:::i;:::-;;;15323:154;;;15501:6;15487:21;;;;;14793:723;;;;:::o;68939:147::-;69076:6;68939:147;;;;;:::o;17539:98::-;17592:7;17619:10;17612:17;;17539:98;:::o;62988:689::-;63119:19;63125:2;63129:8;63119:5;:19::i;:::-;63198:1;63180:2;:14;;;:19;63176:483;;63220:11;63234:13;;63220:27;;63266:13;63288:8;63282:3;:14;63266:30;;63315:233;63346:62;63385:1;63389:2;63393:7;;;;;;63402:5;63346:30;:62::i;:::-;63341:167;;63444:40;;;;;;;;;;;;;;63341:167;63543:3;63535:5;:11;63315:233;;63630:3;63613:13;;:20;63609:34;;63635:8;;;63609:34;63201:458;;63176:483;62988:689;;;:::o;1219:190::-;1344:4;1397;1368:25;1381:5;1388:4;1368:12;:25::i;:::-;:33;1361:40;;1219:190;;;;;:::o;57270:2966::-;57343:20;57366:13;;57343:36;;57406:1;57394:8;:13;57390:44;;;57416:18;;;;;;;;;;;;;;57390:44;57447:61;57477:1;57481:2;57485:12;57499:8;57447:21;:61::i;:::-;57991:1;30991:2;57961:1;:26;;57960:32;57948:8;:45;57922:18;:22;57941:2;57922:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;58270:139;58307:2;58361:33;58384:1;58388:2;58392:1;58361:14;:33::i;:::-;58328:30;58349:8;58328:20;:30::i;:::-;:66;58270:18;:139::i;:::-;58236:17;:31;58254:12;58236:31;;;;;;;;;;;:173;;;;58426:16;58457:11;58486:8;58471:12;:23;58457:37;;59007:16;59003:2;58999:25;58987:37;;59379:12;59339:8;59298:1;59236:25;59177:1;59116;59089:335;59750:1;59736:12;59732:20;59690:346;59791:3;59782:7;59779:16;59690:346;;60009:7;59999:8;59996:1;59969:25;59966:1;59963;59958:59;59844:1;59835:7;59831:15;59820:26;;59690:346;;;59694:77;60081:1;60069:8;:13;60065:45;;;60091:19;;;;;;;;;;;;;;60065:45;60143:3;60127:13;:19;;;;57696:2462;;60168:60;60197:1;60201:2;60205:12;60219:8;60168:20;:60::i;:::-;57332:2904;57270:2966;;:::o;2086:296::-;2169:7;2189:20;2212:4;2189:27;;2232:9;2227:118;2251:5;:12;2247:1;:16;2227:118;;;2300:33;2310:12;2324:5;2330:1;2324:8;;;;;;;;:::i;:::-;;;;;;;;2300:9;:33::i;:::-;2285:48;;2265:3;;;;;:::i;:::-;;;;2227:118;;;;2362:12;2355:19;;;2086:296;;;;:::o;44682:324::-;44752:14;44985:1;44975:8;44972:15;44946:24;44942:46;44932:56;;44682:324;;;:::o;8293:149::-;8356:7;8387:1;8383;:5;:51;;8414:20;8429:1;8432;8414:14;:20::i;:::-;8383:51;;;8391:20;8406:1;8409;8391:14;:20::i;:::-;8383:51;8376:58;;8293:149;;;;:::o;8450:268::-;8518:13;8625:1;8619:4;8612:15;8654:1;8648:4;8641:15;8695:4;8689;8679:21;8670:30;;8450:268;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;24:722:1:-;120:5;145:81;161:64;218:6;161:64;:::i;:::-;145:81;:::i;:::-;136:90;;246:5;275:6;268:5;261:21;309:4;302:5;298:16;291:23;;335:6;385:3;377:4;369:6;365:17;360:3;356:27;353:36;350:143;;;404:79;;:::i;:::-;350:143;517:1;502:238;527:6;524:1;521:13;502:238;;;595:3;624:37;657:3;645:10;624:37;:::i;:::-;619:3;612:50;691:4;686:3;682:14;675:21;;725:4;720:3;716:14;709:21;;562:178;549:1;546;542:9;537:14;;502:238;;;506:14;126:620;;24:722;;;;;:::o;752:410::-;829:5;854:65;870:48;911:6;870:48;:::i;:::-;854:65;:::i;:::-;845:74;;942:6;935:5;928:21;980:4;973:5;969:16;1018:3;1009:6;1004:3;1000:16;997:25;994:112;;;1025:79;;:::i;:::-;994:112;1115:41;1149:6;1144:3;1139;1115:41;:::i;:::-;835:327;752:410;;;;;:::o;1168:412::-;1246:5;1271:66;1287:49;1329:6;1287:49;:::i;:::-;1271:66;:::i;:::-;1262:75;;1360:6;1353:5;1346:21;1398:4;1391:5;1387:16;1436:3;1427:6;1422:3;1418:16;1415:25;1412:112;;;1443:79;;:::i;:::-;1412:112;1533:41;1567:6;1562:3;1557;1533:41;:::i;:::-;1252:328;1168:412;;;;;:::o;1586:139::-;1632:5;1670:6;1657:20;1648:29;;1686:33;1713:5;1686:33;:::i;:::-;1586:139;;;;:::o;1748:370::-;1819:5;1868:3;1861:4;1853:6;1849:17;1845:27;1835:122;;1876:79;;:::i;:::-;1835:122;1993:6;1980:20;2018:94;2108:3;2100:6;2093:4;2085:6;2081:17;2018:94;:::i;:::-;2009:103;;1825:293;1748:370;;;;:::o;2124:133::-;2167:5;2205:6;2192:20;2183:29;;2221:30;2245:5;2221:30;:::i;:::-;2124:133;;;;:::o;2263:139::-;2309:5;2347:6;2334:20;2325:29;;2363:33;2390:5;2363:33;:::i;:::-;2263:139;;;;:::o;2408:137::-;2453:5;2491:6;2478:20;2469:29;;2507:32;2533:5;2507:32;:::i;:::-;2408:137;;;;:::o;2551:141::-;2607:5;2638:6;2632:13;2623:22;;2654:32;2680:5;2654:32;:::i;:::-;2551:141;;;;:::o;2711:338::-;2766:5;2815:3;2808:4;2800:6;2796:17;2792:27;2782:122;;2823:79;;:::i;:::-;2782:122;2940:6;2927:20;2965:78;3039:3;3031:6;3024:4;3016:6;3012:17;2965:78;:::i;:::-;2956:87;;2772:277;2711:338;;;;:::o;3069:340::-;3125:5;3174:3;3167:4;3159:6;3155:17;3151:27;3141:122;;3182:79;;:::i;:::-;3141:122;3299:6;3286:20;3324:79;3399:3;3391:6;3384:4;3376:6;3372:17;3324:79;:::i;:::-;3315:88;;3131:278;3069:340;;;;:::o;3415:139::-;3461:5;3499:6;3486:20;3477:29;;3515:33;3542:5;3515:33;:::i;:::-;3415:139;;;;:::o;3560:329::-;3619:6;3668:2;3656:9;3647:7;3643:23;3639:32;3636:119;;;3674:79;;:::i;:::-;3636:119;3794:1;3819:53;3864:7;3855:6;3844:9;3840:22;3819:53;:::i;:::-;3809:63;;3765:117;3560:329;;;;:::o;3895:474::-;3963:6;3971;4020:2;4008:9;3999:7;3995:23;3991:32;3988:119;;;4026:79;;:::i;:::-;3988:119;4146:1;4171:53;4216:7;4207:6;4196:9;4192:22;4171:53;:::i;:::-;4161:63;;4117:117;4273:2;4299:53;4344:7;4335:6;4324:9;4320:22;4299:53;:::i;:::-;4289:63;;4244:118;3895:474;;;;;:::o;4375:619::-;4452:6;4460;4468;4517:2;4505:9;4496:7;4492:23;4488:32;4485:119;;;4523:79;;:::i;:::-;4485:119;4643:1;4668:53;4713:7;4704:6;4693:9;4689:22;4668:53;:::i;:::-;4658:63;;4614:117;4770:2;4796:53;4841:7;4832:6;4821:9;4817:22;4796:53;:::i;:::-;4786:63;;4741:118;4898:2;4924:53;4969:7;4960:6;4949:9;4945:22;4924:53;:::i;:::-;4914:63;;4869:118;4375:619;;;;;:::o;5000:943::-;5095:6;5103;5111;5119;5168:3;5156:9;5147:7;5143:23;5139:33;5136:120;;;5175:79;;:::i;:::-;5136:120;5295:1;5320:53;5365:7;5356:6;5345:9;5341:22;5320:53;:::i;:::-;5310:63;;5266:117;5422:2;5448:53;5493:7;5484:6;5473:9;5469:22;5448:53;:::i;:::-;5438:63;;5393:118;5550:2;5576:53;5621:7;5612:6;5601:9;5597:22;5576:53;:::i;:::-;5566:63;;5521:118;5706:2;5695:9;5691:18;5678:32;5737:18;5729:6;5726:30;5723:117;;;5759:79;;:::i;:::-;5723:117;5864:62;5918:7;5909:6;5898:9;5894:22;5864:62;:::i;:::-;5854:72;;5649:287;5000:943;;;;;;;:::o;5949:468::-;6014:6;6022;6071:2;6059:9;6050:7;6046:23;6042:32;6039:119;;;6077:79;;:::i;:::-;6039:119;6197:1;6222:53;6267:7;6258:6;6247:9;6243:22;6222:53;:::i;:::-;6212:63;;6168:117;6324:2;6350:50;6392:7;6383:6;6372:9;6368:22;6350:50;:::i;:::-;6340:60;;6295:115;5949:468;;;;;:::o;6423:474::-;6491:6;6499;6548:2;6536:9;6527:7;6523:23;6519:32;6516:119;;;6554:79;;:::i;:::-;6516:119;6674:1;6699:53;6744:7;6735:6;6724:9;6720:22;6699:53;:::i;:::-;6689:63;;6645:117;6801:2;6827:53;6872:7;6863:6;6852:9;6848:22;6827:53;:::i;:::-;6817:63;;6772:118;6423:474;;;;;:::o;6903:329::-;6962:6;7011:2;6999:9;6990:7;6986:23;6982:32;6979:119;;;7017:79;;:::i;:::-;6979:119;7137:1;7162:53;7207:7;7198:6;7187:9;7183:22;7162:53;:::i;:::-;7152:63;;7108:117;6903:329;;;;:::o;7238:327::-;7296:6;7345:2;7333:9;7324:7;7320:23;7316:32;7313:119;;;7351:79;;:::i;:::-;7313:119;7471:1;7496:52;7540:7;7531:6;7520:9;7516:22;7496:52;:::i;:::-;7486:62;;7442:116;7238:327;;;;:::o;7571:349::-;7640:6;7689:2;7677:9;7668:7;7664:23;7660:32;7657:119;;;7695:79;;:::i;:::-;7657:119;7815:1;7840:63;7895:7;7886:6;7875:9;7871:22;7840:63;:::i;:::-;7830:73;;7786:127;7571:349;;;;:::o;7926:509::-;7995:6;8044:2;8032:9;8023:7;8019:23;8015:32;8012:119;;;8050:79;;:::i;:::-;8012:119;8198:1;8187:9;8183:17;8170:31;8228:18;8220:6;8217:30;8214:117;;;8250:79;;:::i;:::-;8214:117;8355:63;8410:7;8401:6;8390:9;8386:22;8355:63;:::i;:::-;8345:73;;8141:287;7926:509;;;;:::o;8441:329::-;8500:6;8549:2;8537:9;8528:7;8524:23;8520:32;8517:119;;;8555:79;;:::i;:::-;8517:119;8675:1;8700:53;8745:7;8736:6;8725:9;8721:22;8700:53;:::i;:::-;8690:63;;8646:117;8441:329;;;;:::o;8776:684::-;8869:6;8877;8926:2;8914:9;8905:7;8901:23;8897:32;8894:119;;;8932:79;;:::i;:::-;8894:119;9052:1;9077:53;9122:7;9113:6;9102:9;9098:22;9077:53;:::i;:::-;9067:63;;9023:117;9207:2;9196:9;9192:18;9179:32;9238:18;9230:6;9227:30;9224:117;;;9260:79;;:::i;:::-;9224:117;9365:78;9435:7;9426:6;9415:9;9411:22;9365:78;:::i;:::-;9355:88;;9150:303;8776:684;;;;;:::o;9466:619::-;9543:6;9551;9559;9608:2;9596:9;9587:7;9583:23;9579:32;9576:119;;;9614:79;;:::i;:::-;9576:119;9734:1;9759:53;9804:7;9795:6;9784:9;9780:22;9759:53;:::i;:::-;9749:63;;9705:117;9861:2;9887:53;9932:7;9923:6;9912:9;9908:22;9887:53;:::i;:::-;9877:63;;9832:118;9989:2;10015:53;10060:7;10051:6;10040:9;10036:22;10015:53;:::i;:::-;10005:63;;9960:118;9466:619;;;;;:::o;10091:118::-;10178:24;10196:5;10178:24;:::i;:::-;10173:3;10166:37;10091:118;;:::o;10215:157::-;10320:45;10340:24;10358:5;10340:24;:::i;:::-;10320:45;:::i;:::-;10315:3;10308:58;10215:157;;:::o;10378:109::-;10459:21;10474:5;10459:21;:::i;:::-;10454:3;10447:34;10378:109;;:::o;10493:118::-;10580:24;10598:5;10580:24;:::i;:::-;10575:3;10568:37;10493:118;;:::o;10617:360::-;10703:3;10731:38;10763:5;10731:38;:::i;:::-;10785:70;10848:6;10843:3;10785:70;:::i;:::-;10778:77;;10864:52;10909:6;10904:3;10897:4;10890:5;10886:16;10864:52;:::i;:::-;10941:29;10963:6;10941:29;:::i;:::-;10936:3;10932:39;10925:46;;10707:270;10617:360;;;;:::o;10983:364::-;11071:3;11099:39;11132:5;11099:39;:::i;:::-;11154:71;11218:6;11213:3;11154:71;:::i;:::-;11147:78;;11234:52;11279:6;11274:3;11267:4;11260:5;11256:16;11234:52;:::i;:::-;11311:29;11333:6;11311:29;:::i;:::-;11306:3;11302:39;11295:46;;11075:272;10983:364;;;;:::o;11353:377::-;11459:3;11487:39;11520:5;11487:39;:::i;:::-;11542:89;11624:6;11619:3;11542:89;:::i;:::-;11535:96;;11640:52;11685:6;11680:3;11673:4;11666:5;11662:16;11640:52;:::i;:::-;11717:6;11712:3;11708:16;11701:23;;11463:267;11353:377;;;;:::o;11736:366::-;11878:3;11899:67;11963:2;11958:3;11899:67;:::i;:::-;11892:74;;11975:93;12064:3;11975:93;:::i;:::-;12093:2;12088:3;12084:12;12077:19;;11736:366;;;:::o;12108:::-;12250:3;12271:67;12335:2;12330:3;12271:67;:::i;:::-;12264:74;;12347:93;12436:3;12347:93;:::i;:::-;12465:2;12460:3;12456:12;12449:19;;12108:366;;;:::o;12480:::-;12622:3;12643:67;12707:2;12702:3;12643:67;:::i;:::-;12636:74;;12719:93;12808:3;12719:93;:::i;:::-;12837:2;12832:3;12828:12;12821:19;;12480:366;;;:::o;12852:::-;12994:3;13015:67;13079:2;13074:3;13015:67;:::i;:::-;13008:74;;13091:93;13180:3;13091:93;:::i;:::-;13209:2;13204:3;13200:12;13193:19;;12852:366;;;:::o;13224:::-;13366:3;13387:67;13451:2;13446:3;13387:67;:::i;:::-;13380:74;;13463:93;13552:3;13463:93;:::i;:::-;13581:2;13576:3;13572:12;13565:19;;13224:366;;;:::o;13596:400::-;13756:3;13777:84;13859:1;13854:3;13777:84;:::i;:::-;13770:91;;13870:93;13959:3;13870:93;:::i;:::-;13988:1;13983:3;13979:11;13972:18;;13596:400;;;:::o;14002:366::-;14144:3;14165:67;14229:2;14224:3;14165:67;:::i;:::-;14158:74;;14241:93;14330:3;14241:93;:::i;:::-;14359:2;14354:3;14350:12;14343:19;;14002:366;;;:::o;14374:365::-;14516:3;14537:66;14601:1;14596:3;14537:66;:::i;:::-;14530:73;;14612:93;14701:3;14612:93;:::i;:::-;14730:2;14725:3;14721:12;14714:19;;14374:365;;;:::o;14745:118::-;14832:24;14850:5;14832:24;:::i;:::-;14827:3;14820:37;14745:118;;:::o;14869:256::-;14981:3;14996:75;15067:3;15058:6;14996:75;:::i;:::-;15096:2;15091:3;15087:12;15080:19;;15116:3;15109:10;;14869:256;;;;:::o;15131:701::-;15412:3;15434:95;15525:3;15516:6;15434:95;:::i;:::-;15427:102;;15546:95;15637:3;15628:6;15546:95;:::i;:::-;15539:102;;15658:148;15802:3;15658:148;:::i;:::-;15651:155;;15823:3;15816:10;;15131:701;;;;;:::o;15838:222::-;15931:4;15969:2;15958:9;15954:18;15946:26;;15982:71;16050:1;16039:9;16035:17;16026:6;15982:71;:::i;:::-;15838:222;;;;:::o;16066:640::-;16261:4;16299:3;16288:9;16284:19;16276:27;;16313:71;16381:1;16370:9;16366:17;16357:6;16313:71;:::i;:::-;16394:72;16462:2;16451:9;16447:18;16438:6;16394:72;:::i;:::-;16476;16544:2;16533:9;16529:18;16520:6;16476:72;:::i;:::-;16595:9;16589:4;16585:20;16580:2;16569:9;16565:18;16558:48;16623:76;16694:4;16685:6;16623:76;:::i;:::-;16615:84;;16066:640;;;;;;;:::o;16712:210::-;16799:4;16837:2;16826:9;16822:18;16814:26;;16850:65;16912:1;16901:9;16897:17;16888:6;16850:65;:::i;:::-;16712:210;;;;:::o;16928:222::-;17021:4;17059:2;17048:9;17044:18;17036:26;;17072:71;17140:1;17129:9;17125:17;17116:6;17072:71;:::i;:::-;16928:222;;;;:::o;17156:313::-;17269:4;17307:2;17296:9;17292:18;17284:26;;17356:9;17350:4;17346:20;17342:1;17331:9;17327:17;17320:47;17384:78;17457:4;17448:6;17384:78;:::i;:::-;17376:86;;17156:313;;;;:::o;17475:419::-;17641:4;17679:2;17668:9;17664:18;17656:26;;17728:9;17722:4;17718:20;17714:1;17703:9;17699:17;17692:47;17756:131;17882:4;17756:131;:::i;:::-;17748:139;;17475:419;;;:::o;17900:::-;18066:4;18104:2;18093:9;18089:18;18081:26;;18153:9;18147:4;18143:20;18139:1;18128:9;18124:17;18117:47;18181:131;18307:4;18181:131;:::i;:::-;18173:139;;17900:419;;;:::o;18325:::-;18491:4;18529:2;18518:9;18514:18;18506:26;;18578:9;18572:4;18568:20;18564:1;18553:9;18549:17;18542:47;18606:131;18732:4;18606:131;:::i;:::-;18598:139;;18325:419;;;:::o;18750:::-;18916:4;18954:2;18943:9;18939:18;18931:26;;19003:9;18997:4;18993:20;18989:1;18978:9;18974:17;18967:47;19031:131;19157:4;19031:131;:::i;:::-;19023:139;;18750:419;;;:::o;19175:::-;19341:4;19379:2;19368:9;19364:18;19356:26;;19428:9;19422:4;19418:20;19414:1;19403:9;19399:17;19392:47;19456:131;19582:4;19456:131;:::i;:::-;19448:139;;19175:419;;;:::o;19600:::-;19766:4;19804:2;19793:9;19789:18;19781:26;;19853:9;19847:4;19843:20;19839:1;19828:9;19824:17;19817:47;19881:131;20007:4;19881:131;:::i;:::-;19873:139;;19600:419;;;:::o;20025:::-;20191:4;20229:2;20218:9;20214:18;20206:26;;20278:9;20272:4;20268:20;20264:1;20253:9;20249:17;20242:47;20306:131;20432:4;20306:131;:::i;:::-;20298:139;;20025:419;;;:::o;20450:222::-;20543:4;20581:2;20570:9;20566:18;20558:26;;20594:71;20662:1;20651:9;20647:17;20638:6;20594:71;:::i;:::-;20450:222;;;;:::o;20678:332::-;20799:4;20837:2;20826:9;20822:18;20814:26;;20850:71;20918:1;20907:9;20903:17;20894:6;20850:71;:::i;:::-;20931:72;20999:2;20988:9;20984:18;20975:6;20931:72;:::i;:::-;20678:332;;;;;:::o;21016:129::-;21050:6;21077:20;;:::i;:::-;21067:30;;21106:33;21134:4;21126:6;21106:33;:::i;:::-;21016:129;;;:::o;21151:75::-;21184:6;21217:2;21211:9;21201:19;;21151:75;:::o;21232:311::-;21309:4;21399:18;21391:6;21388:30;21385:56;;;21421:18;;:::i;:::-;21385:56;21471:4;21463:6;21459:17;21451:25;;21531:4;21525;21521:15;21513:23;;21232:311;;;:::o;21549:307::-;21610:4;21700:18;21692:6;21689:30;21686:56;;;21722:18;;:::i;:::-;21686:56;21760:29;21782:6;21760:29;:::i;:::-;21752:37;;21844:4;21838;21834:15;21826:23;;21549:307;;;:::o;21862:308::-;21924:4;22014:18;22006:6;22003:30;22000:56;;;22036:18;;:::i;:::-;22000:56;22074:29;22096:6;22074:29;:::i;:::-;22066:37;;22158:4;22152;22148:15;22140:23;;21862:308;;;:::o;22176:98::-;22227:6;22261:5;22255:12;22245:22;;22176:98;;;:::o;22280:99::-;22332:6;22366:5;22360:12;22350:22;;22280:99;;;:::o;22385:168::-;22468:11;22502:6;22497:3;22490:19;22542:4;22537:3;22533:14;22518:29;;22385:168;;;;:::o;22559:169::-;22643:11;22677:6;22672:3;22665:19;22717:4;22712:3;22708:14;22693:29;;22559:169;;;;:::o;22734:148::-;22836:11;22873:3;22858:18;;22734:148;;;;:::o;22888:305::-;22928:3;22947:20;22965:1;22947:20;:::i;:::-;22942:25;;22981:20;22999:1;22981:20;:::i;:::-;22976:25;;23135:1;23067:66;23063:74;23060:1;23057:81;23054:107;;;23141:18;;:::i;:::-;23054:107;23185:1;23182;23178:9;23171:16;;22888:305;;;;:::o;23199:185::-;23239:1;23256:20;23274:1;23256:20;:::i;:::-;23251:25;;23290:20;23308:1;23290:20;:::i;:::-;23285:25;;23329:1;23319:35;;23334:18;;:::i;:::-;23319:35;23376:1;23373;23369:9;23364:14;;23199:185;;;;:::o;23390:348::-;23430:7;23453:20;23471:1;23453:20;:::i;:::-;23448:25;;23487:20;23505:1;23487:20;:::i;:::-;23482:25;;23675:1;23607:66;23603:74;23600:1;23597:81;23592:1;23585:9;23578:17;23574:105;23571:131;;;23682:18;;:::i;:::-;23571:131;23730:1;23727;23723:9;23712:20;;23390:348;;;;:::o;23744:191::-;23784:4;23804:20;23822:1;23804:20;:::i;:::-;23799:25;;23838:20;23856:1;23838:20;:::i;:::-;23833:25;;23877:1;23874;23871:8;23868:34;;;23882:18;;:::i;:::-;23868:34;23927:1;23924;23920:9;23912:17;;23744:191;;;;:::o;23941:96::-;23978:7;24007:24;24025:5;24007:24;:::i;:::-;23996:35;;23941:96;;;:::o;24043:90::-;24077:7;24120:5;24113:13;24106:21;24095:32;;24043:90;;;:::o;24139:77::-;24176:7;24205:5;24194:16;;24139:77;;;:::o;24222:149::-;24258:7;24298:66;24291:5;24287:78;24276:89;;24222:149;;;:::o;24377:126::-;24414:7;24454:42;24447:5;24443:54;24432:65;;24377:126;;;:::o;24509:77::-;24546:7;24575:5;24564:16;;24509:77;;;:::o;24592:154::-;24676:6;24671:3;24666;24653:30;24738:1;24729:6;24724:3;24720:16;24713:27;24592:154;;;:::o;24752:307::-;24820:1;24830:113;24844:6;24841:1;24838:13;24830:113;;;24929:1;24924:3;24920:11;24914:18;24910:1;24905:3;24901:11;24894:39;24866:2;24863:1;24859:10;24854:15;;24830:113;;;24961:6;24958:1;24955:13;24952:101;;;25041:1;25032:6;25027:3;25023:16;25016:27;24952:101;24801:258;24752:307;;;:::o;25065:320::-;25109:6;25146:1;25140:4;25136:12;25126:22;;25193:1;25187:4;25183:12;25214:18;25204:81;;25270:4;25262:6;25258:17;25248:27;;25204:81;25332:2;25324:6;25321:14;25301:18;25298:38;25295:84;;;25351:18;;:::i;:::-;25295:84;25116:269;25065:320;;;:::o;25391:281::-;25474:27;25496:4;25474:27;:::i;:::-;25466:6;25462:40;25604:6;25592:10;25589:22;25568:18;25556:10;25553:34;25550:62;25547:88;;;25615:18;;:::i;:::-;25547:88;25655:10;25651:2;25644:22;25434:238;25391:281;;:::o;25678:233::-;25717:3;25740:24;25758:5;25740:24;:::i;:::-;25731:33;;25786:66;25779:5;25776:77;25773:103;;;25856:18;;:::i;:::-;25773:103;25903:1;25896:5;25892:13;25885:20;;25678:233;;;:::o;25917:100::-;25956:7;25985:26;26005:5;25985:26;:::i;:::-;25974:37;;25917:100;;;:::o;26023:94::-;26062:7;26091:20;26105:5;26091:20;:::i;:::-;26080:31;;26023:94;;;:::o;26123:176::-;26155:1;26172:20;26190:1;26172:20;:::i;:::-;26167:25;;26206:20;26224:1;26206:20;:::i;:::-;26201:25;;26245:1;26235:35;;26250:18;;:::i;:::-;26235:35;26291:1;26288;26284:9;26279:14;;26123:176;;;;:::o;26305:180::-;26353:77;26350:1;26343:88;26450:4;26447:1;26440:15;26474:4;26471:1;26464:15;26491:180;26539:77;26536:1;26529:88;26636:4;26633:1;26626:15;26660:4;26657:1;26650:15;26677:180;26725:77;26722:1;26715:88;26822:4;26819:1;26812:15;26846:4;26843:1;26836:15;26863:180;26911:77;26908:1;26901:88;27008:4;27005:1;26998:15;27032:4;27029:1;27022:15;27049:180;27097:77;27094:1;27087:88;27194:4;27191:1;27184:15;27218:4;27215:1;27208:15;27235:117;27344:1;27341;27334:12;27358:117;27467:1;27464;27457:12;27481:117;27590:1;27587;27580:12;27604:117;27713:1;27710;27703:12;27727:117;27836:1;27833;27826:12;27850:102;27891:6;27942:2;27938:7;27933:2;27926:5;27922:14;27918:28;27908:38;;27850:102;;;:::o;27958:94::-;27991:8;28039:5;28035:2;28031:14;28010:35;;27958:94;;;:::o;28058:181::-;28198:33;28194:1;28186:6;28182:14;28175:57;28058:181;:::o;28245:225::-;28385:34;28381:1;28373:6;28369:14;28362:58;28454:8;28449:2;28441:6;28437:15;28430:33;28245:225;:::o;28476:169::-;28616:21;28612:1;28604:6;28600:14;28593:45;28476:169;:::o;28651:165::-;28791:17;28787:1;28779:6;28775:14;28768:41;28651:165;:::o;28822:168::-;28962:20;28958:1;28950:6;28946:14;28939:44;28822:168;:::o;28996:155::-;29136:7;29132:1;29124:6;29120:14;29113:31;28996:155;:::o;29157:182::-;29297:34;29293:1;29285:6;29281:14;29274:58;29157:182;:::o;29345:158::-;29485:10;29481:1;29473:6;29469:14;29462:34;29345:158;:::o;29509:122::-;29582:24;29600:5;29582:24;:::i;:::-;29575:5;29572:35;29562:63;;29621:1;29618;29611:12;29562:63;29509:122;:::o;29637:116::-;29707:21;29722:5;29707:21;:::i;:::-;29700:5;29697:32;29687:60;;29743:1;29740;29733:12;29687:60;29637:116;:::o;29759:122::-;29832:24;29850:5;29832:24;:::i;:::-;29825:5;29822:35;29812:63;;29871:1;29868;29861:12;29812:63;29759:122;:::o;29887:120::-;29959:23;29976:5;29959:23;:::i;:::-;29952:5;29949:34;29939:62;;29997:1;29994;29987:12;29939:62;29887:120;:::o;30013:122::-;30086:24;30104:5;30086:24;:::i;:::-;30079:5;30076:35;30066:63;;30125:1;30122;30115:12;30066:63;30013:122;:::o
Swarm Source
ipfs://642bbc12dc7de3f7f07b677eb3bc63d3683ec6b2630e550f1cb180294d764c51
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.