Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 27 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Mint | 21405676 | 453 days ago | IN | 0 ETH | 0.00023778 | ||||
| Mint | 21292415 | 469 days ago | IN | 0 ETH | 0.00057897 | ||||
| Mint | 21290058 | 469 days ago | IN | 0 ETH | 0.00050052 | ||||
| Mint | 21170322 | 486 days ago | IN | 0 ETH | 0.00074667 | ||||
| Mint | 21170156 | 486 days ago | IN | 0 ETH | 0.00083421 | ||||
| Mint | 21170153 | 486 days ago | IN | 0 ETH | 0.00083402 | ||||
| Mint | 21170143 | 486 days ago | IN | 0 ETH | 0.00084453 | ||||
| Mint | 21170137 | 486 days ago | IN | 0 ETH | 0.00081092 | ||||
| Mint | 21170097 | 486 days ago | IN | 0 ETH | 0.0008563 | ||||
| Mint | 21170061 | 486 days ago | IN | 0 ETH | 0.00216371 | ||||
| Set Approval For... | 20974801 | 513 days ago | IN | 0 ETH | 0.00056855 | ||||
| Set Approval For... | 20849878 | 530 days ago | IN | 0 ETH | 0.00035648 | ||||
| Mint | 20825994 | 534 days ago | IN | 0 ETH | 0.00098017 | ||||
| Set Approval For... | 20825183 | 534 days ago | IN | 0 ETH | 0.00054021 | ||||
| Mint | 20825033 | 534 days ago | IN | 0 ETH | 0.00102609 | ||||
| Mint | 20824941 | 534 days ago | IN | 0 ETH | 0.00116512 | ||||
| Mint | 20824686 | 534 days ago | IN | 0 ETH | 0.00104262 | ||||
| Mint | 20824671 | 534 days ago | IN | 0 ETH | 0.0006075 | ||||
| Mint | 20824671 | 534 days ago | IN | 0 ETH | 0.00145585 | ||||
| Mint | 20820204 | 535 days ago | IN | 0 ETH | 0.00110115 | ||||
| Mint | 20819996 | 535 days ago | IN | 0 ETH | 0.001314 | ||||
| Mint | 20818737 | 535 days ago | IN | 0 ETH | 0.00103876 | ||||
| Mint | 20817653 | 535 days ago | IN | 0 ETH | 0.00116737 | ||||
| Mint | 20817390 | 535 days ago | IN | 0 ETH | 0.0015246 | ||||
| Mint | 20619925 | 563 days ago | IN | 0 ETH | 0.00015642 |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Wombat66
Compiler Version
v0.8.26+commit.8a97fa7a
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2024-08-27
*/
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
pragma solidity ^0.8.20;
/**
* @dev Interface for the NFT Royalty Standard.
*
* A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
* support for royalty payments across all NFT marketplaces and ecosystem participants.
*/
interface IERC2981 is IERC165 {
/**
* @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
* exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
*/
function royaltyInfo(
uint256 tokenId,
uint256 salePrice
) external view returns (address receiver, uint256 royaltyAmount);
}
pragma solidity ^0.8.20;
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
pragma solidity ^0.8.20;
/**
* @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
*
* Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
* specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
*
* Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
* fee is specified in basis points by default.
*
* IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
* https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
* voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
*/
abstract contract ERC2981 is IERC2981, ERC165 {
struct RoyaltyInfo {
address receiver;
uint96 royaltyFraction;
}
RoyaltyInfo private _defaultRoyaltyInfo;
mapping(uint256 tokenId => RoyaltyInfo) private _tokenRoyaltyInfo;
/**
* @dev The default royalty set is invalid (eg. (numerator / denominator) >= 1).
*/
error ERC2981InvalidDefaultRoyalty(uint256 numerator, uint256 denominator);
/**
* @dev The default royalty receiver is invalid.
*/
error ERC2981InvalidDefaultRoyaltyReceiver(address receiver);
/**
* @dev The royalty set for an specific `tokenId` is invalid (eg. (numerator / denominator) >= 1).
*/
error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator);
/**
* @dev The royalty receiver for `tokenId` is invalid.
*/
error ERC2981InvalidTokenRoyaltyReceiver(uint256 tokenId, address receiver);
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @inheritdoc IERC2981
*/
function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual returns (address, uint256) {
RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];
if (royalty.receiver == address(0)) {
royalty = _defaultRoyaltyInfo;
}
uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();
return (royalty.receiver, royaltyAmount);
}
/**
* @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
* fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
* override.
*/
function _feeDenominator() internal pure virtual returns (uint96) {
return 10000;
}
/**
* @dev Sets the royalty information that all ids in this contract will default to.
*
* Requirements:
*
* - `receiver` cannot be the zero address.
* - `feeNumerator` cannot be greater than the fee denominator.
*/
function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
uint256 denominator = _feeDenominator();
if (feeNumerator > denominator) {
// Royalty fee will exceed the sale price
revert ERC2981InvalidDefaultRoyalty(feeNumerator, denominator);
}
if (receiver == address(0)) {
revert ERC2981InvalidDefaultRoyaltyReceiver(address(0));
}
_defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
}
/**
* @dev Removes default royalty information.
*/
function _deleteDefaultRoyalty() internal virtual {
delete _defaultRoyaltyInfo;
}
/**
* @dev Sets the royalty information for a specific token id, overriding the global default.
*
* Requirements:
*
* - `receiver` cannot be the zero address.
* - `feeNumerator` cannot be greater than the fee denominator.
*/
function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {
uint256 denominator = _feeDenominator();
if (feeNumerator > denominator) {
// Royalty fee will exceed the sale price
revert ERC2981InvalidTokenRoyalty(tokenId, feeNumerator, denominator);
}
if (receiver == address(0)) {
revert ERC2981InvalidTokenRoyaltyReceiver(tokenId, address(0));
}
_tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
}
/**
* @dev Resets royalty information for the token id back to the global default.
*/
function _resetTokenRoyalty(uint256 tokenId) internal virtual {
delete _tokenRoyaltyInfo[tokenId];
}
}
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();
/**
* `_sequentialUpTo()` must be greater than `_startTokenId()`.
*/
error SequentialUpToTooSmall();
/**
* The `tokenId` of a sequential mint exceeds `_sequentialUpTo()`.
*/
error SequentialMintExceedsLimit();
/**
* Spot minting requires a `tokenId` greater than `_sequentialUpTo()`.
*/
error SpotMintTokenIdTooSmall();
/**
* Cannot mint over a token that already exists.
*/
error TokenAlreadyExists();
/**
* The feature is not compatible with spot mints.
*/
error NotCompatibleWithSpotMints();
// =============================================================
// 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.3.0
// 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()`.
*
* The `_sequentialUpTo()` function can be overriden to enable spot mints
* (i.e. non-consecutive mints) for `tokenId`s greater than `_sequentialUpTo()`.
*
* 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;
// The amount of tokens minted above `_sequentialUpTo()`.
// We call these spot mints (i.e. non-sequential mints).
uint256 private _spotMinted;
// =============================================================
// CONSTRUCTOR
// =============================================================
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
_currentIndex = _startTokenId();
if (_sequentialUpTo() < _startTokenId()) _revert(SequentialUpToTooSmall.selector);
}
// =============================================================
// TOKEN COUNTING OPERATIONS
// =============================================================
/**
* @dev Returns the starting token ID for sequential mints.
*
* Override this function to change the starting token ID for sequential mints.
*
* Note: The value returned must never change after any tokens have been minted.
*/
function _startTokenId() internal view virtual returns (uint256) {
return 0;
}
/**
* @dev Returns the maximum token ID (inclusive) for sequential mints.
*
* Override this function to return a value less than 2**256 - 1,
* but greater than `_startTokenId()`, to enable spot (non-sequential) mints.
*
* Note: The value returned must never change after any tokens have been minted.
*/
function _sequentialUpTo() internal view virtual returns (uint256) {
return type(uint256).max;
}
/**
* @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 result) {
// Counter underflow is impossible as `_burnCounter` cannot be incremented
// more than `_currentIndex + _spotMinted - _startTokenId()` times.
unchecked {
// With spot minting, the intermediate `result` can be temporarily negative,
// and the computation must be unchecked.
result = _currentIndex - _burnCounter - _startTokenId();
if (_sequentialUpTo() != type(uint256).max) result += _spotMinted;
}
}
/**
* @dev Returns the total amount of tokens minted in the contract.
*/
function _totalMinted() internal view virtual returns (uint256 result) {
// Counter underflow is impossible as `_currentIndex` does not decrement,
// and it is initialized to `_startTokenId()`.
unchecked {
result = _currentIndex - _startTokenId();
if (_sequentialUpTo() != type(uint256).max) result += _spotMinted;
}
}
/**
* @dev Returns the total number of tokens burned.
*/
function _totalBurned() internal view virtual returns (uint256) {
return _burnCounter;
}
/**
* @dev Returns the total number of tokens that are spot-minted.
*/
function _totalSpotMinted() internal view virtual returns (uint256) {
return _spotMinted;
}
// =============================================================
// 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.selector);
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.selector);
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 Returns whether the ownership slot at `index` is initialized.
* An uninitialized slot does not necessarily mean that the slot has no owner.
*/
function _ownershipIsInitialized(uint256 index) internal view virtual returns (bool) {
return _packedOwnerships[index] != 0;
}
/**
* @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);
}
}
/**
* @dev Returns the packed ownership data of `tokenId`.
*/
function _packedOwnershipOf(uint256 tokenId) private view returns (uint256 packed) {
if (_startTokenId() <= tokenId) {
packed = _packedOwnerships[tokenId];
if (tokenId > _sequentialUpTo()) {
if (_packedOwnershipExists(packed)) return packed;
_revert(OwnerQueryForNonexistentToken.selector);
}
// If the data at the starting slot does not exist, start the scan.
if (packed == 0) {
if (tokenId >= _currentIndex) _revert(OwnerQueryForNonexistentToken.selector);
// 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, `tokenId` will not underflow.
//
// We can directly compare the packed value.
// If the address is zero, packed will be zero.
for (;;) {
unchecked {
packed = _packedOwnerships[--tokenId];
}
if (packed == 0) continue;
if (packed & _BITMASK_BURNED == 0) return packed;
// Otherwise, the token is burned, and we must revert.
// This handles the case of batch burned tokens, where only the burned bit
// of the starting slot is set, and remaining slots are left uninitialized.
_revert(OwnerQueryForNonexistentToken.selector);
}
}
// Otherwise, the data exists and we can skip the scan.
// This is possible because we have already achieved the target condition.
// This saves 2143 gas on transfers of initialized tokens.
// If the token is not burned, return `packed`. Otherwise, revert.
if (packed & _BITMASK_BURNED == 0) return packed;
}
_revert(OwnerQueryForNonexistentToken.selector);
}
/**
* @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. See {ERC721A-_approve}.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
*/
function approve(address to, uint256 tokenId) public payable virtual override {
_approve(to, tokenId, true);
}
/**
* @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.selector);
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 result) {
if (_startTokenId() <= tokenId) {
if (tokenId > _sequentialUpTo()) return _packedOwnershipExists(_packedOwnerships[tokenId]);
if (tokenId < _currentIndex) {
uint256 packed;
while ((packed = _packedOwnerships[tokenId]) == 0) --tokenId;
result = packed & _BITMASK_BURNED == 0;
}
}
}
/**
* @dev Returns whether `packed` represents a token that exists.
*/
function _packedOwnershipExists(uint256 packed) private pure returns (bool result) {
assembly {
// The following is equivalent to `owner != address(0) && burned == false`.
// Symbolically tested.
result := gt(and(packed, _BITMASK_ADDRESS), and(packed, _BITMASK_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);
// Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean.
from = address(uint160(uint256(uint160(from)) & _BITMASK_ADDRESS));
if (address(uint160(prevOwnershipPacked)) != from) _revert(TransferFromIncorrectOwner.selector);
(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.selector);
_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;
}
}
}
}
// Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;
assembly {
// 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.
from, // `from`.
toMasked, // `to`.
tokenId // `tokenId`.
)
}
if (toMasked == 0) _revert(TransferToZeroAddress.selector);
_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.selector);
}
}
/**
* @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.selector);
}
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.selector);
_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:
// - `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)
);
// Updates:
// - `balance += quantity`.
// - `numberMinted += quantity`.
//
// We can directly add to the `balance` and `numberMinted`.
_packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);
// Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;
if (toMasked == 0) _revert(MintToZeroAddress.selector);
uint256 end = startTokenId + quantity;
uint256 tokenId = startTokenId;
if (end - 1 > _sequentialUpTo()) _revert(SequentialMintExceedsLimit.selector);
do {
assembly {
// 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`.
tokenId // `tokenId`.
)
}
// The `!=` check ensures that large values of `quantity`
// that overflows uint256 will make the loop run out of gas.
} while (++tokenId != end);
_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.selector);
if (quantity == 0) _revert(MintZeroQuantity.selector);
if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) _revert(MintERC2309QuantityExceedsLimit.selector);
_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)
);
if (startTokenId + quantity - 1 > _sequentialUpTo()) _revert(SequentialMintExceedsLimit.selector);
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.selector);
}
} while (index < end);
// This prevents reentrancy to `_safeMint`.
// It does not prevent reentrancy to `_safeMintSpot`.
if (_currentIndex != end) revert();
}
}
}
/**
* @dev Equivalent to `_safeMint(to, quantity, '')`.
*/
function _safeMint(address to, uint256 quantity) internal virtual {
_safeMint(to, quantity, '');
}
/**
* @dev Mints a single token at `tokenId`.
*
* Note: A spot-minted `tokenId` that has been burned can be re-minted again.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` must be greater than `_sequentialUpTo()`.
* - `tokenId` must not exist.
*
* Emits a {Transfer} event for each mint.
*/
function _mintSpot(address to, uint256 tokenId) internal virtual {
if (tokenId <= _sequentialUpTo()) _revert(SpotMintTokenIdTooSmall.selector);
uint256 prevOwnershipPacked = _packedOwnerships[tokenId];
if (_packedOwnershipExists(prevOwnershipPacked)) _revert(TokenAlreadyExists.selector);
_beforeTokenTransfers(address(0), to, tokenId, 1);
// Overflows are incredibly unrealistic.
// The `numberMinted` for `to` is incremented by 1, and has a max limit of 2**64 - 1.
// `_spotMinted` is incremented by 1, and has a max limit of 2**256 - 1.
unchecked {
// Updates:
// - `address` to the owner.
// - `startTimestamp` to the timestamp of minting.
// - `burned` to `false`.
// - `nextInitialized` to `true` (as `quantity == 1`).
_packedOwnerships[tokenId] = _packOwnershipData(
to,
_nextInitializedFlag(1) | _nextExtraData(address(0), to, prevOwnershipPacked)
);
// Updates:
// - `balance += 1`.
// - `numberMinted += 1`.
//
// We can directly add to the `balance` and `numberMinted`.
_packedAddressData[to] += (1 << _BITPOS_NUMBER_MINTED) | 1;
// Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;
if (toMasked == 0) _revert(MintToZeroAddress.selector);
assembly {
// 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`.
tokenId // `tokenId`.
)
}
++_spotMinted;
}
_afterTokenTransfers(address(0), to, tokenId, 1);
}
/**
* @dev Safely mints a single token at `tokenId`.
*
* Note: A spot-minted `tokenId` that has been burned can be re-minted again.
*
* Requirements:
*
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}.
* - `tokenId` must be greater than `_sequentialUpTo()`.
* - `tokenId` must not exist.
*
* See {_mintSpot}.
*
* Emits a {Transfer} event.
*/
function _safeMintSpot(
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_mintSpot(to, tokenId);
unchecked {
if (to.code.length != 0) {
uint256 currentSpotMinted = _spotMinted;
if (!_checkContractOnERC721Received(address(0), to, tokenId, _data)) {
_revert(TransferToNonERC721ReceiverImplementer.selector);
}
// This prevents reentrancy to `_safeMintSpot`.
// It does not prevent reentrancy to `_safeMint`.
if (_spotMinted != currentSpotMinted) revert();
}
}
}
/**
* @dev Equivalent to `_safeMintSpot(to, tokenId, '')`.
*/
function _safeMintSpot(address to, uint256 tokenId) internal virtual {
_safeMintSpot(to, tokenId, '');
}
// =============================================================
// APPROVAL OPERATIONS
// =============================================================
/**
* @dev Equivalent to `_approve(to, tokenId, false)`.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_approve(to, tokenId, false);
}
/**
* @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:
*
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function _approve(
address to,
uint256 tokenId,
bool approvalCheck
) internal virtual {
address owner = ownerOf(tokenId);
if (approvalCheck && _msgSenderERC721A() != owner)
if (!isApprovedForAll(owner, _msgSenderERC721A())) {
_revert(ApprovalCallerNotOwnerNorApproved.selector);
}
_tokenApprovals[tokenId].value = to;
emit Approval(owner, to, tokenId);
}
// =============================================================
// 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.selector);
}
_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 + _spotMinted` 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.selector);
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)
}
}
/**
* @dev For more efficient reverts.
*/
function _revert(bytes4 errorSelector) internal pure {
assembly {
mstore(0x00, errorSelector)
revert(0x00, 0x04)
}
}
}
// File: @openzeppelin/contracts/utils/Context.sol
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
// File: @openzeppelin/contracts/access/Ownable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
// File: @openzeppelin/contracts/utils/math/Math.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
* @dev Muldiv operation overflow.
*/
error MathOverflowedMulDiv();
enum Rounding {
Floor, // Toward negative infinity
Ceil, // Toward positive infinity
Trunc, // Toward zero
Expand // Away from zero
}
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds towards infinity instead
* of rounding towards zero.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
if (b == 0) {
// Guarantee the same behavior as in a regular Solidity division.
return a / b;
}
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
* denominator == 0.
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
* Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0 = x * y; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
if (denominator <= prod1) {
revert MathOverflowedMulDiv();
}
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator.
// Always >= 1. See https://cs.stackexchange.com/q/138556/92363.
uint256 twos = denominator & (0 - denominator);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
// works in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
* towards zero.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256 of a positive value rounded towards zero.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
}
}
/**
* @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
*/
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
}
// File: @openzeppelin/contracts/utils/math/SignedMath.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard signed math utilities missing in the Solidity language.
*/
library SignedMath {
/**
* @dev Returns the largest of two signed numbers.
*/
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two signed numbers.
*/
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two signed numbers without overflow.
* The result is rounded towards zero.
*/
function average(int256 a, int256 b) internal pure returns (int256) {
// Formula from the book "Hacker's Delight"
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
/**
* @dev Returns the absolute unsigned value of a signed value.
*/
function abs(int256 n) internal pure returns (uint256) {
unchecked {
// must be unchecked in order to support `n = type(int256).min`
return uint256(n >= 0 ? n : -n);
}
}
}
// File: @openzeppelin/contracts/utils/Strings.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)
pragma solidity ^0.8.20;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant HEX_DIGITS = "0123456789abcdef";
uint8 private constant ADDRESS_LENGTH = 20;
/**
* @dev The `value` string doesn't fit in the specified `length`.
*/
error StringsInsufficientHexLength(uint256 value, uint256 length);
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `int256` to its ASCII `string` decimal representation.
*/
function toStringSigned(int256 value) internal pure returns (string memory) {
return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
uint256 localValue = value;
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = HEX_DIGITS[localValue & 0xf];
localValue >>= 4;
}
if (localValue != 0) {
revert StringsInsufficientHexLength(value, length);
}
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal
* representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);
}
/**
* @dev Returns true if the two strings are equal.
*/
function equal(string memory a, string memory b) internal pure returns (bool) {
return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
}
}
pragma solidity ^0.8.11;
contract Wombat66 is ERC721A, ERC2981, Ownable {
bool public isActive = false;
string public _baseTokenURI;
uint256 public mintPerWallet = 1;
uint256 public constant MAX_SUPPLY = 6_666;
constructor(string memory baseURI) ERC721A("Wombat66", "WMB") Ownable(msg.sender){
setBaseURI(baseURI);
_setDefaultRoyalty(_msgSender(), 1000); // Set default royalty to 10%
}
modifier onlyAuthorized() {
require(owner() == msg.sender);
_;
}
modifier canMintAmount(uint256 _count) {
uint256 currentSupply = totalSupply();
require(currentSupply + _count <= MAX_SUPPLY, "Exceeds maximum supply limit.");
_;
}
function setDefaultRoyalty(address receiver, uint96 feeNumerator) external onlyOwner {
_setDefaultRoyalty(receiver, feeNumerator);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721A, ERC2981) returns (bool) {
return super.supportsInterface(interfaceId);
}
function toggleSale() public onlyAuthorized {
isActive = !isActive;
}
function setBaseURI(string memory baseURI) public onlyAuthorized {
_baseTokenURI = baseURI;
}
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
function getMintPerWallet() public view returns (uint256) {
return mintPerWallet;
}
function batchAirdrop(uint256 _count, address[] calldata addresses) external onlyAuthorized canMintAmount(_count * addresses.length){
for (uint256 i = 0; i < addresses.length; i ++) {
require(addresses[i] != address(0), "Can't add a null address");
_safeMint(addresses[i], _count);
}
}
function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {
require(_exists(_tokenId), "Token Id Non-existent");
return bytes(_baseURI()).length > 0 ? string(abi.encodePacked(_baseURI(), Strings.toString(_tokenId), ".json")) : "";
}
function _startTokenId() internal view virtual override returns (uint256) {
return 1;
}
function mint(uint256 _count) public canMintAmount(_count){
if (msg.sender != owner()) {
require(isActive, "Sale is not active currently.");
require(balanceOf(msg.sender) + _count <= mintPerWallet, "Mint per wallet exceeded");
}
_safeMint(msg.sender, _count);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidDefaultRoyalty","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidTokenRoyalty","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidTokenRoyaltyReceiver","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"NotCompatibleWithSpotMints","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"SequentialMintExceedsLimit","type":"error"},{"inputs":[],"name":"SequentialUpToTooSmall","type":"error"},{"inputs":[],"name":"SpotMintTokenIdTooSmall","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","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":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_count","type":"uint256"},{"internalType":"address[]","name":"addresses","type":"address[]"}],"name":"batchAirdrop","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":[],"name":"getMintPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","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":"toggleSale","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":"result","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"}]Contract Creation Code
60806040525f600b60146101000a81548160ff0219169083151502179055506001600d5534801561002e575f80fd5b50604051613daa380380613daa83398181016040528101906100509190610656565b336040518060400160405280600881526020017f576f6d62617436360000000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f574d42000000000000000000000000000000000000000000000000000000000081525081600290816100cc91906108aa565b5080600390816100dc91906108aa565b506100eb6101df60201b60201c565b5f819055506100fe6101df60201b60201c565b61010c6101e760201b60201c565b10156101295761012863fed8210f60e01b61020e60201b60201c565b5b50505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361019b575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161019291906109b8565b60405180910390fd5b6101aa8161021660201b60201c565b506101ba816102d960201b60201c565b6101d96101cb61033060201b60201c565b6103e861033760201b60201c565b50610a4e565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b805f5260045ffd5b5f600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b3373ffffffffffffffffffffffffffffffffffffffff166102fe6104d860201b60201c565b73ffffffffffffffffffffffffffffffffffffffff161461031d575f80fd5b80600c908161032c91906108aa565b5050565b5f33905090565b5f61034661050060201b60201c565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff1611156103ab5781816040517f6f483d090000000000000000000000000000000000000000000000000000000081526004016103a2929190610a27565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361041b575f6040517fb6d9900a00000000000000000000000000000000000000000000000000000000815260040161041291906109b8565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff1681525060095f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b5f600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f612710905090565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61056882610522565b810181811067ffffffffffffffff8211171561058757610586610532565b5b80604052505050565b5f610599610509565b90506105a5828261055f565b919050565b5f67ffffffffffffffff8211156105c4576105c3610532565b5b6105cd82610522565b9050602081019050919050565b8281835e5f83830152505050565b5f6105fa6105f5846105aa565b610590565b9050828152602081018484840111156106165761061561051e565b5b6106218482856105da565b509392505050565b5f82601f83011261063d5761063c61051a565b5b815161064d8482602086016105e8565b91505092915050565b5f6020828403121561066b5761066a610512565b5b5f82015167ffffffffffffffff81111561068857610687610516565b5b61069484828501610629565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806106eb57607f821691505b6020821081036106fe576106fd6106a7565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026107607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610725565b61076a8683610725565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6107ae6107a96107a484610782565b61078b565b610782565b9050919050565b5f819050919050565b6107c783610794565b6107db6107d3826107b5565b848454610731565b825550505050565b5f90565b6107ef6107e3565b6107fa8184846107be565b505050565b5b8181101561081d576108125f826107e7565b600181019050610800565b5050565b601f8211156108625761083381610704565b61083c84610716565b8101602085101561084b578190505b61085f61085785610716565b8301826107ff565b50505b505050565b5f82821c905092915050565b5f6108825f1984600802610867565b1980831691505092915050565b5f61089a8383610873565b9150826002028217905092915050565b6108b38261069d565b67ffffffffffffffff8111156108cc576108cb610532565b5b6108d682546106d4565b6108e1828285610821565b5f60209050601f831160018114610912575f8415610900578287015190505b61090a858261088f565b865550610971565b601f19841661092086610704565b5f5b8281101561094757848901518255600182019150602085019450602081019050610922565b868310156109645784890151610960601f891682610873565b8355505b6001600288020188555050505b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6109a282610979565b9050919050565b6109b281610998565b82525050565b5f6020820190506109cb5f8301846109a9565b92915050565b5f6bffffffffffffffffffffffff82169050919050565b5f610a026109fd6109f8846109d1565b61078b565b610782565b9050919050565b610a12816109e8565b82525050565b610a2181610782565b82525050565b5f604082019050610a3a5f830185610a09565b610a476020830184610a18565b9392505050565b61334f80610a5b5f395ff3fe6080604052600436106101b6575f3560e01c8063700c35d2116100eb578063a22cb46511610089578063cfc86f7b11610063578063cfc86f7b146105af578063e985e9c5146105d9578063f2fde38b14610615578063fb7e6ccb1461063d576101b6565b8063a22cb4651461052f578063b88d4fde14610557578063c87b56dd14610573576101b6565b80637d8966e4116100c55780637d8966e41461049d5780638da5cb5b146104b357806395d89b41146104dd578063a0712d6814610507576101b6565b8063700c35d21461042157806370a082311461044b578063715018a614610487576101b6565b806322f3e2d41161015857806332cb6b0c1161013257806332cb6b0c1461037757806342842e0e146103a157806355f804b3146103bd5780636352211e146103e5576101b6565b806322f3e2d4146102f457806323b872dd1461031e5780632a55205a1461033a576101b6565b8063081812fc11610194578063081812fc14610248578063083c81be14610284578063095ea7b3146102ae57806318160ddd146102ca576101b6565b806301ffc9a7146101ba57806304634d8d146101f657806306fdde031461021e575b5f80fd5b3480156101c5575f80fd5b506101e060048036038101906101db919061238e565b610665565b6040516101ed91906123d3565b60405180910390f35b348015610201575f80fd5b5061021c60048036038101906102179190612487565b610676565b005b348015610229575f80fd5b5061023261068c565b60405161023f9190612535565b60405180910390f35b348015610253575f80fd5b5061026e60048036038101906102699190612588565b61071c565b60405161027b91906125c2565b60405180910390f35b34801561028f575f80fd5b50610298610775565b6040516102a591906125ea565b60405180910390f35b6102c860048036038101906102c39190612603565b61077e565b005b3480156102d5575f80fd5b506102de61078e565b6040516102eb91906125ea565b60405180910390f35b3480156102ff575f80fd5b506103086107d9565b60405161031591906123d3565b60405180910390f35b61033860048036038101906103339190612641565b6107ec565b005b348015610345575f80fd5b50610360600480360381019061035b9190612691565b610a97565b60405161036e9291906126cf565b60405180910390f35b348015610382575f80fd5b5061038b610c73565b60405161039891906125ea565b60405180910390f35b6103bb60048036038101906103b69190612641565b610c79565b005b3480156103c8575f80fd5b506103e360048036038101906103de9190612822565b610c98565b005b3480156103f0575f80fd5b5061040b60048036038101906104069190612588565b610ce9565b60405161041891906125c2565b60405180910390f35b34801561042c575f80fd5b50610435610cfa565b60405161044291906125ea565b60405180910390f35b348015610456575f80fd5b50610471600480360381019061046c9190612869565b610d00565b60405161047e91906125ea565b60405180910390f35b348015610492575f80fd5b5061049b610d94565b005b3480156104a8575f80fd5b506104b1610da7565b005b3480156104be575f80fd5b506104c7610e11565b6040516104d491906125c2565b60405180910390f35b3480156104e8575f80fd5b506104f1610e39565b6040516104fe9190612535565b60405180910390f35b348015610512575f80fd5b5061052d60048036038101906105289190612588565b610ec9565b005b34801561053a575f80fd5b50610555600480360381019061055091906128be565b611016565b005b610571600480360381019061056c919061299a565b61111c565b005b34801561057e575f80fd5b5061059960048036038101906105949190612588565b61116d565b6040516105a69190612535565b60405180910390f35b3480156105ba575f80fd5b506105c3611213565b6040516105d09190612535565b60405180910390f35b3480156105e4575f80fd5b506105ff60048036038101906105fa9190612a1a565b61129f565b60405161060c91906123d3565b60405180910390f35b348015610620575f80fd5b5061063b60048036038101906106369190612869565b61132d565b005b348015610648575f80fd5b50610663600480360381019061065e9190612ab5565b6113b1565b005b5f61066f82611541565b9050919050565b61067e6115ba565b6106888282611641565b5050565b60606002805461069b90612b3f565b80601f01602080910402602001604051908101604052809291908181526020018280546106c790612b3f565b80156107125780601f106106e957610100808354040283529160200191610712565b820191905f5260205f20905b8154815290600101906020018083116106f557829003601f168201915b5050505050905090565b5f610726826117dc565b61073b5761073a63cf4700e460e01b61187f565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f600d54905090565b61078a82826001611887565b5050565b5f6107976119b1565b6001545f54030390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6107c96119b9565b146107d657600854810190505b90565b600b60149054906101000a900460ff1681565b5f6107f6826119e0565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461086b5761086a63a114810060e01b61187f565b5b5f8061087684611aef565b9150915061088c8187610887611b12565b611b19565b6108b7576108a18661089c611b12565b61129f565b6108b6576108b56359c896be60e01b61187f565b5b5b6108c48686866001611b5c565b80156108ce575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f81546001019190508190555061099685610972888887611b62565b7c020000000000000000000000000000000000000000000000000000000017611b89565b60045f8681526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000841603610a12575f6001850190505f60045f8381526020019081526020015f205403610a10575f548114610a0f578360045f8381526020019081526020015f20819055505b5b505b5f73ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45f8103610a8157610a8063ea553b3460e01b61187f565b5b610a8e8787876001611bb3565b50505050505050565b5f805f600a5f8681526020019081526020015f206040518060400160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505f73ffffffffffffffffffffffffffffffffffffffff16815f015173ffffffffffffffffffffffffffffffffffffffff1603610c205760096040518060400160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b5f610c29611bb9565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610c559190612b9c565b610c5f9190612c0a565b9050815f0151819350935050509250929050565b611a0a81565b610c9383838360405180602001604052805f81525061111c565b505050565b3373ffffffffffffffffffffffffffffffffffffffff16610cb7610e11565b73ffffffffffffffffffffffffffffffffffffffff1614610cd6575f80fd5b80600c9081610ce59190612dd7565b5050565b5f610cf3826119e0565b9050919050565b600d5481565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610d4557610d44638f4eb60460e01b61187f565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b610d9c6115ba565b610da55f611bc2565b565b3373ffffffffffffffffffffffffffffffffffffffff16610dc6610e11565b73ffffffffffffffffffffffffffffffffffffffff1614610de5575f80fd5b600b60149054906101000a900460ff1615600b60146101000a81548160ff021916908315150217905550565b5f600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054610e4890612b3f565b80601f0160208091040260200160405190810160405280929190818152602001828054610e7490612b3f565b8015610ebf5780601f10610e9657610100808354040283529160200191610ebf565b820191905f5260205f20905b815481529060010190602001808311610ea257829003601f168201915b5050505050905090565b805f610ed361078e565b9050611a0a8282610ee49190612ea6565b1115610f25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1c90612f23565b60405180910390fd5b610f2d610e11565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461100757600b60149054906101000a900460ff16610fae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fa590612f8b565b60405180910390fd5b600d5483610fbb33610d00565b610fc59190612ea6565b1115611006576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ffd90612ff3565b60405180910390fd5b5b6110113384611c85565b505050565b8060075f611022611b12565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166110cb611b12565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161111091906123d3565b60405180910390a35050565b6111278484846107ec565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146111675761115184848484611ca2565b6111665761116563d1a57ed660e01b61187f565b5b5b50505050565b6060611178826117dc565b6111b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ae9061305b565b60405180910390fd5b5f6111c0611dcc565b51116111da5760405180602001604052805f81525061120c565b6111e2611dcc565b6111eb83611e5c565b6040516020016111fc9291906130fd565b6040516020818303038152906040525b9050919050565b600c805461122090612b3f565b80601f016020809104026020016040519081016040528092919081815260200182805461124c90612b3f565b80156112975780601f1061126e57610100808354040283529160200191611297565b820191905f5260205f20905b81548152906001019060200180831161127a57829003601f168201915b505050505081565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b6113356115ba565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113a5575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161139c91906125c2565b60405180910390fd5b6113ae81611bc2565b50565b3373ffffffffffffffffffffffffffffffffffffffff166113d0610e11565b73ffffffffffffffffffffffffffffffffffffffff16146113ef575f80fd5b81819050836113fe9190612b9c565b5f61140761078e565b9050611a0a82826114189190612ea6565b1115611459576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145090612f23565b60405180910390fd5b5f5b84849050811015611539575f73ffffffffffffffffffffffffffffffffffffffff168585838181106114905761148f61312b565b5b90506020020160208101906114a59190612869565b73ffffffffffffffffffffffffffffffffffffffff16036114fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f2906131a2565b60405180910390fd5b61152c8585838181106115115761151061312b565b5b90506020020160208101906115269190612869565b87611c85565b808060010191505061145b565b505050505050565b5f7f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806115b357506115b282611f26565b5b9050919050565b6115c2611f8f565b73ffffffffffffffffffffffffffffffffffffffff166115e0610e11565b73ffffffffffffffffffffffffffffffffffffffff161461163f57611603611f8f565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161163691906125c2565b60405180910390fd5b565b5f61164a611bb9565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff1611156116af5781816040517f6f483d090000000000000000000000000000000000000000000000000000000081526004016116a69291906131f0565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361171f575f6040517fb6d9900a00000000000000000000000000000000000000000000000000000000815260040161171691906125c2565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff1681525060095f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b5f816117e66119b1565b11611879576117f36119b9565b82111561181b5761181460045f8481526020019081526020015f2054611f96565b905061187a565b5f54821015611878575f5b5f60045f8581526020019081526020015f205491508103611852578261184b90613217565b9250611826565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b5b919050565b805f5260045ffd5b5f61189183610ce9565b90508180156118d357508073ffffffffffffffffffffffffffffffffffffffff166118ba611b12565b73ffffffffffffffffffffffffffffffffffffffff1614155b156118ff576118e9816118e4611b12565b61129f565b6118fe576118fd63cfb3b94260e01b61187f565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b5f816119ea6119b1565b11611ad95760045f8381526020019081526020015f20549050611a0b6119b9565b821115611a3057611a1b81611f96565b611aea57611a2f63df2d9b4260e01b61187f565b5b5f8103611ab1575f548210611a5057611a4f63df2d9b4260e01b61187f565b5b5b60045f836001900393508381526020019081526020015f205490505f810315611aac575f7c010000000000000000000000000000000000000000000000000000000082160315611aea57611aab63df2d9b4260e01b61187f565b5b611a51565b5f7c010000000000000000000000000000000000000000000000000000000082160315611aea575b611ae963df2d9b4260e01b61187f565b5b919050565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b5f8060e883901c905060e8611b78868684611fd6565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b5f612710905090565b5f600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611c9e828260405180602001604052805f815250611fde565b5050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611cc7611b12565b8786866040518563ffffffff1660e01b8152600401611ce99493929190613290565b6020604051808303815f875af1925050508015611d2457506040513d601f19601f82011682018060405250810190611d2191906132ee565b60015b611d79573d805f8114611d52576040519150601f19603f3d011682016040523d82523d5f602084013e611d57565b606091505b505f815103611d7157611d7063d1a57ed660e01b61187f565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600c8054611ddb90612b3f565b80601f0160208091040260200160405190810160405280929190818152602001828054611e0790612b3f565b8015611e525780601f10611e2957610100808354040283529160200191611e52565b820191905f5260205f20905b815481529060010190602001808311611e3557829003601f168201915b5050505050905090565b60605f6001611e6a84612054565b0190505f8167ffffffffffffffff811115611e8857611e876126fe565b5b6040519080825280601f01601f191660200182016040528015611eba5781602001600182028036833780820191505090505b5090505f82602001820190505b600115611f1b578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611f1057611f0f612bdd565b5b0494505f8503611ec7575b819350505050919050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f33905090565b5f7c0100000000000000000000000000000000000000000000000000000000821673ffffffffffffffffffffffffffffffffffffffff8316119050919050565b5f9392505050565b611fe883836121a5565b5f8373ffffffffffffffffffffffffffffffffffffffff163b1461204f575f805490505f83820390505b6120245f868380600101945086611ca2565b6120395761203863d1a57ed660e01b61187f565b5b81811061201257815f541461204c575f80fd5b50505b505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106120b0577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816120a6576120a5612bdd565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106120ed576d04ee2d6d415b85acef810000000083816120e3576120e2612bdd565b5b0492506020810190505b662386f26fc10000831061211c57662386f26fc10000838161211257612111612bdd565b5b0492506010810190505b6305f5e1008310612145576305f5e100838161213b5761213a612bdd565b5b0492506008810190505b612710831061216a5761271083816121605761215f612bdd565b5b0492506004810190505b6064831061218d576064838161218357612182612bdd565b5b0492506002810190505b600a831061219c576001810190505b80915050919050565b5f805490505f82036121c2576121c163b562e8dd60e01b61187f565b5b6121ce5f848385611b5c565b6121ec836121dd5f865f611b62565b6121e685612319565b17611b89565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f73ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161690505f810361229d5761229c632e07630060e01b61187f565b5b5f83830190505f8390506122af6119b9565b6001830311156122ca576122c96381647e3a60e01b61187f565b5b5b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a48181600101915081036122cb57815f819055505050506123145f848385611bb3565b505050565b5f6001821460e11b9050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61236d81612339565b8114612377575f80fd5b50565b5f8135905061238881612364565b92915050565b5f602082840312156123a3576123a2612331565b5b5f6123b08482850161237a565b91505092915050565b5f8115159050919050565b6123cd816123b9565b82525050565b5f6020820190506123e65f8301846123c4565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612415826123ec565b9050919050565b6124258161240b565b811461242f575f80fd5b50565b5f813590506124408161241c565b92915050565b5f6bffffffffffffffffffffffff82169050919050565b61246681612446565b8114612470575f80fd5b50565b5f813590506124818161245d565b92915050565b5f806040838503121561249d5761249c612331565b5b5f6124aa85828601612432565b92505060206124bb85828601612473565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f612507826124c5565b61251181856124cf565b93506125218185602086016124df565b61252a816124ed565b840191505092915050565b5f6020820190508181035f83015261254d81846124fd565b905092915050565b5f819050919050565b61256781612555565b8114612571575f80fd5b50565b5f813590506125828161255e565b92915050565b5f6020828403121561259d5761259c612331565b5b5f6125aa84828501612574565b91505092915050565b6125bc8161240b565b82525050565b5f6020820190506125d55f8301846125b3565b92915050565b6125e481612555565b82525050565b5f6020820190506125fd5f8301846125db565b92915050565b5f806040838503121561261957612618612331565b5b5f61262685828601612432565b925050602061263785828601612574565b9150509250929050565b5f805f6060848603121561265857612657612331565b5b5f61266586828701612432565b935050602061267686828701612432565b925050604061268786828701612574565b9150509250925092565b5f80604083850312156126a7576126a6612331565b5b5f6126b485828601612574565b92505060206126c585828601612574565b9150509250929050565b5f6040820190506126e25f8301856125b3565b6126ef60208301846125db565b9392505050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612734826124ed565b810181811067ffffffffffffffff82111715612753576127526126fe565b5b80604052505050565b5f612765612328565b9050612771828261272b565b919050565b5f67ffffffffffffffff8211156127905761278f6126fe565b5b612799826124ed565b9050602081019050919050565b828183375f83830152505050565b5f6127c66127c184612776565b61275c565b9050828152602081018484840111156127e2576127e16126fa565b5b6127ed8482856127a6565b509392505050565b5f82601f830112612809576128086126f6565b5b81356128198482602086016127b4565b91505092915050565b5f6020828403121561283757612836612331565b5b5f82013567ffffffffffffffff81111561285457612853612335565b5b612860848285016127f5565b91505092915050565b5f6020828403121561287e5761287d612331565b5b5f61288b84828501612432565b91505092915050565b61289d816123b9565b81146128a7575f80fd5b50565b5f813590506128b881612894565b92915050565b5f80604083850312156128d4576128d3612331565b5b5f6128e185828601612432565b92505060206128f2858286016128aa565b9150509250929050565b5f67ffffffffffffffff821115612916576129156126fe565b5b61291f826124ed565b9050602081019050919050565b5f61293e612939846128fc565b61275c565b90508281526020810184848401111561295a576129596126fa565b5b6129658482856127a6565b509392505050565b5f82601f830112612981576129806126f6565b5b813561299184826020860161292c565b91505092915050565b5f805f80608085870312156129b2576129b1612331565b5b5f6129bf87828801612432565b94505060206129d087828801612432565b93505060406129e187828801612574565b925050606085013567ffffffffffffffff811115612a0257612a01612335565b5b612a0e8782880161296d565b91505092959194509250565b5f8060408385031215612a3057612a2f612331565b5b5f612a3d85828601612432565b9250506020612a4e85828601612432565b9150509250929050565b5f80fd5b5f80fd5b5f8083601f840112612a7557612a746126f6565b5b8235905067ffffffffffffffff811115612a9257612a91612a58565b5b602083019150836020820283011115612aae57612aad612a5c565b5b9250929050565b5f805f60408486031215612acc57612acb612331565b5b5f612ad986828701612574565b935050602084013567ffffffffffffffff811115612afa57612af9612335565b5b612b0686828701612a60565b92509250509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612b5657607f821691505b602082108103612b6957612b68612b12565b5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612ba682612555565b9150612bb183612555565b9250828202612bbf81612555565b91508282048414831517612bd657612bd5612b6f565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f612c1482612555565b9150612c1f83612555565b925082612c2f57612c2e612bdd565b5b828204905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302612c967fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612c5b565b612ca08683612c5b565b95508019841693508086168417925050509392505050565b5f819050919050565b5f612cdb612cd6612cd184612555565b612cb8565b612555565b9050919050565b5f819050919050565b612cf483612cc1565b612d08612d0082612ce2565b848454612c67565b825550505050565b5f90565b612d1c612d10565b612d27818484612ceb565b505050565b5b81811015612d4a57612d3f5f82612d14565b600181019050612d2d565b5050565b601f821115612d8f57612d6081612c3a565b612d6984612c4c565b81016020851015612d78578190505b612d8c612d8485612c4c565b830182612d2c565b50505b505050565b5f82821c905092915050565b5f612daf5f1984600802612d94565b1980831691505092915050565b5f612dc78383612da0565b9150826002028217905092915050565b612de0826124c5565b67ffffffffffffffff811115612df957612df86126fe565b5b612e038254612b3f565b612e0e828285612d4e565b5f60209050601f831160018114612e3f575f8415612e2d578287015190505b612e378582612dbc565b865550612e9e565b601f198416612e4d86612c3a565b5f5b82811015612e7457848901518255600182019150602085019450602081019050612e4f565b86831015612e915784890151612e8d601f891682612da0565b8355505b6001600288020188555050505b505050505050565b5f612eb082612555565b9150612ebb83612555565b9250828201905080821115612ed357612ed2612b6f565b5b92915050565b7f45786365656473206d6178696d756d20737570706c79206c696d69742e0000005f82015250565b5f612f0d601d836124cf565b9150612f1882612ed9565b602082019050919050565b5f6020820190508181035f830152612f3a81612f01565b9050919050565b7f53616c65206973206e6f74206163746976652063757272656e746c792e0000005f82015250565b5f612f75601d836124cf565b9150612f8082612f41565b602082019050919050565b5f6020820190508181035f830152612fa281612f69565b9050919050565b7f4d696e74207065722077616c6c657420657863656564656400000000000000005f82015250565b5f612fdd6018836124cf565b9150612fe882612fa9565b602082019050919050565b5f6020820190508181035f83015261300a81612fd1565b9050919050565b7f546f6b656e204964204e6f6e2d6578697374656e7400000000000000000000005f82015250565b5f6130456015836124cf565b915061305082613011565b602082019050919050565b5f6020820190508181035f83015261307281613039565b9050919050565b5f81905092915050565b5f61308d826124c5565b6130978185613079565b93506130a78185602086016124df565b80840191505092915050565b7f2e6a736f6e0000000000000000000000000000000000000000000000000000005f82015250565b5f6130e7600583613079565b91506130f2826130b3565b600582019050919050565b5f6131088285613083565b91506131148284613083565b915061311f826130db565b91508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f43616e2774206164642061206e756c6c206164647265737300000000000000005f82015250565b5f61318c6018836124cf565b915061319782613158565b602082019050919050565b5f6020820190508181035f8301526131b981613180565b9050919050565b5f6131da6131d56131d084612446565b612cb8565b612555565b9050919050565b6131ea816131c0565b82525050565b5f6040820190506132035f8301856131e1565b61321060208301846125db565b9392505050565b5f61322182612555565b91505f820361323357613232612b6f565b5b600182039050919050565b5f81519050919050565b5f82825260208201905092915050565b5f6132628261323e565b61326c8185613248565b935061327c8185602086016124df565b613285816124ed565b840191505092915050565b5f6080820190506132a35f8301876125b3565b6132b060208301866125b3565b6132bd60408301856125db565b81810360608301526132cf8184613258565b905095945050505050565b5f815190506132e881612364565b92915050565b5f6020828403121561330357613302612331565b5b5f613310848285016132da565b9150509291505056fea2646970667358221220bee1f5776f6c3b0e6911bea8c5d4b62d07d186f676a350da13d295f0c03099aa64736f6c634300081a00330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005f68747470733a2f2f7265642d72616e646f6d2d666c65612d3836372e6d7970696e6174612e636c6f75642f697066732f516d6162566a3241476f716e5a6770336f4e774445664e694b69415a6b73735046516b434a775863357a437059722f00
Deployed Bytecode
0x6080604052600436106101b6575f3560e01c8063700c35d2116100eb578063a22cb46511610089578063cfc86f7b11610063578063cfc86f7b146105af578063e985e9c5146105d9578063f2fde38b14610615578063fb7e6ccb1461063d576101b6565b8063a22cb4651461052f578063b88d4fde14610557578063c87b56dd14610573576101b6565b80637d8966e4116100c55780637d8966e41461049d5780638da5cb5b146104b357806395d89b41146104dd578063a0712d6814610507576101b6565b8063700c35d21461042157806370a082311461044b578063715018a614610487576101b6565b806322f3e2d41161015857806332cb6b0c1161013257806332cb6b0c1461037757806342842e0e146103a157806355f804b3146103bd5780636352211e146103e5576101b6565b806322f3e2d4146102f457806323b872dd1461031e5780632a55205a1461033a576101b6565b8063081812fc11610194578063081812fc14610248578063083c81be14610284578063095ea7b3146102ae57806318160ddd146102ca576101b6565b806301ffc9a7146101ba57806304634d8d146101f657806306fdde031461021e575b5f80fd5b3480156101c5575f80fd5b506101e060048036038101906101db919061238e565b610665565b6040516101ed91906123d3565b60405180910390f35b348015610201575f80fd5b5061021c60048036038101906102179190612487565b610676565b005b348015610229575f80fd5b5061023261068c565b60405161023f9190612535565b60405180910390f35b348015610253575f80fd5b5061026e60048036038101906102699190612588565b61071c565b60405161027b91906125c2565b60405180910390f35b34801561028f575f80fd5b50610298610775565b6040516102a591906125ea565b60405180910390f35b6102c860048036038101906102c39190612603565b61077e565b005b3480156102d5575f80fd5b506102de61078e565b6040516102eb91906125ea565b60405180910390f35b3480156102ff575f80fd5b506103086107d9565b60405161031591906123d3565b60405180910390f35b61033860048036038101906103339190612641565b6107ec565b005b348015610345575f80fd5b50610360600480360381019061035b9190612691565b610a97565b60405161036e9291906126cf565b60405180910390f35b348015610382575f80fd5b5061038b610c73565b60405161039891906125ea565b60405180910390f35b6103bb60048036038101906103b69190612641565b610c79565b005b3480156103c8575f80fd5b506103e360048036038101906103de9190612822565b610c98565b005b3480156103f0575f80fd5b5061040b60048036038101906104069190612588565b610ce9565b60405161041891906125c2565b60405180910390f35b34801561042c575f80fd5b50610435610cfa565b60405161044291906125ea565b60405180910390f35b348015610456575f80fd5b50610471600480360381019061046c9190612869565b610d00565b60405161047e91906125ea565b60405180910390f35b348015610492575f80fd5b5061049b610d94565b005b3480156104a8575f80fd5b506104b1610da7565b005b3480156104be575f80fd5b506104c7610e11565b6040516104d491906125c2565b60405180910390f35b3480156104e8575f80fd5b506104f1610e39565b6040516104fe9190612535565b60405180910390f35b348015610512575f80fd5b5061052d60048036038101906105289190612588565b610ec9565b005b34801561053a575f80fd5b50610555600480360381019061055091906128be565b611016565b005b610571600480360381019061056c919061299a565b61111c565b005b34801561057e575f80fd5b5061059960048036038101906105949190612588565b61116d565b6040516105a69190612535565b60405180910390f35b3480156105ba575f80fd5b506105c3611213565b6040516105d09190612535565b60405180910390f35b3480156105e4575f80fd5b506105ff60048036038101906105fa9190612a1a565b61129f565b60405161060c91906123d3565b60405180910390f35b348015610620575f80fd5b5061063b60048036038101906106369190612869565b61132d565b005b348015610648575f80fd5b50610663600480360381019061065e9190612ab5565b6113b1565b005b5f61066f82611541565b9050919050565b61067e6115ba565b6106888282611641565b5050565b60606002805461069b90612b3f565b80601f01602080910402602001604051908101604052809291908181526020018280546106c790612b3f565b80156107125780601f106106e957610100808354040283529160200191610712565b820191905f5260205f20905b8154815290600101906020018083116106f557829003601f168201915b5050505050905090565b5f610726826117dc565b61073b5761073a63cf4700e460e01b61187f565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f600d54905090565b61078a82826001611887565b5050565b5f6107976119b1565b6001545f54030390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6107c96119b9565b146107d657600854810190505b90565b600b60149054906101000a900460ff1681565b5f6107f6826119e0565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461086b5761086a63a114810060e01b61187f565b5b5f8061087684611aef565b9150915061088c8187610887611b12565b611b19565b6108b7576108a18661089c611b12565b61129f565b6108b6576108b56359c896be60e01b61187f565b5b5b6108c48686866001611b5c565b80156108ce575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f81546001019190508190555061099685610972888887611b62565b7c020000000000000000000000000000000000000000000000000000000017611b89565b60045f8681526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000841603610a12575f6001850190505f60045f8381526020019081526020015f205403610a10575f548114610a0f578360045f8381526020019081526020015f20819055505b5b505b5f73ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45f8103610a8157610a8063ea553b3460e01b61187f565b5b610a8e8787876001611bb3565b50505050505050565b5f805f600a5f8681526020019081526020015f206040518060400160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505f73ffffffffffffffffffffffffffffffffffffffff16815f015173ffffffffffffffffffffffffffffffffffffffff1603610c205760096040518060400160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b5f610c29611bb9565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610c559190612b9c565b610c5f9190612c0a565b9050815f0151819350935050509250929050565b611a0a81565b610c9383838360405180602001604052805f81525061111c565b505050565b3373ffffffffffffffffffffffffffffffffffffffff16610cb7610e11565b73ffffffffffffffffffffffffffffffffffffffff1614610cd6575f80fd5b80600c9081610ce59190612dd7565b5050565b5f610cf3826119e0565b9050919050565b600d5481565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610d4557610d44638f4eb60460e01b61187f565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b610d9c6115ba565b610da55f611bc2565b565b3373ffffffffffffffffffffffffffffffffffffffff16610dc6610e11565b73ffffffffffffffffffffffffffffffffffffffff1614610de5575f80fd5b600b60149054906101000a900460ff1615600b60146101000a81548160ff021916908315150217905550565b5f600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054610e4890612b3f565b80601f0160208091040260200160405190810160405280929190818152602001828054610e7490612b3f565b8015610ebf5780601f10610e9657610100808354040283529160200191610ebf565b820191905f5260205f20905b815481529060010190602001808311610ea257829003601f168201915b5050505050905090565b805f610ed361078e565b9050611a0a8282610ee49190612ea6565b1115610f25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1c90612f23565b60405180910390fd5b610f2d610e11565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461100757600b60149054906101000a900460ff16610fae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fa590612f8b565b60405180910390fd5b600d5483610fbb33610d00565b610fc59190612ea6565b1115611006576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ffd90612ff3565b60405180910390fd5b5b6110113384611c85565b505050565b8060075f611022611b12565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166110cb611b12565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161111091906123d3565b60405180910390a35050565b6111278484846107ec565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146111675761115184848484611ca2565b6111665761116563d1a57ed660e01b61187f565b5b5b50505050565b6060611178826117dc565b6111b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ae9061305b565b60405180910390fd5b5f6111c0611dcc565b51116111da5760405180602001604052805f81525061120c565b6111e2611dcc565b6111eb83611e5c565b6040516020016111fc9291906130fd565b6040516020818303038152906040525b9050919050565b600c805461122090612b3f565b80601f016020809104026020016040519081016040528092919081815260200182805461124c90612b3f565b80156112975780601f1061126e57610100808354040283529160200191611297565b820191905f5260205f20905b81548152906001019060200180831161127a57829003601f168201915b505050505081565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b6113356115ba565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113a5575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161139c91906125c2565b60405180910390fd5b6113ae81611bc2565b50565b3373ffffffffffffffffffffffffffffffffffffffff166113d0610e11565b73ffffffffffffffffffffffffffffffffffffffff16146113ef575f80fd5b81819050836113fe9190612b9c565b5f61140761078e565b9050611a0a82826114189190612ea6565b1115611459576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145090612f23565b60405180910390fd5b5f5b84849050811015611539575f73ffffffffffffffffffffffffffffffffffffffff168585838181106114905761148f61312b565b5b90506020020160208101906114a59190612869565b73ffffffffffffffffffffffffffffffffffffffff16036114fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f2906131a2565b60405180910390fd5b61152c8585838181106115115761151061312b565b5b90506020020160208101906115269190612869565b87611c85565b808060010191505061145b565b505050505050565b5f7f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806115b357506115b282611f26565b5b9050919050565b6115c2611f8f565b73ffffffffffffffffffffffffffffffffffffffff166115e0610e11565b73ffffffffffffffffffffffffffffffffffffffff161461163f57611603611f8f565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161163691906125c2565b60405180910390fd5b565b5f61164a611bb9565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff1611156116af5781816040517f6f483d090000000000000000000000000000000000000000000000000000000081526004016116a69291906131f0565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361171f575f6040517fb6d9900a00000000000000000000000000000000000000000000000000000000815260040161171691906125c2565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff1681525060095f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b5f816117e66119b1565b11611879576117f36119b9565b82111561181b5761181460045f8481526020019081526020015f2054611f96565b905061187a565b5f54821015611878575f5b5f60045f8581526020019081526020015f205491508103611852578261184b90613217565b9250611826565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b5b919050565b805f5260045ffd5b5f61189183610ce9565b90508180156118d357508073ffffffffffffffffffffffffffffffffffffffff166118ba611b12565b73ffffffffffffffffffffffffffffffffffffffff1614155b156118ff576118e9816118e4611b12565b61129f565b6118fe576118fd63cfb3b94260e01b61187f565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b5f816119ea6119b1565b11611ad95760045f8381526020019081526020015f20549050611a0b6119b9565b821115611a3057611a1b81611f96565b611aea57611a2f63df2d9b4260e01b61187f565b5b5f8103611ab1575f548210611a5057611a4f63df2d9b4260e01b61187f565b5b5b60045f836001900393508381526020019081526020015f205490505f810315611aac575f7c010000000000000000000000000000000000000000000000000000000082160315611aea57611aab63df2d9b4260e01b61187f565b5b611a51565b5f7c010000000000000000000000000000000000000000000000000000000082160315611aea575b611ae963df2d9b4260e01b61187f565b5b919050565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b5f8060e883901c905060e8611b78868684611fd6565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b5f612710905090565b5f600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611c9e828260405180602001604052805f815250611fde565b5050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611cc7611b12565b8786866040518563ffffffff1660e01b8152600401611ce99493929190613290565b6020604051808303815f875af1925050508015611d2457506040513d601f19601f82011682018060405250810190611d2191906132ee565b60015b611d79573d805f8114611d52576040519150601f19603f3d011682016040523d82523d5f602084013e611d57565b606091505b505f815103611d7157611d7063d1a57ed660e01b61187f565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600c8054611ddb90612b3f565b80601f0160208091040260200160405190810160405280929190818152602001828054611e0790612b3f565b8015611e525780601f10611e2957610100808354040283529160200191611e52565b820191905f5260205f20905b815481529060010190602001808311611e3557829003601f168201915b5050505050905090565b60605f6001611e6a84612054565b0190505f8167ffffffffffffffff811115611e8857611e876126fe565b5b6040519080825280601f01601f191660200182016040528015611eba5781602001600182028036833780820191505090505b5090505f82602001820190505b600115611f1b578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611f1057611f0f612bdd565b5b0494505f8503611ec7575b819350505050919050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f33905090565b5f7c0100000000000000000000000000000000000000000000000000000000821673ffffffffffffffffffffffffffffffffffffffff8316119050919050565b5f9392505050565b611fe883836121a5565b5f8373ffffffffffffffffffffffffffffffffffffffff163b1461204f575f805490505f83820390505b6120245f868380600101945086611ca2565b6120395761203863d1a57ed660e01b61187f565b5b81811061201257815f541461204c575f80fd5b50505b505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106120b0577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816120a6576120a5612bdd565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106120ed576d04ee2d6d415b85acef810000000083816120e3576120e2612bdd565b5b0492506020810190505b662386f26fc10000831061211c57662386f26fc10000838161211257612111612bdd565b5b0492506010810190505b6305f5e1008310612145576305f5e100838161213b5761213a612bdd565b5b0492506008810190505b612710831061216a5761271083816121605761215f612bdd565b5b0492506004810190505b6064831061218d576064838161218357612182612bdd565b5b0492506002810190505b600a831061219c576001810190505b80915050919050565b5f805490505f82036121c2576121c163b562e8dd60e01b61187f565b5b6121ce5f848385611b5c565b6121ec836121dd5f865f611b62565b6121e685612319565b17611b89565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f73ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161690505f810361229d5761229c632e07630060e01b61187f565b5b5f83830190505f8390506122af6119b9565b6001830311156122ca576122c96381647e3a60e01b61187f565b5b5b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a48181600101915081036122cb57815f819055505050506123145f848385611bb3565b505050565b5f6001821460e11b9050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61236d81612339565b8114612377575f80fd5b50565b5f8135905061238881612364565b92915050565b5f602082840312156123a3576123a2612331565b5b5f6123b08482850161237a565b91505092915050565b5f8115159050919050565b6123cd816123b9565b82525050565b5f6020820190506123e65f8301846123c4565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612415826123ec565b9050919050565b6124258161240b565b811461242f575f80fd5b50565b5f813590506124408161241c565b92915050565b5f6bffffffffffffffffffffffff82169050919050565b61246681612446565b8114612470575f80fd5b50565b5f813590506124818161245d565b92915050565b5f806040838503121561249d5761249c612331565b5b5f6124aa85828601612432565b92505060206124bb85828601612473565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f612507826124c5565b61251181856124cf565b93506125218185602086016124df565b61252a816124ed565b840191505092915050565b5f6020820190508181035f83015261254d81846124fd565b905092915050565b5f819050919050565b61256781612555565b8114612571575f80fd5b50565b5f813590506125828161255e565b92915050565b5f6020828403121561259d5761259c612331565b5b5f6125aa84828501612574565b91505092915050565b6125bc8161240b565b82525050565b5f6020820190506125d55f8301846125b3565b92915050565b6125e481612555565b82525050565b5f6020820190506125fd5f8301846125db565b92915050565b5f806040838503121561261957612618612331565b5b5f61262685828601612432565b925050602061263785828601612574565b9150509250929050565b5f805f6060848603121561265857612657612331565b5b5f61266586828701612432565b935050602061267686828701612432565b925050604061268786828701612574565b9150509250925092565b5f80604083850312156126a7576126a6612331565b5b5f6126b485828601612574565b92505060206126c585828601612574565b9150509250929050565b5f6040820190506126e25f8301856125b3565b6126ef60208301846125db565b9392505050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612734826124ed565b810181811067ffffffffffffffff82111715612753576127526126fe565b5b80604052505050565b5f612765612328565b9050612771828261272b565b919050565b5f67ffffffffffffffff8211156127905761278f6126fe565b5b612799826124ed565b9050602081019050919050565b828183375f83830152505050565b5f6127c66127c184612776565b61275c565b9050828152602081018484840111156127e2576127e16126fa565b5b6127ed8482856127a6565b509392505050565b5f82601f830112612809576128086126f6565b5b81356128198482602086016127b4565b91505092915050565b5f6020828403121561283757612836612331565b5b5f82013567ffffffffffffffff81111561285457612853612335565b5b612860848285016127f5565b91505092915050565b5f6020828403121561287e5761287d612331565b5b5f61288b84828501612432565b91505092915050565b61289d816123b9565b81146128a7575f80fd5b50565b5f813590506128b881612894565b92915050565b5f80604083850312156128d4576128d3612331565b5b5f6128e185828601612432565b92505060206128f2858286016128aa565b9150509250929050565b5f67ffffffffffffffff821115612916576129156126fe565b5b61291f826124ed565b9050602081019050919050565b5f61293e612939846128fc565b61275c565b90508281526020810184848401111561295a576129596126fa565b5b6129658482856127a6565b509392505050565b5f82601f830112612981576129806126f6565b5b813561299184826020860161292c565b91505092915050565b5f805f80608085870312156129b2576129b1612331565b5b5f6129bf87828801612432565b94505060206129d087828801612432565b93505060406129e187828801612574565b925050606085013567ffffffffffffffff811115612a0257612a01612335565b5b612a0e8782880161296d565b91505092959194509250565b5f8060408385031215612a3057612a2f612331565b5b5f612a3d85828601612432565b9250506020612a4e85828601612432565b9150509250929050565b5f80fd5b5f80fd5b5f8083601f840112612a7557612a746126f6565b5b8235905067ffffffffffffffff811115612a9257612a91612a58565b5b602083019150836020820283011115612aae57612aad612a5c565b5b9250929050565b5f805f60408486031215612acc57612acb612331565b5b5f612ad986828701612574565b935050602084013567ffffffffffffffff811115612afa57612af9612335565b5b612b0686828701612a60565b92509250509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612b5657607f821691505b602082108103612b6957612b68612b12565b5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612ba682612555565b9150612bb183612555565b9250828202612bbf81612555565b91508282048414831517612bd657612bd5612b6f565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f612c1482612555565b9150612c1f83612555565b925082612c2f57612c2e612bdd565b5b828204905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302612c967fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612c5b565b612ca08683612c5b565b95508019841693508086168417925050509392505050565b5f819050919050565b5f612cdb612cd6612cd184612555565b612cb8565b612555565b9050919050565b5f819050919050565b612cf483612cc1565b612d08612d0082612ce2565b848454612c67565b825550505050565b5f90565b612d1c612d10565b612d27818484612ceb565b505050565b5b81811015612d4a57612d3f5f82612d14565b600181019050612d2d565b5050565b601f821115612d8f57612d6081612c3a565b612d6984612c4c565b81016020851015612d78578190505b612d8c612d8485612c4c565b830182612d2c565b50505b505050565b5f82821c905092915050565b5f612daf5f1984600802612d94565b1980831691505092915050565b5f612dc78383612da0565b9150826002028217905092915050565b612de0826124c5565b67ffffffffffffffff811115612df957612df86126fe565b5b612e038254612b3f565b612e0e828285612d4e565b5f60209050601f831160018114612e3f575f8415612e2d578287015190505b612e378582612dbc565b865550612e9e565b601f198416612e4d86612c3a565b5f5b82811015612e7457848901518255600182019150602085019450602081019050612e4f565b86831015612e915784890151612e8d601f891682612da0565b8355505b6001600288020188555050505b505050505050565b5f612eb082612555565b9150612ebb83612555565b9250828201905080821115612ed357612ed2612b6f565b5b92915050565b7f45786365656473206d6178696d756d20737570706c79206c696d69742e0000005f82015250565b5f612f0d601d836124cf565b9150612f1882612ed9565b602082019050919050565b5f6020820190508181035f830152612f3a81612f01565b9050919050565b7f53616c65206973206e6f74206163746976652063757272656e746c792e0000005f82015250565b5f612f75601d836124cf565b9150612f8082612f41565b602082019050919050565b5f6020820190508181035f830152612fa281612f69565b9050919050565b7f4d696e74207065722077616c6c657420657863656564656400000000000000005f82015250565b5f612fdd6018836124cf565b9150612fe882612fa9565b602082019050919050565b5f6020820190508181035f83015261300a81612fd1565b9050919050565b7f546f6b656e204964204e6f6e2d6578697374656e7400000000000000000000005f82015250565b5f6130456015836124cf565b915061305082613011565b602082019050919050565b5f6020820190508181035f83015261307281613039565b9050919050565b5f81905092915050565b5f61308d826124c5565b6130978185613079565b93506130a78185602086016124df565b80840191505092915050565b7f2e6a736f6e0000000000000000000000000000000000000000000000000000005f82015250565b5f6130e7600583613079565b91506130f2826130b3565b600582019050919050565b5f6131088285613083565b91506131148284613083565b915061311f826130db565b91508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f43616e2774206164642061206e756c6c206164647265737300000000000000005f82015250565b5f61318c6018836124cf565b915061319782613158565b602082019050919050565b5f6020820190508181035f8301526131b981613180565b9050919050565b5f6131da6131d56131d084612446565b612cb8565b612555565b9050919050565b6131ea816131c0565b82525050565b5f6040820190506132035f8301856131e1565b61321060208301846125db565b9392505050565b5f61322182612555565b91505f820361323357613232612b6f565b5b600182039050919050565b5f81519050919050565b5f82825260208201905092915050565b5f6132628261323e565b61326c8185613248565b935061327c8185602086016124df565b613285816124ed565b840191505092915050565b5f6080820190506132a35f8301876125b3565b6132b060208301866125b3565b6132bd60408301856125db565b81810360608301526132cf8184613258565b905095945050505050565b5f815190506132e881612364565b92915050565b5f6020828403121561330357613302612331565b5b5f613310848285016132da565b9150509291505056fea2646970667358221220bee1f5776f6c3b0e6911bea8c5d4b62d07d186f676a350da13d295f0c03099aa64736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005f68747470733a2f2f7265642d72616e646f6d2d666c65612d3836372e6d7970696e6174612e636c6f75642f697066732f516d6162566a3241476f716e5a6770336f4e774445664e694b69415a6b73735046516b434a775863357a437059722f00
-----Decoded View---------------
Arg [0] : baseURI (string): https://red-random-flea-867.mypinata.cloud/ipfs/QmabVj2AGoqnZgp3oNwDEfNiKiAZkssPFQkCJwXc5zCpYr/
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 000000000000000000000000000000000000000000000000000000000000005f
Arg [2] : 68747470733a2f2f7265642d72616e646f6d2d666c65612d3836372e6d797069
Arg [3] : 6e6174612e636c6f75642f697066732f516d6162566a3241476f716e5a677033
Arg [4] : 6f4e774445664e694b69415a6b73735046516b434a775863357a437059722f00
Deployed Bytecode Sourcemap
92296:2413:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93132:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92978:146;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;28740:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35980:227;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93613:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35697:124;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;23942:573;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92348:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40252:3523;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4516:429;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;92450:42;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43871:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93392:101;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;30142:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92413:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25666:242;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71402:103;;;;;;;;;;;;;:::i;:::-;;93309:77;;;;;;;;;;;;;:::i;:::-;;70727:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28916:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94411:295;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;36547:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44662:416;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94028:276;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92381:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36938:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71660:220;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93710:312;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93132:171;93235:4;93259:36;93283:11;93259:23;:36::i;:::-;93252:43;;93132:171;;;:::o;92978:146::-;70613:13;:11;:13::i;:::-;93074:42:::1;93093:8;93103:12;93074:18;:42::i;:::-;92978:146:::0;;:::o;28740:100::-;28794:13;28827:5;28820:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28740:100;:::o;35980:227::-;36056:7;36081:16;36089:7;36081;:16::i;:::-;36076:73;;36099:50;36107:41;;;36099:7;:50::i;:::-;36076:73;36169:15;:24;36185:7;36169:24;;;;;;;;;;;:30;;;;;;;;;;;;36162:37;;35980:227;;;:::o;93613:91::-;93662:7;93685:13;;93678:20;;93613:91;:::o;35697:124::-;35786:27;35795:2;35799:7;35808:4;35786:8;:27::i;:::-;35697:124;;:::o;23942:573::-;24003:14;24401:15;:13;:15::i;:::-;24386:12;;24370:13;;:28;:46;24361:55;;24456:17;24435;:15;:17::i;:::-;:38;24431:65;;24485:11;;24475:21;;;;24431:65;23942:573;:::o;92348:28::-;;;;;;;;;;;;;:::o;40252:3523::-;40394:27;40424;40443:7;40424:18;:27::i;:::-;40394:57;;19884:14;40595:4;40579:22;;:41;40556:66;;40680:4;40639:45;;40655:19;40639:45;;;40635:95;;40686:44;40694:35;;;40686:7;:44::i;:::-;40635:95;40744:27;40773:23;40800:35;40827:7;40800:26;:35::i;:::-;40743:92;;;;40935:68;40960:15;40977:4;40983:19;:17;:19::i;:::-;40935:24;:68::i;:::-;40930:189;;41023:43;41040:4;41046:19;:17;:19::i;:::-;41023:16;:43::i;:::-;41018:101;;41068:51;41076:42;;;41068:7;:51::i;:::-;41018:101;40930:189;41132:43;41154:4;41160:2;41164:7;41173:1;41132:21;:43::i;:::-;41268:15;41265:160;;;41408:1;41387:19;41380:30;41265:160;41805:18;:24;41824:4;41805:24;;;;;;;;;;;;;;;;41803:26;;;;;;;;;;;;41874:18;:22;41893:2;41874:22;;;;;;;;;;;;;;;;41872:24;;;;;;;;;;;42196:146;42233:2;42282:45;42297:4;42303:2;42307:19;42282:14;:45::i;:::-;19482:8;42254:73;42196:18;:146::i;:::-;42167:17;:26;42185:7;42167:26;;;;;;;;;;;:175;;;;42513:1;19482:8;42462:19;:47;:52;42458:627;;42535:19;42567:1;42557:7;:11;42535:33;;42724:1;42690:17;:30;42708:11;42690:30;;;;;;;;;;;;:35;42686:384;;42828:13;;42813:11;:28;42809:242;;43008:19;42975:17;:30;42993:11;42975:30;;;;;;;;;;;:52;;;;42809:242;42686:384;42516:569;42458:627;43198:16;19884:14;43233:2;43217:20;;:39;43198:58;;43597:7;43561:8;43527:4;43469:25;43414:1;43357;43334:299;43670:1;43658:8;:13;43654:58;;43673:39;43681:30;;;43673:7;:39::i;:::-;43654:58;43725:42;43746:4;43752:2;43756:7;43765:1;43725:20;:42::i;:::-;40383:3392;;;;40252:3523;;;:::o;4516:429::-;4602:7;4611;4631:26;4660:17;:26;4678:7;4660:26;;;;;;;;;;;4631:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4731:1;4703:30;;:7;:16;;;:30;;;4699:92;;4760:19;4750:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4699:92;4803:21;4867:17;:15;:17::i;:::-;4827:57;;4840:7;:23;;;4828:35;;:9;:35;;;;:::i;:::-;4827:57;;;;:::i;:::-;4803:81;;4905:7;:16;;;4923:13;4897:40;;;;;;4516:429;;;;;:::o;92450:42::-;92487:5;92450:42;:::o;43871:193::-;44017:39;44034:4;44040:2;44044:7;44017:39;;;;;;;;;;;;:16;:39::i;:::-;43871:193;;;:::o;93392:101::-;92745:10;92734:21;;:7;:5;:7::i;:::-;:21;;;92726:30;;;;;;93480:7:::1;93464:13;:23;;;;;;:::i;:::-;;93392:101:::0;:::o;30142:152::-;30214:7;30257:27;30276:7;30257:18;:27::i;:::-;30234:52;;30142:152;;;:::o;92413:32::-;;;;:::o;25666:242::-;25738:7;25779:1;25762:19;;:5;:19;;;25758:69;;25783:44;25791:35;;;25783:7;:44::i;:::-;25758:69;18426:13;25845:18;:25;25864:5;25845:25;;;;;;;;;;;;;;;;:55;25838:62;;25666:242;;;:::o;71402:103::-;70613:13;:11;:13::i;:::-;71467:30:::1;71494:1;71467:18;:30::i;:::-;71402:103::o:0;93309:77::-;92745:10;92734:21;;:7;:5;:7::i;:::-;:21;;;92726:30;;;;;;93372:8:::1;;;;;;;;;;;93371:9;93360:8;;:20;;;;;;;;;;;;;;;;;;93309:77::o:0;70727:87::-;70773:7;70800:6;;;;;;;;;;;70793:13;;70727:87;:::o;28916:104::-;28972:13;29005:7;28998:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28916:104;:::o;94411:295::-;94462:6;92826:21;92850:13;:11;:13::i;:::-;92826:37;;92487:5;92898:6;92882:13;:22;;;;:::i;:::-;:36;;92874:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;94494:7:::1;:5;:7::i;:::-;94480:21;;:10;:21;;;94476:187;;94520:8;;;;;;;;;;;94512:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;94613:13;;94603:6;94579:21;94589:10;94579:9;:21::i;:::-;:30;;;;:::i;:::-;:47;;94571:84;;;;;;;;;;;;:::i;:::-;;;;;;;;;94476:187;94671:29;94681:10;94693:6;94671:9;:29::i;:::-;92815:155:::0;94411:295;;:::o;36547:234::-;36694:8;36642:18;:39;36661:19;:17;:19::i;:::-;36642:39;;;;;;;;;;;;;;;:49;36682:8;36642:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;36754:8;36718:55;;36733:19;:17;:19::i;:::-;36718:55;;;36764:8;36718:55;;;;;;:::i;:::-;;;;;;;;36547:234;;:::o;44662:416::-;44837:31;44850:4;44856:2;44860:7;44837:12;:31::i;:::-;44901:1;44883:2;:14;;;:19;44879:192;;44922:56;44953:4;44959:2;44963:7;44972:5;44922:30;:56::i;:::-;44917:154;;44999:56;45007:47;;;44999:7;:56::i;:::-;44917:154;44879:192;44662:416;;;;:::o;94028:276::-;94102:13;94132:17;94140:8;94132:7;:17::i;:::-;94124:51;;;;;;;;;;;;:::i;:::-;;;;;;;;;94216:1;94195:10;:8;:10::i;:::-;94189:24;:28;:109;;;;;;;;;;;;;;;;;94244:10;:8;:10::i;:::-;94256:26;94273:8;94256:16;:26::i;:::-;94227:65;;;;;;;;;:::i;:::-;;;;;;;;;;;;;94189:109;94182:116;;94028:276;;;:::o;92381:27::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;36938:164::-;37035:4;37059:18;:25;37078:5;37059:25;;;;;;;;;;;;;;;:35;37085:8;37059:35;;;;;;;;;;;;;;;;;;;;;;;;;37052:42;;36938:164;;;;:::o;71660:220::-;70613:13;:11;:13::i;:::-;71765:1:::1;71745:22;;:8;:22;;::::0;71741:93:::1;;71819:1;71791:31;;;;;;;;;;;:::i;:::-;;;;;;;;71741:93;71844:28;71863:8;71844:18;:28::i;:::-;71660:220:::0;:::o;93710:312::-;92745:10;92734:21;;:7;:5;:7::i;:::-;:21;;;92726:30;;;;;;93825:9:::1;;:16;;93816:6;:25;;;;:::i;:::-;92826:21;92850:13;:11;:13::i;:::-;92826:37;;92487:5;92898:6;92882:13;:22;;;;:::i;:::-;:36;;92874:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;93854:9:::2;93849:168;93873:9;;:16;;93869:1;:20;93849:168;;;93938:1;93914:26;;:9;;93924:1;93914:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;:26;;::::0;93906:63:::2;;;;;;;;;;;;:::i;:::-;;;;;;;;;93978:31;93988:9;;93998:1;93988:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;94002:6;93978:9;:31::i;:::-;93891:4;;;;;;;93849:168;;;;92815:155:::1;92763:1;93710:312:::0;;;:::o;4246:215::-;4348:4;4387:26;4372:41;;;:11;:41;;;;:81;;;;4417:36;4441:11;4417:23;:36::i;:::-;4372:81;4365:88;;4246:215;;;:::o;70892:166::-;70963:12;:10;:12::i;:::-;70952:23;;:7;:5;:7::i;:::-;:23;;;70948:103;;71026:12;:10;:12::i;:::-;70999:40;;;;;;;;;;;:::i;:::-;;;;;;;;70948:103;70892:166::o;5595:518::-;5690:19;5712:17;:15;:17::i;:::-;5690:39;;;;5759:11;5744:12;:26;;;5740:176;;;5878:12;5892:11;5849:55;;;;;;;;;;;;:::i;:::-;;;;;;;;5740:176;5950:1;5930:22;;:8;:22;;;5926:110;;6021:1;5976:48;;;;;;;;;;;:::i;:::-;;;;;;;;5926:110;6070:35;;;;;;;;6082:8;6070:35;;;;;;6092:12;6070:35;;;;;6048:19;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5679:434;5595:518;;:::o;37360:475::-;37425:11;37472:7;37453:15;:13;:15::i;:::-;:26;37449:379;;37510:17;:15;:17::i;:::-;37500:7;:27;37496:90;;;37536:50;37559:17;:26;37577:7;37559:26;;;;;;;;;;;;37536:22;:50::i;:::-;37529:57;;;;37496:90;37617:13;;37607:7;:23;37603:214;;;37651:14;37684:60;37732:1;37701:17;:26;37719:7;37701:26;;;;;;;;;;;;37692:35;;;37691:42;37684:60;;37735:9;;;;:::i;:::-;;;37684:60;;;37800:1;19202:8;37772:6;:24;:29;37763:38;;37632:185;37603:214;37449:379;37360:475;;;;:::o;67869:165::-;67970:13;67964:4;67957:27;68011:4;68005;67998:18;59284:474;59413:13;59429:16;59437:7;59429;:16::i;:::-;59413:32;;59462:13;:45;;;;;59502:5;59479:28;;:19;:17;:19::i;:::-;:28;;;;59462:45;59458:201;;;59527:44;59544:5;59551:19;:17;:19::i;:::-;59527:16;:44::i;:::-;59522:137;;59592:51;59600:42;;;59592:7;:51::i;:::-;59522:137;59458:201;59704:2;59671:15;:24;59687:7;59671:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;59742:7;59738:2;59722:28;;59731:5;59722:28;;;;;;;;;;;;59402:356;59284:474;;;:::o;94310:95::-;94375:7;94398:1;94391:8;;94310:95;:::o;23440:110::-;23498:7;23525:17;23518:24;;23440:110;:::o;31627:2213::-;31694:14;31744:7;31725:15;:13;:15::i;:::-;:26;31721:2054;;31777:17;:26;31795:7;31777:26;;;;;;;;;;;;31768:35;;31834:17;:15;:17::i;:::-;31824:7;:27;31820:183;;;31876:30;31899:6;31876:22;:30::i;:::-;31908:13;31872:49;31940:47;31948:38;;;31940:7;:47::i;:::-;31820:183;32114:1;32104:6;:11;32100:1292;;32151:13;;32140:7;:24;32136:77;;32166:47;32174:38;;;32166:7;:47::i;:::-;32136:77;32770:607;32848:17;:28;32866:9;;;;;;;32848:28;;;;;;;;;;;;32839:37;;32936:1;32926:6;:11;32922:25;32939:8;32922:25;33002:1;19202:8;32974:6;:24;:29;32970:48;33005:13;32970:48;33310:47;33318:38;;;33310:7;:47::i;:::-;32770:607;;;32100:1292;33747:1;19202:8;33719:6;:24;:29;33715:48;33750:13;33715:48;31721:2054;33785:47;33793:38;;;33785:7;:47::i;:::-;31627:2213;;;;:::o;39147:485::-;39249:27;39278:23;39319:38;39360:15;:24;39376:7;39360:24;;;;;;;;;;;39319:65;;39537:18;39514:41;;39594:19;39588:26;39569:45;;39499:126;39147:485;;;:::o;65850:105::-;65910:7;65937:10;65930:17;;65850:105;:::o;38375:659::-;38524:11;38689:16;38682:5;38678:28;38669:37;;38849:16;38838:9;38834:32;38821:45;;38999:15;38988:9;38985:30;38977:5;38966:9;38963:20;38960:56;38950:66;;38375:659;;;;;:::o;45740:159::-;;;;;:::o;65159:311::-;65294:7;65314:16;19606:3;65340:19;:41;;65314:68;;19606:3;65408:31;65419:4;65425:2;65429:9;65408:10;:31::i;:::-;65400:40;;:62;;65393:69;;;65159:311;;;;;:::o;34388:450::-;34468:14;34636:16;34629:5;34625:28;34616:37;;34813:5;34799:11;34774:23;34770:41;34767:52;34760:5;34757:63;34747:73;;34388:450;;;;:::o;46564:158::-;;;;;:::o;5227:97::-;5285:6;5311:5;5304:12;;5227:97;:::o;72040:191::-;72114:16;72133:6;;;;;;;;;;;72114:25;;72159:8;72150:6;;:17;;;;;;;;;;;;;;;;;;72214:8;72183:40;;72204:8;72183:40;;;;;;;;;;;;72103:128;72040:191;:::o;54478:112::-;54555:27;54565:2;54569:8;54555:27;;;;;;;;;;;;:9;:27::i;:::-;54478:112;;:::o;47162:691::-;47325:4;47371:2;47346:45;;;47392:19;:17;:19::i;:::-;47413:4;47419:7;47428:5;47346:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;47342:504;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47646:1;47629:6;:13;:18;47625:115;;47668:56;47676:47;;;47668:7;:56::i;:::-;47625:115;47812:6;47806:13;47797:6;47793:2;47789:15;47782:38;47342:504;47515:54;;;47505:64;;;:6;:64;;;;47498:71;;;47162:691;;;;;;:::o;93499:108::-;93559:13;93588;93581:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93499:108;:::o;89733:718::-;89789:13;89840:14;89877:1;89857:17;89868:5;89857:10;:17::i;:::-;:21;89840:38;;89893:20;89927:6;89916:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89893:41;;89949:11;90078:6;90074:2;90070:15;90062:6;90058:28;90051:35;;90115:290;90122:4;90115:290;;;90147:5;;;;;;;;90289:10;90284:2;90277:5;90273:14;90268:32;90263:3;90255:46;90347:2;90338:11;;;;;;:::i;:::-;;;;;90381:1;90372:5;:10;90115:290;90368:21;90115:290;90426:6;90419:13;;;;;89733:718;;;:::o;2163:148::-;2239:4;2278:25;2263:40;;;:11;:40;;;;2256:47;;2163:148;;;:::o;68736:98::-;68789:7;68816:10;68809:17;;68736:98;:::o;37931:335::-;38001:11;38231:15;38223:6;38219:28;38200:16;38192:6;38188:29;38185:63;38175:73;;37931:335;;;:::o;64860:147::-;64997:6;64860:147;;;;;:::o;53607:787::-;53738:19;53744:2;53748:8;53738:5;:19::i;:::-;53817:1;53799:2;:14;;;:19;53795:581;;53839:11;53853:13;;53839:27;;53885:13;53907:8;53901:3;:14;53885:30;;53934:242;53965:62;54004:1;54008:2;54012:7;;;;;;54021:5;53965:30;:62::i;:::-;53960:176;;54056:56;54064:47;;;54056:7;:56::i;:::-;53960:176;54171:3;54163:5;:11;53934:242;;54347:3;54330:13;;:20;54326:34;;54352:8;;;54326:34;53820:556;;53795:581;53607:787;;;:::o;84797:948::-;84850:7;84870:14;84887:1;84870:18;;84937:8;84928:5;:17;84924:106;;84975:8;84966:17;;;;;;:::i;:::-;;;;;85012:2;85002:12;;;;84924:106;85057:8;85048:5;:17;85044:106;;85095:8;85086:17;;;;;;:::i;:::-;;;;;85132:2;85122:12;;;;85044:106;85177:8;85168:5;:17;85164:106;;85215:8;85206:17;;;;;;:::i;:::-;;;;;85252:2;85242:12;;;;85164:106;85297:7;85288:5;:16;85284:103;;85334:7;85325:16;;;;;;:::i;:::-;;;;;85370:1;85360:11;;;;85284:103;85414:7;85405:5;:16;85401:103;;85451:7;85442:16;;;;;;:::i;:::-;;;;;85487:1;85477:11;;;;85401:103;85531:7;85522:5;:16;85518:103;;85568:7;85559:16;;;;;;:::i;:::-;;;;;85604:1;85594:11;;;;85518:103;85648:7;85639:5;:16;85635:68;;85686:1;85676:11;;;;85635:68;85731:6;85724:13;;;84797:948;;;:::o;48315:2399::-;48388:20;48411:13;;48388:36;;48451:1;48439:8;:13;48435:53;;48454:34;48462:25;;;48454:7;:34::i;:::-;48435:53;48501:61;48531:1;48535:2;48539:12;48553:8;48501:21;:61::i;:::-;49035:139;49072:2;49126:33;49149:1;49153:2;49157:1;49126:14;:33::i;:::-;49093:30;49114:8;49093:20;:30::i;:::-;:66;49035:18;:139::i;:::-;49001:17;:31;49019:12;49001:31;;;;;;;;;;;:173;;;;49461:1;18564:2;49431:1;:26;;49430:32;49418:8;:45;49392:18;:22;49411:2;49392:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;49574:16;19884:14;49609:2;49593:20;;:39;49574:58;;49665:1;49653:8;:13;49649:54;;49668:35;49676:26;;;49668:7;:35::i;:::-;49649:54;49720:11;49749:8;49734:12;:23;49720:37;;49772:15;49790:12;49772:30;;49833:17;:15;:17::i;:::-;49829:1;49823:3;:7;:27;49819:77;;;49852:44;49860:35;;;49852:7;:44::i;:::-;49819:77;49913:676;50332:7;50288:8;50243:1;50177:25;50114:1;50049;50018:358;50584:3;50571:9;;;;;;:16;49913:676;;50621:3;50605:13;:19;;;;48750:1886;;;50646:60;50675:1;50679:2;50683:12;50697:8;50646:20;:60::i;:::-;48377:2337;48315:2399;;:::o;34940:324::-;35010:14;35243:1;35233:8;35230:15;35204:24;35200:46;35190:56;;34940:324;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:126::-;1555:7;1595:42;1588:5;1584:54;1573:65;;1518:126;;;:::o;1650:96::-;1687:7;1716:24;1734:5;1716:24;:::i;:::-;1705:35;;1650:96;;;:::o;1752:122::-;1825:24;1843:5;1825:24;:::i;:::-;1818:5;1815:35;1805:63;;1864:1;1861;1854:12;1805:63;1752:122;:::o;1880:139::-;1926:5;1964:6;1951:20;1942:29;;1980:33;2007:5;1980:33;:::i;:::-;1880:139;;;;:::o;2025:109::-;2061:7;2101:26;2094:5;2090:38;2079:49;;2025:109;;;:::o;2140:120::-;2212:23;2229:5;2212:23;:::i;:::-;2205:5;2202:34;2192:62;;2250:1;2247;2240:12;2192:62;2140:120;:::o;2266:137::-;2311:5;2349:6;2336:20;2327:29;;2365:32;2391:5;2365:32;:::i;:::-;2266:137;;;;:::o;2409:472::-;2476:6;2484;2533:2;2521:9;2512:7;2508:23;2504:32;2501:119;;;2539:79;;:::i;:::-;2501:119;2659:1;2684:53;2729:7;2720:6;2709:9;2705:22;2684:53;:::i;:::-;2674:63;;2630:117;2786:2;2812:52;2856:7;2847:6;2836:9;2832:22;2812:52;:::i;:::-;2802:62;;2757:117;2409:472;;;;;:::o;2887:99::-;2939:6;2973:5;2967:12;2957:22;;2887:99;;;:::o;2992:169::-;3076:11;3110:6;3105:3;3098:19;3150:4;3145:3;3141:14;3126:29;;2992:169;;;;:::o;3167:139::-;3256:6;3251:3;3246;3240:23;3297:1;3288:6;3283:3;3279:16;3272:27;3167:139;;;:::o;3312:102::-;3353:6;3404:2;3400:7;3395:2;3388:5;3384:14;3380:28;3370:38;;3312:102;;;:::o;3420:377::-;3508:3;3536:39;3569:5;3536:39;:::i;:::-;3591:71;3655:6;3650:3;3591:71;:::i;:::-;3584:78;;3671:65;3729:6;3724:3;3717:4;3710:5;3706:16;3671:65;:::i;:::-;3761:29;3783:6;3761:29;:::i;:::-;3756:3;3752:39;3745:46;;3512:285;3420:377;;;;:::o;3803:313::-;3916:4;3954:2;3943:9;3939:18;3931:26;;4003:9;3997:4;3993:20;3989:1;3978:9;3974:17;3967:47;4031:78;4104:4;4095:6;4031:78;:::i;:::-;4023:86;;3803:313;;;;:::o;4122:77::-;4159:7;4188:5;4177:16;;4122:77;;;:::o;4205:122::-;4278:24;4296:5;4278:24;:::i;:::-;4271:5;4268:35;4258:63;;4317:1;4314;4307:12;4258:63;4205:122;:::o;4333:139::-;4379:5;4417:6;4404:20;4395:29;;4433:33;4460:5;4433:33;:::i;:::-;4333:139;;;;:::o;4478:329::-;4537:6;4586:2;4574:9;4565:7;4561:23;4557:32;4554:119;;;4592:79;;:::i;:::-;4554:119;4712:1;4737:53;4782:7;4773:6;4762:9;4758:22;4737:53;:::i;:::-;4727:63;;4683:117;4478:329;;;;:::o;4813:118::-;4900:24;4918:5;4900:24;:::i;:::-;4895:3;4888:37;4813:118;;:::o;4937:222::-;5030:4;5068:2;5057:9;5053:18;5045:26;;5081:71;5149:1;5138:9;5134:17;5125:6;5081:71;:::i;:::-;4937:222;;;;:::o;5165:118::-;5252:24;5270:5;5252:24;:::i;:::-;5247:3;5240:37;5165:118;;:::o;5289:222::-;5382:4;5420:2;5409:9;5405:18;5397:26;;5433:71;5501:1;5490:9;5486:17;5477:6;5433:71;:::i;:::-;5289:222;;;;:::o;5517:474::-;5585:6;5593;5642:2;5630:9;5621:7;5617:23;5613:32;5610:119;;;5648:79;;:::i;:::-;5610:119;5768:1;5793:53;5838:7;5829:6;5818:9;5814:22;5793:53;:::i;:::-;5783:63;;5739:117;5895:2;5921:53;5966:7;5957:6;5946:9;5942:22;5921:53;:::i;:::-;5911:63;;5866:118;5517:474;;;;;:::o;5997:619::-;6074:6;6082;6090;6139:2;6127:9;6118:7;6114:23;6110:32;6107:119;;;6145:79;;:::i;:::-;6107:119;6265:1;6290:53;6335:7;6326:6;6315:9;6311:22;6290:53;:::i;:::-;6280:63;;6236:117;6392:2;6418:53;6463:7;6454:6;6443:9;6439:22;6418:53;:::i;:::-;6408:63;;6363:118;6520:2;6546:53;6591:7;6582:6;6571:9;6567:22;6546:53;:::i;:::-;6536:63;;6491:118;5997:619;;;;;:::o;6622:474::-;6690:6;6698;6747:2;6735:9;6726:7;6722:23;6718:32;6715:119;;;6753:79;;:::i;:::-;6715:119;6873:1;6898:53;6943:7;6934:6;6923:9;6919:22;6898:53;:::i;:::-;6888:63;;6844:117;7000:2;7026:53;7071:7;7062:6;7051:9;7047:22;7026:53;:::i;:::-;7016:63;;6971:118;6622:474;;;;;:::o;7102:332::-;7223:4;7261:2;7250:9;7246:18;7238:26;;7274:71;7342:1;7331:9;7327:17;7318:6;7274:71;:::i;:::-;7355:72;7423:2;7412:9;7408:18;7399:6;7355:72;:::i;:::-;7102:332;;;;;:::o;7440:117::-;7549:1;7546;7539:12;7563:117;7672:1;7669;7662:12;7686:180;7734:77;7731:1;7724:88;7831:4;7828:1;7821:15;7855:4;7852:1;7845:15;7872:281;7955:27;7977:4;7955:27;:::i;:::-;7947:6;7943:40;8085:6;8073:10;8070:22;8049:18;8037:10;8034:34;8031:62;8028:88;;;8096:18;;:::i;:::-;8028:88;8136:10;8132:2;8125:22;7915:238;7872:281;;:::o;8159:129::-;8193:6;8220:20;;:::i;:::-;8210:30;;8249:33;8277:4;8269:6;8249:33;:::i;:::-;8159:129;;;:::o;8294:308::-;8356:4;8446:18;8438:6;8435:30;8432:56;;;8468:18;;:::i;:::-;8432:56;8506:29;8528:6;8506:29;:::i;:::-;8498:37;;8590:4;8584;8580:15;8572:23;;8294:308;;;:::o;8608:148::-;8706:6;8701:3;8696;8683:30;8747:1;8738:6;8733:3;8729:16;8722:27;8608:148;;;:::o;8762:425::-;8840:5;8865:66;8881:49;8923:6;8881:49;:::i;:::-;8865:66;:::i;:::-;8856:75;;8954:6;8947:5;8940:21;8992:4;8985:5;8981:16;9030:3;9021:6;9016:3;9012:16;9009:25;9006:112;;;9037:79;;:::i;:::-;9006:112;9127:54;9174:6;9169:3;9164;9127:54;:::i;:::-;8846:341;8762:425;;;;;:::o;9207:340::-;9263:5;9312:3;9305:4;9297:6;9293:17;9289:27;9279:122;;9320:79;;:::i;:::-;9279:122;9437:6;9424:20;9462:79;9537:3;9529:6;9522:4;9514:6;9510:17;9462:79;:::i;:::-;9453:88;;9269:278;9207:340;;;;:::o;9553:509::-;9622:6;9671:2;9659:9;9650:7;9646:23;9642:32;9639:119;;;9677:79;;:::i;:::-;9639:119;9825:1;9814:9;9810:17;9797:31;9855:18;9847:6;9844:30;9841:117;;;9877:79;;:::i;:::-;9841:117;9982:63;10037:7;10028:6;10017:9;10013:22;9982:63;:::i;:::-;9972:73;;9768:287;9553:509;;;;:::o;10068:329::-;10127:6;10176:2;10164:9;10155:7;10151:23;10147:32;10144:119;;;10182:79;;:::i;:::-;10144:119;10302:1;10327:53;10372:7;10363:6;10352:9;10348:22;10327:53;:::i;:::-;10317:63;;10273:117;10068:329;;;;:::o;10403:116::-;10473:21;10488:5;10473:21;:::i;:::-;10466:5;10463:32;10453:60;;10509:1;10506;10499:12;10453:60;10403:116;:::o;10525:133::-;10568:5;10606:6;10593:20;10584:29;;10622:30;10646:5;10622:30;:::i;:::-;10525:133;;;;:::o;10664:468::-;10729:6;10737;10786:2;10774:9;10765:7;10761:23;10757:32;10754:119;;;10792:79;;:::i;:::-;10754:119;10912:1;10937:53;10982:7;10973:6;10962:9;10958:22;10937:53;:::i;:::-;10927:63;;10883:117;11039:2;11065:50;11107:7;11098:6;11087:9;11083:22;11065:50;:::i;:::-;11055:60;;11010:115;10664:468;;;;;:::o;11138:307::-;11199:4;11289:18;11281:6;11278:30;11275:56;;;11311:18;;:::i;:::-;11275:56;11349:29;11371:6;11349:29;:::i;:::-;11341:37;;11433:4;11427;11423:15;11415:23;;11138:307;;;:::o;11451:423::-;11528:5;11553:65;11569:48;11610:6;11569:48;:::i;:::-;11553:65;:::i;:::-;11544:74;;11641:6;11634:5;11627:21;11679:4;11672:5;11668:16;11717:3;11708:6;11703:3;11699:16;11696:25;11693:112;;;11724:79;;:::i;:::-;11693:112;11814:54;11861:6;11856:3;11851;11814:54;:::i;:::-;11534:340;11451:423;;;;;:::o;11893:338::-;11948:5;11997:3;11990:4;11982:6;11978:17;11974:27;11964:122;;12005:79;;:::i;:::-;11964:122;12122:6;12109:20;12147:78;12221:3;12213:6;12206:4;12198:6;12194:17;12147:78;:::i;:::-;12138:87;;11954:277;11893:338;;;;:::o;12237:943::-;12332:6;12340;12348;12356;12405:3;12393:9;12384:7;12380:23;12376:33;12373:120;;;12412:79;;:::i;:::-;12373:120;12532:1;12557:53;12602:7;12593:6;12582:9;12578:22;12557:53;:::i;:::-;12547:63;;12503:117;12659:2;12685:53;12730:7;12721:6;12710:9;12706:22;12685:53;:::i;:::-;12675:63;;12630:118;12787:2;12813:53;12858:7;12849:6;12838:9;12834:22;12813:53;:::i;:::-;12803:63;;12758:118;12943:2;12932:9;12928:18;12915:32;12974:18;12966:6;12963:30;12960:117;;;12996:79;;:::i;:::-;12960:117;13101:62;13155:7;13146:6;13135:9;13131:22;13101:62;:::i;:::-;13091:72;;12886:287;12237:943;;;;;;;:::o;13186:474::-;13254:6;13262;13311:2;13299:9;13290:7;13286:23;13282:32;13279:119;;;13317:79;;:::i;:::-;13279:119;13437:1;13462:53;13507:7;13498:6;13487:9;13483:22;13462:53;:::i;:::-;13452:63;;13408:117;13564:2;13590:53;13635:7;13626:6;13615:9;13611:22;13590:53;:::i;:::-;13580:63;;13535:118;13186:474;;;;;:::o;13666:117::-;13775:1;13772;13765:12;13789:117;13898:1;13895;13888:12;13929:568;14002:8;14012:6;14062:3;14055:4;14047:6;14043:17;14039:27;14029:122;;14070:79;;:::i;:::-;14029:122;14183:6;14170:20;14160:30;;14213:18;14205:6;14202:30;14199:117;;;14235:79;;:::i;:::-;14199:117;14349:4;14341:6;14337:17;14325:29;;14403:3;14395:4;14387:6;14383:17;14373:8;14369:32;14366:41;14363:128;;;14410:79;;:::i;:::-;14363:128;13929:568;;;;;:::o;14503:704::-;14598:6;14606;14614;14663:2;14651:9;14642:7;14638:23;14634:32;14631:119;;;14669:79;;:::i;:::-;14631:119;14789:1;14814:53;14859:7;14850:6;14839:9;14835:22;14814:53;:::i;:::-;14804:63;;14760:117;14944:2;14933:9;14929:18;14916:32;14975:18;14967:6;14964:30;14961:117;;;14997:79;;:::i;:::-;14961:117;15110:80;15182:7;15173:6;15162:9;15158:22;15110:80;:::i;:::-;15092:98;;;;14887:313;14503:704;;;;;:::o;15213:180::-;15261:77;15258:1;15251:88;15358:4;15355:1;15348:15;15382:4;15379:1;15372:15;15399:320;15443:6;15480:1;15474:4;15470:12;15460:22;;15527:1;15521:4;15517:12;15548:18;15538:81;;15604:4;15596:6;15592:17;15582:27;;15538:81;15666:2;15658:6;15655:14;15635:18;15632:38;15629:84;;15685:18;;:::i;:::-;15629:84;15450:269;15399:320;;;:::o;15725:180::-;15773:77;15770:1;15763:88;15870:4;15867:1;15860:15;15894:4;15891:1;15884:15;15911:410;15951:7;15974:20;15992:1;15974:20;:::i;:::-;15969:25;;16008:20;16026:1;16008:20;:::i;:::-;16003:25;;16063:1;16060;16056:9;16085:30;16103:11;16085:30;:::i;:::-;16074:41;;16264:1;16255:7;16251:15;16248:1;16245:22;16225:1;16218:9;16198:83;16175:139;;16294:18;;:::i;:::-;16175:139;15959:362;15911:410;;;;:::o;16327:180::-;16375:77;16372:1;16365:88;16472:4;16469:1;16462:15;16496:4;16493:1;16486:15;16513:185;16553:1;16570:20;16588:1;16570:20;:::i;:::-;16565:25;;16604:20;16622:1;16604:20;:::i;:::-;16599:25;;16643:1;16633:35;;16648:18;;:::i;:::-;16633:35;16690:1;16687;16683:9;16678:14;;16513:185;;;;:::o;16704:141::-;16753:4;16776:3;16768:11;;16799:3;16796:1;16789:14;16833:4;16830:1;16820:18;16812:26;;16704:141;;;:::o;16851:93::-;16888:6;16935:2;16930;16923:5;16919:14;16915:23;16905:33;;16851:93;;;:::o;16950:107::-;16994:8;17044:5;17038:4;17034:16;17013:37;;16950:107;;;;:::o;17063:393::-;17132:6;17182:1;17170:10;17166:18;17205:97;17235:66;17224:9;17205:97;:::i;:::-;17323:39;17353:8;17342:9;17323:39;:::i;:::-;17311:51;;17395:4;17391:9;17384:5;17380:21;17371:30;;17444:4;17434:8;17430:19;17423:5;17420:30;17410:40;;17139:317;;17063:393;;;;;:::o;17462:60::-;17490:3;17511:5;17504:12;;17462:60;;;:::o;17528:142::-;17578:9;17611:53;17629:34;17638:24;17656:5;17638:24;:::i;:::-;17629:34;:::i;:::-;17611:53;:::i;:::-;17598:66;;17528:142;;;:::o;17676:75::-;17719:3;17740:5;17733:12;;17676:75;;;:::o;17757:269::-;17867:39;17898:7;17867:39;:::i;:::-;17928:91;17977:41;18001:16;17977:41;:::i;:::-;17969:6;17962:4;17956:11;17928:91;:::i;:::-;17922:4;17915:105;17833:193;17757:269;;;:::o;18032:73::-;18077:3;18032:73;:::o;18111:189::-;18188:32;;:::i;:::-;18229:65;18287:6;18279;18273:4;18229:65;:::i;:::-;18164:136;18111:189;;:::o;18306:186::-;18366:120;18383:3;18376:5;18373:14;18366:120;;;18437:39;18474:1;18467:5;18437:39;:::i;:::-;18410:1;18403:5;18399:13;18390:22;;18366:120;;;18306:186;;:::o;18498:543::-;18599:2;18594:3;18591:11;18588:446;;;18633:38;18665:5;18633:38;:::i;:::-;18717:29;18735:10;18717:29;:::i;:::-;18707:8;18703:44;18900:2;18888:10;18885:18;18882:49;;;18921:8;18906:23;;18882:49;18944:80;19000:22;19018:3;19000:22;:::i;:::-;18990:8;18986:37;18973:11;18944:80;:::i;:::-;18603:431;;18588:446;18498:543;;;:::o;19047:117::-;19101:8;19151:5;19145:4;19141:16;19120:37;;19047:117;;;;:::o;19170:169::-;19214:6;19247:51;19295:1;19291:6;19283:5;19280:1;19276:13;19247:51;:::i;:::-;19243:56;19328:4;19322;19318:15;19308:25;;19221:118;19170:169;;;;:::o;19344:295::-;19420:4;19566:29;19591:3;19585:4;19566:29;:::i;:::-;19558:37;;19628:3;19625:1;19621:11;19615:4;19612:21;19604:29;;19344:295;;;;:::o;19644:1395::-;19761:37;19794:3;19761:37;:::i;:::-;19863:18;19855:6;19852:30;19849:56;;;19885:18;;:::i;:::-;19849:56;19929:38;19961:4;19955:11;19929:38;:::i;:::-;20014:67;20074:6;20066;20060:4;20014:67;:::i;:::-;20108:1;20132:4;20119:17;;20164:2;20156:6;20153:14;20181:1;20176:618;;;;20838:1;20855:6;20852:77;;;20904:9;20899:3;20895:19;20889:26;20880:35;;20852:77;20955:67;21015:6;21008:5;20955:67;:::i;:::-;20949:4;20942:81;20811:222;20146:887;;20176:618;20228:4;20224:9;20216:6;20212:22;20262:37;20294:4;20262:37;:::i;:::-;20321:1;20335:208;20349:7;20346:1;20343:14;20335:208;;;20428:9;20423:3;20419:19;20413:26;20405:6;20398:42;20479:1;20471:6;20467:14;20457:24;;20526:2;20515:9;20511:18;20498:31;;20372:4;20369:1;20365:12;20360:17;;20335:208;;;20571:6;20562:7;20559:19;20556:179;;;20629:9;20624:3;20620:19;20614:26;20672:48;20714:4;20706:6;20702:17;20691:9;20672:48;:::i;:::-;20664:6;20657:64;20579:156;20556:179;20781:1;20777;20769:6;20765:14;20761:22;20755:4;20748:36;20183:611;;;20146:887;;19736:1303;;;19644:1395;;:::o;21045:191::-;21085:3;21104:20;21122:1;21104:20;:::i;:::-;21099:25;;21138:20;21156:1;21138:20;:::i;:::-;21133:25;;21181:1;21178;21174:9;21167:16;;21202:3;21199:1;21196:10;21193:36;;;21209:18;;:::i;:::-;21193:36;21045:191;;;;:::o;21242:179::-;21382:31;21378:1;21370:6;21366:14;21359:55;21242:179;:::o;21427:366::-;21569:3;21590:67;21654:2;21649:3;21590:67;:::i;:::-;21583:74;;21666:93;21755:3;21666:93;:::i;:::-;21784:2;21779:3;21775:12;21768:19;;21427:366;;;:::o;21799:419::-;21965:4;22003:2;21992:9;21988:18;21980:26;;22052:9;22046:4;22042:20;22038:1;22027:9;22023:17;22016:47;22080:131;22206:4;22080:131;:::i;:::-;22072:139;;21799:419;;;:::o;22224:179::-;22364:31;22360:1;22352:6;22348:14;22341:55;22224:179;:::o;22409:366::-;22551:3;22572:67;22636:2;22631:3;22572:67;:::i;:::-;22565:74;;22648:93;22737:3;22648:93;:::i;:::-;22766:2;22761:3;22757:12;22750:19;;22409:366;;;:::o;22781:419::-;22947:4;22985:2;22974:9;22970:18;22962:26;;23034:9;23028:4;23024:20;23020:1;23009:9;23005:17;22998:47;23062:131;23188:4;23062:131;:::i;:::-;23054:139;;22781:419;;;:::o;23206:174::-;23346:26;23342:1;23334:6;23330:14;23323:50;23206:174;:::o;23386:366::-;23528:3;23549:67;23613:2;23608:3;23549:67;:::i;:::-;23542:74;;23625:93;23714:3;23625:93;:::i;:::-;23743:2;23738:3;23734:12;23727:19;;23386:366;;;:::o;23758:419::-;23924:4;23962:2;23951:9;23947:18;23939:26;;24011:9;24005:4;24001:20;23997:1;23986:9;23982:17;23975:47;24039:131;24165:4;24039:131;:::i;:::-;24031:139;;23758:419;;;:::o;24183:171::-;24323:23;24319:1;24311:6;24307:14;24300:47;24183:171;:::o;24360:366::-;24502:3;24523:67;24587:2;24582:3;24523:67;:::i;:::-;24516:74;;24599:93;24688:3;24599:93;:::i;:::-;24717:2;24712:3;24708:12;24701:19;;24360:366;;;:::o;24732:419::-;24898:4;24936:2;24925:9;24921:18;24913:26;;24985:9;24979:4;24975:20;24971:1;24960:9;24956:17;24949:47;25013:131;25139:4;25013:131;:::i;:::-;25005:139;;24732:419;;;:::o;25157:148::-;25259:11;25296:3;25281:18;;25157:148;;;;:::o;25311:390::-;25417:3;25445:39;25478:5;25445:39;:::i;:::-;25500:89;25582:6;25577:3;25500:89;:::i;:::-;25493:96;;25598:65;25656:6;25651:3;25644:4;25637:5;25633:16;25598:65;:::i;:::-;25688:6;25683:3;25679:16;25672:23;;25421:280;25311:390;;;;:::o;25707:155::-;25847:7;25843:1;25835:6;25831:14;25824:31;25707:155;:::o;25868:400::-;26028:3;26049:84;26131:1;26126:3;26049:84;:::i;:::-;26042:91;;26142:93;26231:3;26142:93;:::i;:::-;26260:1;26255:3;26251:11;26244:18;;25868:400;;;:::o;26274:701::-;26555:3;26577:95;26668:3;26659:6;26577:95;:::i;:::-;26570:102;;26689:95;26780:3;26771:6;26689:95;:::i;:::-;26682:102;;26801:148;26945:3;26801:148;:::i;:::-;26794:155;;26966:3;26959:10;;26274:701;;;;;:::o;26981:180::-;27029:77;27026:1;27019:88;27126:4;27123:1;27116:15;27150:4;27147:1;27140:15;27167:174;27307:26;27303:1;27295:6;27291:14;27284:50;27167:174;:::o;27347:366::-;27489:3;27510:67;27574:2;27569:3;27510:67;:::i;:::-;27503:74;;27586:93;27675:3;27586:93;:::i;:::-;27704:2;27699:3;27695:12;27688:19;;27347:366;;;:::o;27719:419::-;27885:4;27923:2;27912:9;27908:18;27900:26;;27972:9;27966:4;27962:20;27958:1;27947:9;27943:17;27936:47;28000:131;28126:4;28000:131;:::i;:::-;27992:139;;27719:419;;;:::o;28144:140::-;28193:9;28226:52;28244:33;28253:23;28270:5;28253:23;:::i;:::-;28244:33;:::i;:::-;28226:52;:::i;:::-;28213:65;;28144:140;;;:::o;28290:129::-;28376:36;28406:5;28376:36;:::i;:::-;28371:3;28364:49;28290:129;;:::o;28425:330::-;28545:4;28583:2;28572:9;28568:18;28560:26;;28596:70;28663:1;28652:9;28648:17;28639:6;28596:70;:::i;:::-;28676:72;28744:2;28733:9;28729:18;28720:6;28676:72;:::i;:::-;28425:330;;;;;:::o;28761:171::-;28800:3;28823:24;28841:5;28823:24;:::i;:::-;28814:33;;28869:4;28862:5;28859:15;28856:41;;28877:18;;:::i;:::-;28856:41;28924:1;28917:5;28913:13;28906:20;;28761:171;;;:::o;28938:98::-;28989:6;29023:5;29017:12;29007:22;;28938:98;;;:::o;29042:168::-;29125:11;29159:6;29154:3;29147:19;29199:4;29194:3;29190:14;29175:29;;29042:168;;;;:::o;29216:373::-;29302:3;29330:38;29362:5;29330:38;:::i;:::-;29384:70;29447:6;29442:3;29384:70;:::i;:::-;29377:77;;29463:65;29521:6;29516:3;29509:4;29502:5;29498:16;29463:65;:::i;:::-;29553:29;29575:6;29553:29;:::i;:::-;29548:3;29544:39;29537:46;;29306:283;29216:373;;;;:::o;29595:640::-;29790:4;29828:3;29817:9;29813:19;29805:27;;29842:71;29910:1;29899:9;29895:17;29886:6;29842:71;:::i;:::-;29923:72;29991:2;29980:9;29976:18;29967:6;29923:72;:::i;:::-;30005;30073:2;30062:9;30058:18;30049:6;30005:72;:::i;:::-;30124:9;30118:4;30114:20;30109:2;30098:9;30094:18;30087:48;30152:76;30223:4;30214:6;30152:76;:::i;:::-;30144:84;;29595:640;;;;;;;:::o;30241:141::-;30297:5;30328:6;30322:13;30313:22;;30344:32;30370:5;30344:32;:::i;:::-;30241:141;;;;:::o;30388:349::-;30457:6;30506:2;30494:9;30485:7;30481:23;30477:32;30474:119;;;30512:79;;:::i;:::-;30474:119;30632:1;30657:63;30712:7;30703:6;30692:9;30688:22;30657:63;:::i;:::-;30647:73;;30603:127;30388:349;;;;:::o
Swarm Source
ipfs://bee1f5776f6c3b0e6911bea8c5d4b62d07d186f676a350da13d295f0c03099aa
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.