Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
Overview
Max Total Supply
76 MadHatters
Holders
24
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
5 MadHattersLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
MadHatters
Compiler Version
v0.8.13+commit.abaa5c0e
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-04-02 */ // SPDX-License-Identifier: MIT // File: IOperatorFilterRegistry.sol pragma solidity ^0.8.13; interface IOperatorFilterRegistry { function isOperatorAllowed(address registrant, address operator) external view returns (bool); function register(address registrant) external; function registerAndSubscribe(address registrant, address subscription) external; function registerAndCopyEntries( address registrant, address registrantToCopy ) external; function unregister(address addr) external; function updateOperator( address registrant, address operator, bool filtered ) external; function updateOperators( address registrant, address[] calldata operators, bool filtered ) external; function updateCodeHash( address registrant, bytes32 codehash, bool filtered ) external; function updateCodeHashes( address registrant, bytes32[] calldata codeHashes, bool filtered ) external; function subscribe(address registrant, address registrantToSubscribe) external; function unsubscribe(address registrant, bool copyExistingEntries) external; function subscriptionOf(address addr) external returns (address registrant); function subscribers(address registrant) external returns (address[] memory); function subscriberAt(address registrant, uint256 index) external returns (address); function copyEntriesOf(address registrant, address registrantToCopy) external; function isOperatorFiltered(address registrant, address operator) external returns (bool); function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); function filteredOperators(address addr) external returns (address[] memory); function filteredCodeHashes(address addr) external returns (bytes32[] memory); function filteredOperatorAt(address registrant, uint256 index) external returns (address); function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); function isRegistered(address addr) external returns (bool); function codeHashOf(address addr) external returns (bytes32); } // File: OperatorFilterer.sol pragma solidity ^0.8.13; /** * @title OperatorFilterer * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another * registrant's entries in the OperatorFilterRegistry. */ abstract contract OperatorFilterer { error OperatorNotAllowed(address operator); IOperatorFilterRegistry constant OPERATOR_FILTER_REGISTRY = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); constructor(address subscriptionOrRegistrantToCopy, bool subscribe) { // If an inheriting token contract is deployed to a network without the registry deployed, the modifier // will not revert, but the contract will need to be registered with the registry once it is deployed in // order for the modifier to filter addresses. if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { if (subscribe) { OPERATOR_FILTER_REGISTRY.registerAndSubscribe( address(this), subscriptionOrRegistrantToCopy ); } else { if (subscriptionOrRegistrantToCopy != address(0)) { OPERATOR_FILTER_REGISTRY.registerAndCopyEntries( address(this), subscriptionOrRegistrantToCopy ); } else { OPERATOR_FILTER_REGISTRY.register(address(this)); } } } } modifier onlyAllowedOperator(address from) virtual { // Check registry code length to facilitate testing in environments without a deployed registry. if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { // Allow spending tokens from addresses with balance // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred // from an EOA. if (from == msg.sender) { _; return; } if ( !OPERATOR_FILTER_REGISTRY.isOperatorAllowed( address(this), msg.sender ) ) { revert OperatorNotAllowed(msg.sender); } } _; } modifier onlyAllowedOperatorApproval(address operator) virtual { // Check registry code length to facilitate testing in environments without a deployed registry. if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { if ( !OPERATOR_FILTER_REGISTRY.isOperatorAllowed( address(this), operator ) ) { revert OperatorNotAllowed(operator); } } _; } } // File: DefaultOperatorFilterer.sol pragma solidity ^0.8.13; /** * @title DefaultOperatorFilterer * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription. */ abstract contract DefaultOperatorFilterer is OperatorFilterer { address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {} } // File: OrigamiClubNFTv3.sol /** *Submitted for verification at Etherscan.io on 2022-08-31 */ // File: https://github.com/chiru-labs/ERC721A/blob/main/contracts/IERC721A.sol // ERC721A Contracts v4.2.2 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer( address indexed from, address indexed to, uint256 indexed tokenId ); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval( address indexed owner, address indexed approved, uint256 indexed tokenId ); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll( address indexed owner, address indexed operator, bool approved ); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @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; /** * @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; /** * @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: https://github.com/chiru-labs/ERC721A/blob/main/contracts/ERC721A.sol // ERC721A Contracts v4.2.2 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr) if (curr < _currentIndex) { uint256 packed = _packedOwnerships[curr]; // If not burned. if (packed & _BITMASK_BURNED == 0) { // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `curr` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or( owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags) ) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ownerOf(tokenId); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned. } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); ( uint256 approvedAddressSlot, address approvedAddress ) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if ( !_isSenderApprovedOrOwner( approvedAddress, from, _msgSenderERC721A() ) ) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public 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 virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received( _msgSenderERC721A(), from, tokenId, _data ) returns (bytes4 retval) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 toMasked; uint256 end = startTokenId + quantity; // Use assembly to loop and emit the `Transfer` event for gas savings. // The duplicated `log4` removes an extra check and reduces stack juggling. // The assembly, together with the surrounding Solidity code, have been // delicately arranged to nudge the compiler into producing optimized opcodes. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. startTokenId // `tokenId`. ) for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } if (toMasked == 0) revert MintToZeroAddress(); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer( startTokenId, startTokenId + quantity - 1, address(0), to ); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if ( !_checkContractOnERC721Received( address(0), to, index++, _data ) ) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ""); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); ( uint256 approvedAddressSlot, address approvedAddress ) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if ( !_isSenderApprovedOrOwner( approvedAddress, from, _msgSenderERC721A() ) ) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } } // File: https://github.com/chiru-labs/ERC721A/blob/main/contracts/extensions/IERC721AQueryable.sol // ERC721A Contracts v4.2.2 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721AQueryable. */ interface IERC721AQueryable is IERC721A { /** * Invalid query range (`start` >= `stop`). */ error InvalidQueryRange(); /** * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting. * * If the `tokenId` is out of bounds: * * - `addr = address(0)` * - `startTimestamp = 0` * - `burned = false` * - `extraData = 0` * * If the `tokenId` is burned: * * - `addr = <Address of owner before token was burned>` * - `startTimestamp = <Timestamp when token was burned>` * - `burned = true` * - `extraData = <Extra data when token was burned>` * * Otherwise: * * - `addr = <Address of owner>` * - `startTimestamp = <Timestamp of start of ownership>` * - `burned = false` * - `extraData = <Extra data at start of ownership>` */ function explicitOwnershipOf(uint256 tokenId) external view returns (TokenOwnership memory); /** * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order. * See {ERC721AQueryable-explicitOwnershipOf} */ function explicitOwnershipsOf(uint256[] memory tokenIds) external view returns (TokenOwnership[] memory); /** * @dev Returns an array of token IDs owned by `owner`, * in the range [`start`, `stop`) * (i.e. `start <= tokenId < stop`). * * This function allows for tokens to be queried if the collection * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}. * * Requirements: * * - `start < stop` */ function tokensOfOwnerIn( address owner, uint256 start, uint256 stop ) external view returns (uint256[] memory); /** * @dev Returns an array of token IDs owned by `owner`. * * This function scans the ownership mapping and is O(`totalSupply`) in complexity. * It is meant to be called off-chain. * * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into * multiple smaller scans if the collection is large enough to cause * an out-of-gas error (10K collections should be fine). */ function tokensOfOwner(address owner) external view returns (uint256[] memory); } // File: https://github.com/chiru-labs/ERC721A/blob/main/contracts/extensions/ERC721AQueryable.sol // ERC721A Contracts v4.2.2 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @title ERC721AQueryable. * * @dev ERC721A subclass with convenience query functions. */ abstract contract ERC721AQueryable is ERC721A, IERC721AQueryable { /** * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting. * * If the `tokenId` is out of bounds: * * - `addr = address(0)` * - `startTimestamp = 0` * - `burned = false` * - `extraData = 0` * * If the `tokenId` is burned: * * - `addr = <Address of owner before token was burned>` * - `startTimestamp = <Timestamp when token was burned>` * - `burned = true` * - `extraData = <Extra data when token was burned>` * * Otherwise: * * - `addr = <Address of owner>` * - `startTimestamp = <Timestamp of start of ownership>` * - `burned = false` * - `extraData = <Extra data at start of ownership>` */ function explicitOwnershipOf(uint256 tokenId) public view virtual override returns (TokenOwnership memory) { TokenOwnership memory ownership; if (tokenId < _startTokenId() || tokenId >= _nextTokenId()) { return ownership; } ownership = _ownershipAt(tokenId); if (ownership.burned) { return ownership; } return _ownershipOf(tokenId); } /** * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order. * See {ERC721AQueryable-explicitOwnershipOf} */ function explicitOwnershipsOf(uint256[] calldata tokenIds) external view virtual override returns (TokenOwnership[] memory) { unchecked { uint256 tokenIdsLength = tokenIds.length; TokenOwnership[] memory ownerships = new TokenOwnership[]( tokenIdsLength ); for (uint256 i; i != tokenIdsLength; ++i) { ownerships[i] = explicitOwnershipOf(tokenIds[i]); } return ownerships; } } /** * @dev Returns an array of token IDs owned by `owner`, * in the range [`start`, `stop`) * (i.e. `start <= tokenId < stop`). * * This function allows for tokens to be queried if the collection * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}. * * Requirements: * * - `start < stop` */ function tokensOfOwnerIn( address owner, uint256 start, uint256 stop ) external view virtual override returns (uint256[] memory) { unchecked { if (start >= stop) revert InvalidQueryRange(); uint256 tokenIdsIdx; uint256 stopLimit = _nextTokenId(); // Set `start = max(start, _startTokenId())`. if (start < _startTokenId()) { start = _startTokenId(); } // Set `stop = min(stop, stopLimit)`. if (stop > stopLimit) { stop = stopLimit; } uint256 tokenIdsMaxLength = balanceOf(owner); // Set `tokenIdsMaxLength = min(balanceOf(owner), stop - start)`, // to cater for cases where `balanceOf(owner)` is too big. if (start < stop) { uint256 rangeLength = stop - start; if (rangeLength < tokenIdsMaxLength) { tokenIdsMaxLength = rangeLength; } } else { tokenIdsMaxLength = 0; } uint256[] memory tokenIds = new uint256[](tokenIdsMaxLength); if (tokenIdsMaxLength == 0) { return tokenIds; } // We need to call `explicitOwnershipOf(start)`, // because the slot at `start` may not be initialized. TokenOwnership memory ownership = explicitOwnershipOf(start); address currOwnershipAddr; // If the starting slot exists (i.e. not burned), initialize `currOwnershipAddr`. // `ownership.address` will not be zero, as `start` is clamped to the valid token ID range. if (!ownership.burned) { currOwnershipAddr = ownership.addr; } for ( uint256 i = start; i != stop && tokenIdsIdx != tokenIdsMaxLength; ++i ) { ownership = _ownershipAt(i); if (ownership.burned) { continue; } if (ownership.addr != address(0)) { currOwnershipAddr = ownership.addr; } if (currOwnershipAddr == owner) { tokenIds[tokenIdsIdx++] = i; } } // Downsize the array to fit. assembly { mstore(tokenIds, tokenIdsIdx) } return tokenIds; } } /** * @dev Returns an array of token IDs owned by `owner`. * * This function scans the ownership mapping and is O(`totalSupply`) in complexity. * It is meant to be called off-chain. * * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into * multiple smaller scans if the collection is large enough to cause * an out-of-gas error (10K collections should be fine). */ function tokensOfOwner(address owner) external view virtual override returns (uint256[] memory) { unchecked { uint256 tokenIdsIdx; address currOwnershipAddr; uint256 tokenIdsLength = balanceOf(owner); uint256[] memory tokenIds = new uint256[](tokenIdsLength); TokenOwnership memory ownership; for ( uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i ) { ownership = _ownershipAt(i); if (ownership.burned) { continue; } if (ownership.addr != address(0)) { currOwnershipAddr = ownership.addr; } if (currOwnershipAddr == owner) { tokenIds[tokenIdsIdx++] = i; } } return tokenIds; } } } // File: https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol pragma solidity >=0.8.0; /// @notice Simple single owner authorization mixin. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol) abstract contract Owned { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event OwnerUpdated(address indexed user, address indexed newOwner); /*////////////////////////////////////////////////////////////// OWNERSHIP STORAGE //////////////////////////////////////////////////////////////*/ address public owner; modifier onlyOwner() virtual { require(msg.sender == owner, "UNAUTHORIZED"); _; } /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(address _owner) { owner = _owner; emit OwnerUpdated(address(0), _owner); } /*////////////////////////////////////////////////////////////// OWNERSHIP LOGIC //////////////////////////////////////////////////////////////*/ function setOwner(address newOwner) public virtual onlyOwner { owner = newOwner; emit OwnerUpdated(msg.sender, newOwner); } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require( address(this).balance >= amount, "Address: insufficient balance" ); (bool success, ) = recipient.call{value: amount}(""); require( success, "Address: unable to send value, recipient may have reverted" ); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue( target, data, 0, "Address: low-level call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue( target, data, value, "Address: low-level call with value failed" ); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require( address(this).balance >= value, "Address: insufficient balance for call" ); (bool success, bytes memory returndata) = target.call{value: value}( data ); return verifyCallResultFromTarget( target, success, returndata, errorMessage ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall( target, data, "Address: low-level static call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget( target, success, returndata, errorMessage ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall( target, data, "Address: low-level delegate call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget( target, success, returndata, errorMessage ); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721Receiver.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @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); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @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`. * * 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 calldata data ) external; /** * @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 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 ) external; /** * @dev Transfers `tokenId` token 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; /** * @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; /** * @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); } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/IERC721Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @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); } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require( owner != address(0), "ERC721: address zero is not a valid owner" ); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @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, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require( _isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved" ); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public virtual override { require( _isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved" ); _safeTransfer(from, to, tokenId, data); } /** * @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. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { _transfer(from, to, tokenId); require( _checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @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 (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require( ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner" ); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require( ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner" ); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received( _msgSender(), from, tokenId, data ) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert( "ERC721: transfer to non ERC721Receiver implementer" ); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * 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, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} } // File: contracts/MadHatters.sol pragma solidity ^0.8.4; contract MadHatters is ERC721A, ERC721AQueryable, DefaultOperatorFilterer, Owned { uint256 public FIRST_MINT_PRICE = 0.008 ether; uint256 constant EXTRA_MINT_PRICE = 0.008 ether; uint256 constant MAX_SUPPLY_PLUS_ONE = 556; uint256 constant MAX_PER_WALLET_PLUS_ONE = 6; uint256 RESERVED = 25; string tokenBaseUri = "ipfs://QmRkeajFLK2rkChxSLgj7oNdAMSgfKzFzgd2Futkq4Tmp4/"; bool public paused = true; mapping(address => uint256) private _freeMintedCount; mapping(address => uint256) private _totalMintedCount; constructor() ERC721A("MadHatters", "MadHatters") Owned(msg.sender) {} // Rename mint function to optimize gas function mint_540(uint256 _quantity) external payable { unchecked { require(!paused, "MINTING PAUSED"); require( _totalMintedCount[msg.sender] + _quantity < MAX_PER_WALLET_PLUS_ONE, "MAX PER WALLET IS 5" ); uint256 _totalSupply = totalSupply(); require( _totalSupply + _quantity + RESERVED < MAX_SUPPLY_PLUS_ONE, "MAX SUPPLY REACHED" ); uint256 payForCount = _quantity; uint256 payForFirstMint = 0; uint256 freeMintCount = _freeMintedCount[msg.sender]; if (freeMintCount < 1) { if (_quantity > 1) { payForCount = _quantity - 1; } else { payForCount = 0; } payForFirstMint = 1; _freeMintedCount[msg.sender] = 1; } _totalMintedCount[msg.sender] += _quantity; require( msg.value >= (payForCount * EXTRA_MINT_PRICE + payForFirstMint * FIRST_MINT_PRICE), "INCORRECT ETH AMOUNT" ); _mint(msg.sender, _quantity); } } // Set first mint price function setFirstMintPrice(uint256 _newPrice) public onlyOwner { FIRST_MINT_PRICE = _newPrice; } function freeMintedCount(address owner) external view returns (uint256) { return _freeMintedCount[owner]; } function totalMintedCount(address owner) external view returns (uint256) { return _totalMintedCount[owner]; } function _startTokenId() internal pure override returns (uint256) { return 1; } function _baseURI() internal view override returns (string memory) { return tokenBaseUri; } function setBaseURI(string calldata _newBaseUri) external onlyOwner { tokenBaseUri = _newBaseUri; } function flipSale() external onlyOwner { paused = !paused; } function collectReserves() external onlyOwner { require(RESERVED > 0, "RESERVES TAKEN"); _mint(msg.sender, 25); RESERVED = 0; } function withdraw() external onlyOwner { require(payable(owner).send(address(this).balance), "UNSUCCESSFUL"); } function setApprovalForAll(address operator, bool approved) public override(ERC721A, IERC721A) onlyAllowedOperatorApproval(operator) { super.setApprovalForAll(operator, approved); } function approve(address operator, uint256 tokenId) public override(ERC721A, IERC721A) onlyAllowedOperatorApproval(operator) { super.approve(operator, tokenId); } function transferFrom( address from, address to, uint256 tokenId ) public override(ERC721A, IERC721A) onlyAllowedOperator(from) { super.transferFrom(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId ) public override(ERC721A, IERC721A) onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public override(ERC721A, IERC721A) onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId, data); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","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":"FIRST_MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collectReserves","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flipSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"freeMintedCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"mint_540","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"nonpayable","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":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseUri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setFirstMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"totalMintedCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052661c6bf5263400006009556019600a556040518060600160405280603681526020016200420060369139600b908051906020019062000045929190620003e0565b506001600c60006101000a81548160ff0219169083151502179055503480156200006e57600080fd5b5033733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600a81526020017f4d616448617474657273000000000000000000000000000000000000000000008152506040518060400160405280600a81526020017f4d6164486174746572730000000000000000000000000000000000000000000081525081600290805190602001906200010b929190620003e0565b50806003908051906020019062000124929190620003e0565b5062000135620003d760201b60201c565b600081905550505060006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111562000332578015620001f8576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b8152600401620001be929190620004d5565b600060405180830381600087803b158015620001d957600080fd5b505af1158015620001ee573d6000803e3d6000fd5b5050505062000331565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620002b2576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b815260040162000278929190620004d5565b600060405180830381600087803b1580156200029357600080fd5b505af1158015620002a8573d6000803e3d6000fd5b5050505062000330565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b8152600401620002fb919062000502565b600060405180830381600087803b1580156200031657600080fd5b505af11580156200032b573d6000803e3d6000fd5b505050505b5b5b505080600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7660405160405180910390a35062000583565b60006001905090565b828054620003ee906200054e565b90600052602060002090601f0160209004810192826200041257600085556200045e565b82601f106200042d57805160ff19168380011785556200045e565b828001600101855582156200045e579182015b828111156200045d57825182559160200191906001019062000440565b5b5090506200046d919062000471565b5090565b5b808211156200048c57600081600090555060010162000472565b5090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620004bd8262000490565b9050919050565b620004cf81620004b0565b82525050565b6000604082019050620004ec6000830185620004c4565b620004fb6020830184620004c4565b9392505050565b6000602082019050620005196000830184620004c4565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200056757607f821691505b6020821081036200057d576200057c6200051f565b5b50919050565b613c6d80620005936000396000f3fe6080604052600436106101cb5760003560e01c80636352211e116100f75780639813323511610095578063bfc28c0a11610064578063bfc28c0a14610663578063c23dc68f146106a0578063c87b56dd146106dd578063e985e9c51461071a576101cb565b8063981332351461059757806399a2557a146105d4578063a22cb46514610611578063b88d4fde1461063a576101cb565b80638462151c116100d15780638462151c146104d95780638da5cb5b1461051657806392ee40251461054157806395d89b411461056c576101cb565b80636352211e1461044857806370a08231146104855780637ba5e621146104c2576101cb565b806318160ddd1161016f57806342842e0e1161013e57806342842e0e1461038e57806355f804b3146103b75780635bbb2177146103e05780635c975abb1461041d576101cb565b806318160ddd146102fa5780632052e89d1461032557806323b872dd1461034e5780633ccfd60b14610377576101cb565b806306fdde03116101ab57806306fdde0314610240578063081812fc1461026b578063095ea7b3146102a857806313af4035146102d1576101cb565b80619d1c146101d057806301ffc9a7146101ec578063029877b614610229575b600080fd5b6101ea60048036038101906101e59190612d15565b610757565b005b3480156101f857600080fd5b50610213600480360381019061020e9190612d9a565b6109e7565b6040516102209190612de2565b60405180910390f35b34801561023557600080fd5b5061023e610a79565b005b34801561024c57600080fd5b50610255610b63565b6040516102629190612e96565b60405180910390f35b34801561027757600080fd5b50610292600480360381019061028d9190612d15565b610bf5565b60405161029f9190612ef9565b60405180910390f35b3480156102b457600080fd5b506102cf60048036038101906102ca9190612f40565b610c74565b005b3480156102dd57600080fd5b506102f860048036038101906102f39190612f80565b610d7e565b005b34801561030657600080fd5b5061030f610eac565b60405161031c9190612fbc565b60405180910390f35b34801561033157600080fd5b5061034c60048036038101906103479190612d15565b610ec3565b005b34801561035a57600080fd5b5061037560048036038101906103709190612fd7565b610f5d565b005b34801561038357600080fd5b5061038c6110ad565b005b34801561039a57600080fd5b506103b560048036038101906103b09190612fd7565b6111d5565b005b3480156103c357600080fd5b506103de60048036038101906103d9919061308f565b611325565b005b3480156103ec57600080fd5b5061040760048036038101906104029190613132565b6113cb565b60405161041491906132e2565b60405180910390f35b34801561042957600080fd5b5061043261148e565b60405161043f9190612de2565b60405180910390f35b34801561045457600080fd5b5061046f600480360381019061046a9190612d15565b6114a1565b60405161047c9190612ef9565b60405180910390f35b34801561049157600080fd5b506104ac60048036038101906104a79190612f80565b6114b3565b6040516104b99190612fbc565b60405180910390f35b3480156104ce57600080fd5b506104d761156b565b005b3480156104e557600080fd5b5061050060048036038101906104fb9190612f80565b611627565b60405161050d91906133c2565b60405180910390f35b34801561052257600080fd5b5061052b61176a565b6040516105389190612ef9565b60405180910390f35b34801561054d57600080fd5b50610556611790565b6040516105639190612fbc565b60405180910390f35b34801561057857600080fd5b50610581611796565b60405161058e9190612e96565b60405180910390f35b3480156105a357600080fd5b506105be60048036038101906105b99190612f80565b611828565b6040516105cb9190612fbc565b60405180910390f35b3480156105e057600080fd5b506105fb60048036038101906105f691906133e4565b611871565b60405161060891906133c2565b60405180910390f35b34801561061d57600080fd5b5061063860048036038101906106339190613463565b611a7d565b005b34801561064657600080fd5b50610661600480360381019061065c91906135d3565b611b87565b005b34801561066f57600080fd5b5061068a60048036038101906106859190612f80565b611cda565b6040516106979190612fbc565b60405180910390f35b3480156106ac57600080fd5b506106c760048036038101906106c29190612d15565b611d23565b6040516106d491906136ab565b60405180910390f35b3480156106e957600080fd5b5061070460048036038101906106ff9190612d15565b611d8d565b6040516107119190612e96565b60405180910390f35b34801561072657600080fd5b50610741600480360381019061073c91906136c6565b611e2b565b60405161074e9190612de2565b60405180910390f35b600c60009054906101000a900460ff16156107a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161079e90613752565b60405180910390fd5b600681600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054011061082b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610822906137be565b60405180910390fd5b6000610835610eac565b905061022c600a548383010110610881576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108789061382a565b60405180910390fd5b6000829050600080600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060018110156109375760018511156108e8576001850392506108ed565b600092505b600191506001600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b84600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506009548202661c6bf5263400008402013410156109d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109cd90613896565b60405180910390fd5b6109e03386611ebf565b5050505050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a4257506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a725750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0090613902565b60405180910390fd5b6000600a5411610b4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b459061396e565b60405180910390fd5b610b59336019611ebf565b6000600a81905550565b606060028054610b72906139bd565b80601f0160208091040260200160405190810160405280929190818152602001828054610b9e906139bd565b8015610beb5780601f10610bc057610100808354040283529160200191610beb565b820191906000526020600020905b815481529060010190602001808311610bce57829003601f168201915b5050505050905090565b6000610c008261207a565b610c36576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8160006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610d6f576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401610cec9291906139ee565b602060405180830381865afa158015610d09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2d9190613a2c565b610d6e57806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610d659190612ef9565b60405180910390fd5b5b610d7983836120d9565b505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0590613902565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7660405160405180910390a350565b6000610eb661221d565b6001546000540303905090565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4a90613902565b60405180910390fd5b8060098190555050565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111561109b573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610fcf57610fca848484612226565b6110a7565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016110189291906139ee565b602060405180830381865afa158015611035573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110599190613a2c565b61109a57336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016110919190612ef9565b60405180910390fd5b5b6110a6848484612226565b5b50505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461113d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113490613902565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f193505050506111d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ca90613aa5565b60405180910390fd5b565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611313573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361124757611242848484612548565b61131f565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016112909291906139ee565b602060405180830381865afa1580156112ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d19190613a2c565b61131257336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016113099190612ef9565b60405180910390fd5b5b61131e848484612548565b5b50505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ac90613902565b60405180910390fd5b8181600b91906113c6929190612bd9565b505050565b6060600083839050905060008167ffffffffffffffff8111156113f1576113f06134a8565b5b60405190808252806020026020018201604052801561142a57816020015b611417612c5f565b81526020019060019003908161140f5790505b50905060005b8281146114825761145986868381811061144d5761144c613ac5565b5b90506020020135611d23565b82828151811061146c5761146b613ac5565b5b6020026020010181905250806001019050611430565b50809250505092915050565b600c60009054906101000a900460ff1681565b60006114ac82612568565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361151a576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115f290613902565b60405180910390fd5b600c60009054906101000a900460ff1615600c60006101000a81548160ff021916908315150217905550565b60606000806000611637856114b3565b905060008167ffffffffffffffff811115611655576116546134a8565b5b6040519080825280602002602001820160405280156116835781602001602082028036833780820191505090505b50905061168e612c5f565b600061169861221d565b90505b83861461175c576116ab81612634565b9150816040015161175157600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16146116f657816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611750578083878060010198508151811061174357611742613ac5565b5b6020026020010181815250505b5b80600101905061169b565b508195505050505050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60095481565b6060600380546117a5906139bd565b80601f01602080910402602001604051908101604052809291908181526020018280546117d1906139bd565b801561181e5780601f106117f35761010080835404028352916020019161181e565b820191906000526020600020905b81548152906001019060200180831161180157829003601f168201915b5050505050905090565b6000600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60608183106118ac576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806118b761265f565b90506118c161221d565b8510156118d3576118d061221d565b94505b808411156118df578093505b60006118ea876114b3565b90508486101561190d576000868603905081811015611907578091505b50611912565b600090505b60008167ffffffffffffffff81111561192e5761192d6134a8565b5b60405190808252806020026020018201604052801561195c5781602001602082028036833780820191505090505b509050600082036119735780945050505050611a76565b600061197e88611d23565b90506000816040015161199357816000015190505b60008990505b8881141580156119a95750848714155b15611a68576119b781612634565b92508260400151611a5d57600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614611a0257826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611a5c5780848880600101995081518110611a4f57611a4e613ac5565b5b6020026020010181815250505b5b806001019050611999565b508583528296505050505050505b9392505050565b8160006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611b78576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611af59291906139ee565b602060405180830381865afa158015611b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b369190613a2c565b611b7757806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611b6e9190612ef9565b60405180910390fd5b5b611b828383612668565b505050565b8360006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611cc6573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611bfa57611bf585858585612773565b611cd3565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611c439291906139ee565b602060405180830381865afa158015611c60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c849190613a2c565b611cc557336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611cbc9190612ef9565b60405180910390fd5b5b611cd285858585612773565b5b5050505050565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611d2b612c5f565b611d33612c5f565b611d3b61221d565b831080611d4f5750611d4b61265f565b8310155b15611d5d5780915050611d88565b611d6683612634565b9050806040015115611d7b5780915050611d88565b611d84836127e6565b9150505b919050565b6060611d988261207a565b611dce576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611dd8612806565b90506000815103611df85760405180602001604052806000815250611e23565b80611e0284612898565b604051602001611e13929190613b30565b6040516020818303038152906040525b915050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60008054905060008203611eff576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f0c60008483856128e8565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611f8383611f7460008660006128ee565b611f7d85612916565b17612926565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461202457808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050611fe9565b506000820361205f576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060008190555050506120756000848385612951565b505050565b60008161208561221d565b11158015612094575060005482105b80156120d2575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60006120e4826114a1565b90508073ffffffffffffffffffffffffffffffffffffffff16612105612957565b73ffffffffffffffffffffffffffffffffffffffff1614612168576121318161212c612957565b611e2b565b612167576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006001905090565b600061223182612568565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612298576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806122a48461295f565b915091506122ba81876122b5612957565b612986565b612306576122cf866122ca612957565b611e2b565b612305576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361236c576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61237986868660016128e8565b801561238457600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055506124528561242e8888876128ee565b7c020000000000000000000000000000000000000000000000000000000017612926565b600460008681526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008416036124d857600060018501905060006004600083815260200190815260200160002054036124d65760005481146124d5578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46125408686866001612951565b505050505050565b61256383838360405180602001604052806000815250611b87565b505050565b6000808290508061257761221d565b116125fd576000548110156125fc5760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036125fa575b600081036125f05760046000836001900393508381526020019081526020016000205490506125c6565b809250505061262f565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b61263c612c5f565b61265860046000848152602001908152602001600020546129ca565b9050919050565b60008054905090565b8060076000612675612957565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612722612957565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516127679190612de2565b60405180910390a35050565b61277e848484610f5d565b60008373ffffffffffffffffffffffffffffffffffffffff163b146127e0576127a984848484612a80565b6127df576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6127ee612c5f565b6127ff6127fa83612568565b6129ca565b9050919050565b6060600b8054612815906139bd565b80601f0160208091040260200160405190810160405280929190818152602001828054612841906139bd565b801561288e5780601f106128635761010080835404028352916020019161288e565b820191906000526020600020905b81548152906001019060200180831161287157829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b6001156128d357600184039350600a81066030018453600a81049050806128b1575b50828103602084039350808452505050919050565b50505050565b60008060e883901c905060e8612905868684612bd0565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600033905090565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b6129d2612c5f565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612aa6612957565b8786866040518563ffffffff1660e01b8152600401612ac89493929190613ba9565b6020604051808303816000875af1925050508015612b0457506040513d601f19601f82011682018060405250810190612b019190613c0a565b60015b612b7d573d8060008114612b34576040519150601f19603f3d011682016040523d82523d6000602084013e612b39565b606091505b506000815103612b75576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60009392505050565b828054612be5906139bd565b90600052602060002090601f016020900481019282612c075760008555612c4e565b82601f10612c2057803560ff1916838001178555612c4e565b82800160010185558215612c4e579182015b82811115612c4d578235825591602001919060010190612c32565b5b509050612c5b9190612cae565b5090565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b5b80821115612cc7576000816000905550600101612caf565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b612cf281612cdf565b8114612cfd57600080fd5b50565b600081359050612d0f81612ce9565b92915050565b600060208284031215612d2b57612d2a612cd5565b5b6000612d3984828501612d00565b91505092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612d7781612d42565b8114612d8257600080fd5b50565b600081359050612d9481612d6e565b92915050565b600060208284031215612db057612daf612cd5565b5b6000612dbe84828501612d85565b91505092915050565b60008115159050919050565b612ddc81612dc7565b82525050565b6000602082019050612df76000830184612dd3565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612e37578082015181840152602081019050612e1c565b83811115612e46576000848401525b50505050565b6000601f19601f8301169050919050565b6000612e6882612dfd565b612e728185612e08565b9350612e82818560208601612e19565b612e8b81612e4c565b840191505092915050565b60006020820190508181036000830152612eb08184612e5d565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612ee382612eb8565b9050919050565b612ef381612ed8565b82525050565b6000602082019050612f0e6000830184612eea565b92915050565b612f1d81612ed8565b8114612f2857600080fd5b50565b600081359050612f3a81612f14565b92915050565b60008060408385031215612f5757612f56612cd5565b5b6000612f6585828601612f2b565b9250506020612f7685828601612d00565b9150509250929050565b600060208284031215612f9657612f95612cd5565b5b6000612fa484828501612f2b565b91505092915050565b612fb681612cdf565b82525050565b6000602082019050612fd16000830184612fad565b92915050565b600080600060608486031215612ff057612fef612cd5565b5b6000612ffe86828701612f2b565b935050602061300f86828701612f2b565b925050604061302086828701612d00565b9150509250925092565b600080fd5b600080fd5b600080fd5b60008083601f84011261304f5761304e61302a565b5b8235905067ffffffffffffffff81111561306c5761306b61302f565b5b60208301915083600182028301111561308857613087613034565b5b9250929050565b600080602083850312156130a6576130a5612cd5565b5b600083013567ffffffffffffffff8111156130c4576130c3612cda565b5b6130d085828601613039565b92509250509250929050565b60008083601f8401126130f2576130f161302a565b5b8235905067ffffffffffffffff81111561310f5761310e61302f565b5b60208301915083602082028301111561312b5761312a613034565b5b9250929050565b6000806020838503121561314957613148612cd5565b5b600083013567ffffffffffffffff81111561316757613166612cda565b5b613173858286016130dc565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6131b481612ed8565b82525050565b600067ffffffffffffffff82169050919050565b6131d7816131ba565b82525050565b6131e681612dc7565b82525050565b600062ffffff82169050919050565b613204816131ec565b82525050565b60808201600082015161322060008501826131ab565b50602082015161323360208501826131ce565b50604082015161324660408501826131dd565b50606082015161325960608501826131fb565b50505050565b600061326b838361320a565b60808301905092915050565b6000602082019050919050565b600061328f8261317f565b613299818561318a565b93506132a48361319b565b8060005b838110156132d55781516132bc888261325f565b97506132c783613277565b9250506001810190506132a8565b5085935050505092915050565b600060208201905081810360008301526132fc8184613284565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61333981612cdf565b82525050565b600061334b8383613330565b60208301905092915050565b6000602082019050919050565b600061336f82613304565b613379818561330f565b935061338483613320565b8060005b838110156133b557815161339c888261333f565b97506133a783613357565b925050600181019050613388565b5085935050505092915050565b600060208201905081810360008301526133dc8184613364565b905092915050565b6000806000606084860312156133fd576133fc612cd5565b5b600061340b86828701612f2b565b935050602061341c86828701612d00565b925050604061342d86828701612d00565b9150509250925092565b61344081612dc7565b811461344b57600080fd5b50565b60008135905061345d81613437565b92915050565b6000806040838503121561347a57613479612cd5565b5b600061348885828601612f2b565b92505060206134998582860161344e565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6134e082612e4c565b810181811067ffffffffffffffff821117156134ff576134fe6134a8565b5b80604052505050565b6000613512612ccb565b905061351e82826134d7565b919050565b600067ffffffffffffffff82111561353e5761353d6134a8565b5b61354782612e4c565b9050602081019050919050565b82818337600083830152505050565b600061357661357184613523565b613508565b905082815260208101848484011115613592576135916134a3565b5b61359d848285613554565b509392505050565b600082601f8301126135ba576135b961302a565b5b81356135ca848260208601613563565b91505092915050565b600080600080608085870312156135ed576135ec612cd5565b5b60006135fb87828801612f2b565b945050602061360c87828801612f2b565b935050604061361d87828801612d00565b925050606085013567ffffffffffffffff81111561363e5761363d612cda565b5b61364a878288016135a5565b91505092959194509250565b60808201600082015161366c60008501826131ab565b50602082015161367f60208501826131ce565b50604082015161369260408501826131dd565b5060608201516136a560608501826131fb565b50505050565b60006080820190506136c06000830184613656565b92915050565b600080604083850312156136dd576136dc612cd5565b5b60006136eb85828601612f2b565b92505060206136fc85828601612f2b565b9150509250929050565b7f4d494e54494e4720504155534544000000000000000000000000000000000000600082015250565b600061373c600e83612e08565b915061374782613706565b602082019050919050565b6000602082019050818103600083015261376b8161372f565b9050919050565b7f4d4158205045522057414c4c4554204953203500000000000000000000000000600082015250565b60006137a8601383612e08565b91506137b382613772565b602082019050919050565b600060208201905081810360008301526137d78161379b565b9050919050565b7f4d415820535550504c5920524541434845440000000000000000000000000000600082015250565b6000613814601283612e08565b915061381f826137de565b602082019050919050565b6000602082019050818103600083015261384381613807565b9050919050565b7f494e434f52524543542045544820414d4f554e54000000000000000000000000600082015250565b6000613880601483612e08565b915061388b8261384a565b602082019050919050565b600060208201905081810360008301526138af81613873565b9050919050565b7f554e415554484f52495a45440000000000000000000000000000000000000000600082015250565b60006138ec600c83612e08565b91506138f7826138b6565b602082019050919050565b6000602082019050818103600083015261391b816138df565b9050919050565b7f52455345525645532054414b454e000000000000000000000000000000000000600082015250565b6000613958600e83612e08565b915061396382613922565b602082019050919050565b600060208201905081810360008301526139878161394b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806139d557607f821691505b6020821081036139e8576139e761398e565b5b50919050565b6000604082019050613a036000830185612eea565b613a106020830184612eea565b9392505050565b600081519050613a2681613437565b92915050565b600060208284031215613a4257613a41612cd5565b5b6000613a5084828501613a17565b91505092915050565b7f554e5355434345535346554c0000000000000000000000000000000000000000600082015250565b6000613a8f600c83612e08565b9150613a9a82613a59565b602082019050919050565b60006020820190508181036000830152613abe81613a82565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081905092915050565b6000613b0a82612dfd565b613b148185613af4565b9350613b24818560208601612e19565b80840191505092915050565b6000613b3c8285613aff565b9150613b488284613aff565b91508190509392505050565b600081519050919050565b600082825260208201905092915050565b6000613b7b82613b54565b613b858185613b5f565b9350613b95818560208601612e19565b613b9e81612e4c565b840191505092915050565b6000608082019050613bbe6000830187612eea565b613bcb6020830186612eea565b613bd86040830185612fad565b8181036060830152613bea8184613b70565b905095945050505050565b600081519050613c0481612d6e565b92915050565b600060208284031215613c2057613c1f612cd5565b5b6000613c2e84828501613bf5565b9150509291505056fea2646970667358221220364ecf356f55b0bfde7180c6ce0a6043d653237481f2c7a45da0fbf1a274149464736f6c634300080d0033697066733a2f2f516d526b65616a464c4b32726b436878534c676a376f4e64414d5367664b7a467a6764324675746b7134546d70342f
Deployed Bytecode
0x6080604052600436106101cb5760003560e01c80636352211e116100f75780639813323511610095578063bfc28c0a11610064578063bfc28c0a14610663578063c23dc68f146106a0578063c87b56dd146106dd578063e985e9c51461071a576101cb565b8063981332351461059757806399a2557a146105d4578063a22cb46514610611578063b88d4fde1461063a576101cb565b80638462151c116100d15780638462151c146104d95780638da5cb5b1461051657806392ee40251461054157806395d89b411461056c576101cb565b80636352211e1461044857806370a08231146104855780637ba5e621146104c2576101cb565b806318160ddd1161016f57806342842e0e1161013e57806342842e0e1461038e57806355f804b3146103b75780635bbb2177146103e05780635c975abb1461041d576101cb565b806318160ddd146102fa5780632052e89d1461032557806323b872dd1461034e5780633ccfd60b14610377576101cb565b806306fdde03116101ab57806306fdde0314610240578063081812fc1461026b578063095ea7b3146102a857806313af4035146102d1576101cb565b80619d1c146101d057806301ffc9a7146101ec578063029877b614610229575b600080fd5b6101ea60048036038101906101e59190612d15565b610757565b005b3480156101f857600080fd5b50610213600480360381019061020e9190612d9a565b6109e7565b6040516102209190612de2565b60405180910390f35b34801561023557600080fd5b5061023e610a79565b005b34801561024c57600080fd5b50610255610b63565b6040516102629190612e96565b60405180910390f35b34801561027757600080fd5b50610292600480360381019061028d9190612d15565b610bf5565b60405161029f9190612ef9565b60405180910390f35b3480156102b457600080fd5b506102cf60048036038101906102ca9190612f40565b610c74565b005b3480156102dd57600080fd5b506102f860048036038101906102f39190612f80565b610d7e565b005b34801561030657600080fd5b5061030f610eac565b60405161031c9190612fbc565b60405180910390f35b34801561033157600080fd5b5061034c60048036038101906103479190612d15565b610ec3565b005b34801561035a57600080fd5b5061037560048036038101906103709190612fd7565b610f5d565b005b34801561038357600080fd5b5061038c6110ad565b005b34801561039a57600080fd5b506103b560048036038101906103b09190612fd7565b6111d5565b005b3480156103c357600080fd5b506103de60048036038101906103d9919061308f565b611325565b005b3480156103ec57600080fd5b5061040760048036038101906104029190613132565b6113cb565b60405161041491906132e2565b60405180910390f35b34801561042957600080fd5b5061043261148e565b60405161043f9190612de2565b60405180910390f35b34801561045457600080fd5b5061046f600480360381019061046a9190612d15565b6114a1565b60405161047c9190612ef9565b60405180910390f35b34801561049157600080fd5b506104ac60048036038101906104a79190612f80565b6114b3565b6040516104b99190612fbc565b60405180910390f35b3480156104ce57600080fd5b506104d761156b565b005b3480156104e557600080fd5b5061050060048036038101906104fb9190612f80565b611627565b60405161050d91906133c2565b60405180910390f35b34801561052257600080fd5b5061052b61176a565b6040516105389190612ef9565b60405180910390f35b34801561054d57600080fd5b50610556611790565b6040516105639190612fbc565b60405180910390f35b34801561057857600080fd5b50610581611796565b60405161058e9190612e96565b60405180910390f35b3480156105a357600080fd5b506105be60048036038101906105b99190612f80565b611828565b6040516105cb9190612fbc565b60405180910390f35b3480156105e057600080fd5b506105fb60048036038101906105f691906133e4565b611871565b60405161060891906133c2565b60405180910390f35b34801561061d57600080fd5b5061063860048036038101906106339190613463565b611a7d565b005b34801561064657600080fd5b50610661600480360381019061065c91906135d3565b611b87565b005b34801561066f57600080fd5b5061068a60048036038101906106859190612f80565b611cda565b6040516106979190612fbc565b60405180910390f35b3480156106ac57600080fd5b506106c760048036038101906106c29190612d15565b611d23565b6040516106d491906136ab565b60405180910390f35b3480156106e957600080fd5b5061070460048036038101906106ff9190612d15565b611d8d565b6040516107119190612e96565b60405180910390f35b34801561072657600080fd5b50610741600480360381019061073c91906136c6565b611e2b565b60405161074e9190612de2565b60405180910390f35b600c60009054906101000a900460ff16156107a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161079e90613752565b60405180910390fd5b600681600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054011061082b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610822906137be565b60405180910390fd5b6000610835610eac565b905061022c600a548383010110610881576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108789061382a565b60405180910390fd5b6000829050600080600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060018110156109375760018511156108e8576001850392506108ed565b600092505b600191506001600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b84600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506009548202661c6bf5263400008402013410156109d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109cd90613896565b60405180910390fd5b6109e03386611ebf565b5050505050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a4257506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a725750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0090613902565b60405180910390fd5b6000600a5411610b4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b459061396e565b60405180910390fd5b610b59336019611ebf565b6000600a81905550565b606060028054610b72906139bd565b80601f0160208091040260200160405190810160405280929190818152602001828054610b9e906139bd565b8015610beb5780601f10610bc057610100808354040283529160200191610beb565b820191906000526020600020905b815481529060010190602001808311610bce57829003601f168201915b5050505050905090565b6000610c008261207a565b610c36576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8160006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610d6f576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401610cec9291906139ee565b602060405180830381865afa158015610d09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2d9190613a2c565b610d6e57806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610d659190612ef9565b60405180910390fd5b5b610d7983836120d9565b505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0590613902565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7660405160405180910390a350565b6000610eb661221d565b6001546000540303905090565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4a90613902565b60405180910390fd5b8060098190555050565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111561109b573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610fcf57610fca848484612226565b6110a7565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016110189291906139ee565b602060405180830381865afa158015611035573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110599190613a2c565b61109a57336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016110919190612ef9565b60405180910390fd5b5b6110a6848484612226565b5b50505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461113d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113490613902565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f193505050506111d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ca90613aa5565b60405180910390fd5b565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611313573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361124757611242848484612548565b61131f565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016112909291906139ee565b602060405180830381865afa1580156112ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d19190613a2c565b61131257336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016113099190612ef9565b60405180910390fd5b5b61131e848484612548565b5b50505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ac90613902565b60405180910390fd5b8181600b91906113c6929190612bd9565b505050565b6060600083839050905060008167ffffffffffffffff8111156113f1576113f06134a8565b5b60405190808252806020026020018201604052801561142a57816020015b611417612c5f565b81526020019060019003908161140f5790505b50905060005b8281146114825761145986868381811061144d5761144c613ac5565b5b90506020020135611d23565b82828151811061146c5761146b613ac5565b5b6020026020010181905250806001019050611430565b50809250505092915050565b600c60009054906101000a900460ff1681565b60006114ac82612568565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361151a576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115f290613902565b60405180910390fd5b600c60009054906101000a900460ff1615600c60006101000a81548160ff021916908315150217905550565b60606000806000611637856114b3565b905060008167ffffffffffffffff811115611655576116546134a8565b5b6040519080825280602002602001820160405280156116835781602001602082028036833780820191505090505b50905061168e612c5f565b600061169861221d565b90505b83861461175c576116ab81612634565b9150816040015161175157600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16146116f657816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611750578083878060010198508151811061174357611742613ac5565b5b6020026020010181815250505b5b80600101905061169b565b508195505050505050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60095481565b6060600380546117a5906139bd565b80601f01602080910402602001604051908101604052809291908181526020018280546117d1906139bd565b801561181e5780601f106117f35761010080835404028352916020019161181e565b820191906000526020600020905b81548152906001019060200180831161180157829003601f168201915b5050505050905090565b6000600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60608183106118ac576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806118b761265f565b90506118c161221d565b8510156118d3576118d061221d565b94505b808411156118df578093505b60006118ea876114b3565b90508486101561190d576000868603905081811015611907578091505b50611912565b600090505b60008167ffffffffffffffff81111561192e5761192d6134a8565b5b60405190808252806020026020018201604052801561195c5781602001602082028036833780820191505090505b509050600082036119735780945050505050611a76565b600061197e88611d23565b90506000816040015161199357816000015190505b60008990505b8881141580156119a95750848714155b15611a68576119b781612634565b92508260400151611a5d57600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614611a0257826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611a5c5780848880600101995081518110611a4f57611a4e613ac5565b5b6020026020010181815250505b5b806001019050611999565b508583528296505050505050505b9392505050565b8160006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611b78576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611af59291906139ee565b602060405180830381865afa158015611b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b369190613a2c565b611b7757806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611b6e9190612ef9565b60405180910390fd5b5b611b828383612668565b505050565b8360006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611cc6573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611bfa57611bf585858585612773565b611cd3565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611c439291906139ee565b602060405180830381865afa158015611c60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c849190613a2c565b611cc557336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611cbc9190612ef9565b60405180910390fd5b5b611cd285858585612773565b5b5050505050565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611d2b612c5f565b611d33612c5f565b611d3b61221d565b831080611d4f5750611d4b61265f565b8310155b15611d5d5780915050611d88565b611d6683612634565b9050806040015115611d7b5780915050611d88565b611d84836127e6565b9150505b919050565b6060611d988261207a565b611dce576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611dd8612806565b90506000815103611df85760405180602001604052806000815250611e23565b80611e0284612898565b604051602001611e13929190613b30565b6040516020818303038152906040525b915050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60008054905060008203611eff576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f0c60008483856128e8565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611f8383611f7460008660006128ee565b611f7d85612916565b17612926565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461202457808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050611fe9565b506000820361205f576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060008190555050506120756000848385612951565b505050565b60008161208561221d565b11158015612094575060005482105b80156120d2575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60006120e4826114a1565b90508073ffffffffffffffffffffffffffffffffffffffff16612105612957565b73ffffffffffffffffffffffffffffffffffffffff1614612168576121318161212c612957565b611e2b565b612167576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006001905090565b600061223182612568565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612298576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806122a48461295f565b915091506122ba81876122b5612957565b612986565b612306576122cf866122ca612957565b611e2b565b612305576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361236c576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61237986868660016128e8565b801561238457600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055506124528561242e8888876128ee565b7c020000000000000000000000000000000000000000000000000000000017612926565b600460008681526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008416036124d857600060018501905060006004600083815260200190815260200160002054036124d65760005481146124d5578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46125408686866001612951565b505050505050565b61256383838360405180602001604052806000815250611b87565b505050565b6000808290508061257761221d565b116125fd576000548110156125fc5760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036125fa575b600081036125f05760046000836001900393508381526020019081526020016000205490506125c6565b809250505061262f565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b61263c612c5f565b61265860046000848152602001908152602001600020546129ca565b9050919050565b60008054905090565b8060076000612675612957565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612722612957565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516127679190612de2565b60405180910390a35050565b61277e848484610f5d565b60008373ffffffffffffffffffffffffffffffffffffffff163b146127e0576127a984848484612a80565b6127df576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6127ee612c5f565b6127ff6127fa83612568565b6129ca565b9050919050565b6060600b8054612815906139bd565b80601f0160208091040260200160405190810160405280929190818152602001828054612841906139bd565b801561288e5780601f106128635761010080835404028352916020019161288e565b820191906000526020600020905b81548152906001019060200180831161287157829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b6001156128d357600184039350600a81066030018453600a81049050806128b1575b50828103602084039350808452505050919050565b50505050565b60008060e883901c905060e8612905868684612bd0565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600033905090565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b6129d2612c5f565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612aa6612957565b8786866040518563ffffffff1660e01b8152600401612ac89493929190613ba9565b6020604051808303816000875af1925050508015612b0457506040513d601f19601f82011682018060405250810190612b019190613c0a565b60015b612b7d573d8060008114612b34576040519150601f19603f3d011682016040523d82523d6000602084013e612b39565b606091505b506000815103612b75576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60009392505050565b828054612be5906139bd565b90600052602060002090601f016020900481019282612c075760008555612c4e565b82601f10612c2057803560ff1916838001178555612c4e565b82800160010185558215612c4e579182015b82811115612c4d578235825591602001919060010190612c32565b5b509050612c5b9190612cae565b5090565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b5b80821115612cc7576000816000905550600101612caf565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b612cf281612cdf565b8114612cfd57600080fd5b50565b600081359050612d0f81612ce9565b92915050565b600060208284031215612d2b57612d2a612cd5565b5b6000612d3984828501612d00565b91505092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612d7781612d42565b8114612d8257600080fd5b50565b600081359050612d9481612d6e565b92915050565b600060208284031215612db057612daf612cd5565b5b6000612dbe84828501612d85565b91505092915050565b60008115159050919050565b612ddc81612dc7565b82525050565b6000602082019050612df76000830184612dd3565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612e37578082015181840152602081019050612e1c565b83811115612e46576000848401525b50505050565b6000601f19601f8301169050919050565b6000612e6882612dfd565b612e728185612e08565b9350612e82818560208601612e19565b612e8b81612e4c565b840191505092915050565b60006020820190508181036000830152612eb08184612e5d565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612ee382612eb8565b9050919050565b612ef381612ed8565b82525050565b6000602082019050612f0e6000830184612eea565b92915050565b612f1d81612ed8565b8114612f2857600080fd5b50565b600081359050612f3a81612f14565b92915050565b60008060408385031215612f5757612f56612cd5565b5b6000612f6585828601612f2b565b9250506020612f7685828601612d00565b9150509250929050565b600060208284031215612f9657612f95612cd5565b5b6000612fa484828501612f2b565b91505092915050565b612fb681612cdf565b82525050565b6000602082019050612fd16000830184612fad565b92915050565b600080600060608486031215612ff057612fef612cd5565b5b6000612ffe86828701612f2b565b935050602061300f86828701612f2b565b925050604061302086828701612d00565b9150509250925092565b600080fd5b600080fd5b600080fd5b60008083601f84011261304f5761304e61302a565b5b8235905067ffffffffffffffff81111561306c5761306b61302f565b5b60208301915083600182028301111561308857613087613034565b5b9250929050565b600080602083850312156130a6576130a5612cd5565b5b600083013567ffffffffffffffff8111156130c4576130c3612cda565b5b6130d085828601613039565b92509250509250929050565b60008083601f8401126130f2576130f161302a565b5b8235905067ffffffffffffffff81111561310f5761310e61302f565b5b60208301915083602082028301111561312b5761312a613034565b5b9250929050565b6000806020838503121561314957613148612cd5565b5b600083013567ffffffffffffffff81111561316757613166612cda565b5b613173858286016130dc565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6131b481612ed8565b82525050565b600067ffffffffffffffff82169050919050565b6131d7816131ba565b82525050565b6131e681612dc7565b82525050565b600062ffffff82169050919050565b613204816131ec565b82525050565b60808201600082015161322060008501826131ab565b50602082015161323360208501826131ce565b50604082015161324660408501826131dd565b50606082015161325960608501826131fb565b50505050565b600061326b838361320a565b60808301905092915050565b6000602082019050919050565b600061328f8261317f565b613299818561318a565b93506132a48361319b565b8060005b838110156132d55781516132bc888261325f565b97506132c783613277565b9250506001810190506132a8565b5085935050505092915050565b600060208201905081810360008301526132fc8184613284565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61333981612cdf565b82525050565b600061334b8383613330565b60208301905092915050565b6000602082019050919050565b600061336f82613304565b613379818561330f565b935061338483613320565b8060005b838110156133b557815161339c888261333f565b97506133a783613357565b925050600181019050613388565b5085935050505092915050565b600060208201905081810360008301526133dc8184613364565b905092915050565b6000806000606084860312156133fd576133fc612cd5565b5b600061340b86828701612f2b565b935050602061341c86828701612d00565b925050604061342d86828701612d00565b9150509250925092565b61344081612dc7565b811461344b57600080fd5b50565b60008135905061345d81613437565b92915050565b6000806040838503121561347a57613479612cd5565b5b600061348885828601612f2b565b92505060206134998582860161344e565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6134e082612e4c565b810181811067ffffffffffffffff821117156134ff576134fe6134a8565b5b80604052505050565b6000613512612ccb565b905061351e82826134d7565b919050565b600067ffffffffffffffff82111561353e5761353d6134a8565b5b61354782612e4c565b9050602081019050919050565b82818337600083830152505050565b600061357661357184613523565b613508565b905082815260208101848484011115613592576135916134a3565b5b61359d848285613554565b509392505050565b600082601f8301126135ba576135b961302a565b5b81356135ca848260208601613563565b91505092915050565b600080600080608085870312156135ed576135ec612cd5565b5b60006135fb87828801612f2b565b945050602061360c87828801612f2b565b935050604061361d87828801612d00565b925050606085013567ffffffffffffffff81111561363e5761363d612cda565b5b61364a878288016135a5565b91505092959194509250565b60808201600082015161366c60008501826131ab565b50602082015161367f60208501826131ce565b50604082015161369260408501826131dd565b5060608201516136a560608501826131fb565b50505050565b60006080820190506136c06000830184613656565b92915050565b600080604083850312156136dd576136dc612cd5565b5b60006136eb85828601612f2b565b92505060206136fc85828601612f2b565b9150509250929050565b7f4d494e54494e4720504155534544000000000000000000000000000000000000600082015250565b600061373c600e83612e08565b915061374782613706565b602082019050919050565b6000602082019050818103600083015261376b8161372f565b9050919050565b7f4d4158205045522057414c4c4554204953203500000000000000000000000000600082015250565b60006137a8601383612e08565b91506137b382613772565b602082019050919050565b600060208201905081810360008301526137d78161379b565b9050919050565b7f4d415820535550504c5920524541434845440000000000000000000000000000600082015250565b6000613814601283612e08565b915061381f826137de565b602082019050919050565b6000602082019050818103600083015261384381613807565b9050919050565b7f494e434f52524543542045544820414d4f554e54000000000000000000000000600082015250565b6000613880601483612e08565b915061388b8261384a565b602082019050919050565b600060208201905081810360008301526138af81613873565b9050919050565b7f554e415554484f52495a45440000000000000000000000000000000000000000600082015250565b60006138ec600c83612e08565b91506138f7826138b6565b602082019050919050565b6000602082019050818103600083015261391b816138df565b9050919050565b7f52455345525645532054414b454e000000000000000000000000000000000000600082015250565b6000613958600e83612e08565b915061396382613922565b602082019050919050565b600060208201905081810360008301526139878161394b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806139d557607f821691505b6020821081036139e8576139e761398e565b5b50919050565b6000604082019050613a036000830185612eea565b613a106020830184612eea565b9392505050565b600081519050613a2681613437565b92915050565b600060208284031215613a4257613a41612cd5565b5b6000613a5084828501613a17565b91505092915050565b7f554e5355434345535346554c0000000000000000000000000000000000000000600082015250565b6000613a8f600c83612e08565b9150613a9a82613a59565b602082019050919050565b60006020820190508181036000830152613abe81613a82565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081905092915050565b6000613b0a82612dfd565b613b148185613af4565b9350613b24818560208601612e19565b80840191505092915050565b6000613b3c8285613aff565b9150613b488284613aff565b91508190509392505050565b600081519050919050565b600082825260208201905092915050565b6000613b7b82613b54565b613b858185613b5f565b9350613b95818560208601612e19565b613b9e81612e4c565b840191505092915050565b6000608082019050613bbe6000830187612eea565b613bcb6020830186612eea565b613bd86040830185612fad565b8181036060830152613bea8184613b70565b905095945050505050565b600081519050613c0481612d6e565b92915050565b600060208284031215613c2057613c1f612cd5565b5b6000613c2e84828501613bf5565b9150509291505056fea2646970667358221220364ecf356f55b0bfde7180c6ce0a6043d653237481f2c7a45da0fbf1a274149464736f6c634300080d0033
Deployed Bytecode Sourcemap
110279:4408:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;110998:1387;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;24917:689;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113217:161;;;;;;;;;;;;;:::i;:::-;;25869:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32758:268;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113754:208;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69973:148;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;21442:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;112422:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113970:216;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113386:125;;;;;;;;;;;;;:::i;:::-;;114194:224;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113014:113;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63601:560;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;110720:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;27359:202;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22626:283;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113135:74;;;;;;;;;;;;;:::i;:::-;;67575:1016;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69337:20;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;110388:45;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26045:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;112540:121;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64549:2579;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113519:227;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;114426:258;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;112669:123;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62964:478;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26255:415;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33789:214;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;110998:1387;111097:6;;;;;;;;;;;111096:7;111088:34;;;;;;;;;;;;:::i;:::-;;;;;;;;;110586:1;111195:9;111163:17;:29;111181:10;111163:29;;;;;;;;;;;;;;;;:41;:88;111137:169;;;;;;;;;;;;:::i;:::-;;;;;;;;;111323:20;111346:13;:11;:13::i;:::-;111323:36;;110533:3;111429:8;;111417:9;111402:12;:24;:35;:57;111376:137;;;;;;;;;;;;:::i;:::-;;;;;;;;;111530:19;111552:9;111530:31;;111576:23;111618:21;111642:16;:28;111659:10;111642:28;;;;;;;;;;;;;;;;111618:52;;111707:1;111691:13;:17;111687:301;;;111745:1;111733:9;:13;111729:153;;;111797:1;111785:9;:13;111771:27;;111729:153;;;111861:1;111847:15;;111729:153;111918:1;111900:19;;111971:1;111940:16;:28;111957:10;111940:28;;;;;;;;;;;;;;;:32;;;;111687:301;112035:9;112002:17;:29;112020:10;112002:29;;;;;;;;;;;;;;;;:42;;;;;;;;;;;112248:16;;112205:15;:59;110476:11;112122;:55;:142;112087:9;:178;;112061:260;;;;;;;;;;;;:::i;:::-;;;;;;;;;112338:28;112344:10;112356:9;112338:5;:28::i;:::-;111063:1315;;;;110998:1387;:::o;24917:689::-;25047:4;25391:10;25376:25;;:11;:25;;;;:102;;;;25468:10;25453:25;;:11;:25;;;;25376:102;:179;;;;25545:10;25530:25;;:11;:25;;;;25376:179;25356:199;;24917:689;;;:::o;113217:161::-;69428:5;;;;;;;;;;;69414:19;;:10;:19;;;69406:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;113293:1:::1;113282:8;;:12;113274:39;;;;;;;;;;;;:::i;:::-;;;;;;;;;113326:21;113332:10;113344:2;113326:5;:21::i;:::-;113369:1;113358:8;:12;;;;113217:161::o:0;25869:100::-;25923:13;25956:5;25949:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25869:100;:::o;32758:268::-;32879:7;32909:16;32917:7;32909;:16::i;:::-;32904:64;;32934:34;;;;;;;;;;;;;;32904:64;32988:15;:24;33004:7;32988:24;;;;;;;;;;;:30;;;;;;;;;;;;32981:37;;32758:268;;;:::o;113754:208::-;113896:8;5278:1;3109:42;5230:45;;;:49;5226:318;;;3109:42;5319;;;5392:4;5420:8;5319:128;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5296:237;;5508:8;5489:28;;;;;;;;;;;:::i;:::-;;;;;;;;5296:237;5226:318;113922:32:::1;113936:8;113946:7;113922:13;:32::i;:::-;113754:208:::0;;;:::o;69973:148::-;69428:5;;;;;;;;;;;69414:19;;:10;:19;;;69406:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;70053:8:::1;70045:5;;:16;;;;;;;;;;;;;;;;;;70104:8;70079:34;;70092:10;70079:34;;;;;;;;;;;;69973:148:::0;:::o;21442:323::-;21503:7;21731:15;:13;:15::i;:::-;21716:12;;21700:13;;:28;:46;21693:53;;21442:323;:::o;112422:110::-;69428:5;;;;;;;;;;;69414:19;;:10;:19;;;69406:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;112515:9:::1;112496:16;:28;;;;112422:110:::0;:::o;113970:216::-;114124:4;4439:1;3109:42;4391:45;;;:49;4387:632;;;4680:10;4672:18;;:4;:18;;;4668:85;;114141:37:::1;114160:4;114166:2;114170:7;114141:18;:37::i;:::-;4731:7:::0;;4668:85;3109:42;4790;;;4863:4;4891:10;4790:130;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4767:241;;4981:10;4962:30;;;;;;;;;;;:::i;:::-;;;;;;;;4767:241;4387:632;114141:37:::1;114160:4;114166:2;114170:7;114141:18;:37::i;:::-;113970:216:::0;;;;;:::o;113386:125::-;69428:5;;;;;;;;;;;69414:19;;:10;:19;;;69406:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;113452:5:::1;;;;;;;;;;;113444:19;;:42;113464:21;113444:42;;;;;;;;;;;;;;;;;;;;;;;113436:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;113386:125::o:0;114194:224::-;114352:4;4439:1;3109:42;4391:45;;;:49;4387:632;;;4680:10;4672:18;;:4;:18;;;4668:85;;114369:41:::1;114392:4;114398:2;114402:7;114369:22;:41::i;:::-;4731:7:::0;;4668:85;3109:42;4790;;;4863:4;4891:10;4790:130;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4767:241;;4981:10;4962:30;;;;;;;;;;;:::i;:::-;;;;;;;;4767:241;4387:632;114369:41:::1;114392:4;114398:2;114402:7;114369:22;:41::i;:::-;114194:224:::0;;;;;:::o;113014:113::-;69428:5;;;;;;;;;;;69414:19;;:10;:19;;;69406:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;113108:11:::1;;113093:12;:26;;;;;;;:::i;:::-;;113014:113:::0;;:::o;63601:560::-;63745:23;63811:22;63836:8;;:15;;63811:40;;63866:34;63942:14;63903:68;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;63866:105;;63991:9;63986:125;64007:14;64002:1;:19;63986:125;;64063:32;64083:8;;64092:1;64083:11;;;;;;;:::i;:::-;;;;;;;;64063:19;:32::i;:::-;64047:10;64058:1;64047:13;;;;;;;;:::i;:::-;;;;;;;:48;;;;64023:3;;;;;63986:125;;;;64132:10;64125:17;;;;63601:560;;;;:::o;110720:25::-;;;;;;;;;;;;;:::o;27359:202::-;27476:7;27524:27;27543:7;27524:18;:27::i;:::-;27501:52;;27359:202;;;:::o;22626:283::-;22743:7;22789:1;22772:19;;:5;:19;;;22768:60;;22800:28;;;;;;;;;;;;;;22768:60;16785:13;22846:18;:25;22865:5;22846:25;;;;;;;;;;;;;;;;:55;22839:62;;22626:283;;;:::o;113135:74::-;69428:5;;;;;;;;;;;69414:19;;:10;:19;;;69406:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;113195:6:::1;;;;;;;;;;;113194:7;113185:6;;:16;;;;;;;;;;;;;;;;;;113135:74::o:0;67575:1016::-;67698:16;67757:19;67791:25;67831:22;67856:16;67866:5;67856:9;:16::i;:::-;67831:41;;67887:25;67929:14;67915:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67887:57;;67959:31;;:::i;:::-;68028:9;68040:15;:13;:15::i;:::-;68028:27;;68005:538;68089:14;68074:11;:29;68005:538;;68172:15;68185:1;68172:12;:15::i;:::-;68160:27;;68210:9;:16;;;68251:8;68206:73;68327:1;68301:28;;:9;:14;;;:28;;;68297:111;;68374:9;:14;;;68354:34;;68297:111;68451:5;68430:26;;:17;:26;;;68426:102;;68507:1;68481:8;68490:13;;;;;;68481:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;68426:102;68005:538;68122:3;;;;;68005:538;;;;68564:8;68557:15;;;;;;;67575:1016;;;:::o;69337:20::-;;;;;;;;;;;;;:::o;110388:45::-;;;;:::o;26045:104::-;26101:13;26134:7;26127:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26045:104;:::o;112540:121::-;112603:7;112630:16;:23;112647:5;112630:23;;;;;;;;;;;;;;;;112623:30;;112540:121;;;:::o;64549:2579::-;64692:16;64759:4;64750:5;:13;64746:45;;64772:19;;;;;;;;;;;;;;64746:45;64806:19;64840:17;64860:14;:12;:14::i;:::-;64840:34;;64960:15;:13;:15::i;:::-;64952:5;:23;64948:87;;;65004:15;:13;:15::i;:::-;64996:23;;64948:87;65111:9;65104:4;:16;65100:73;;;65148:9;65141:16;;65100:73;65187:25;65215:16;65225:5;65215:9;:16::i;:::-;65187:44;;65409:4;65401:5;:12;65397:278;;;65434:19;65463:5;65456:4;:12;65434:34;;65505:17;65491:11;:31;65487:111;;;65567:11;65547:31;;65487:111;65415:198;65397:278;;;65658:1;65638:21;;65397:278;65689:25;65731:17;65717:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65689:60;;65789:1;65768:17;:22;65764:78;;65818:8;65811:15;;;;;;;;65764:78;65986:31;66020:26;66040:5;66020:19;:26::i;:::-;65986:60;;66061:25;66306:9;:16;;;66301:92;;66363:9;:14;;;66343:34;;66301:92;66430:9;66442:5;66430:17;;66407:544;66471:4;66466:1;:9;;:45;;;;;66494:17;66479:11;:32;;66466:45;66407:544;;;66580:15;66593:1;66580:12;:15::i;:::-;66568:27;;66618:9;:16;;;66659:8;66614:73;66735:1;66709:28;;:9;:14;;;:28;;;66705:111;;66782:9;:14;;;66762:34;;66705:111;66859:5;66838:26;;:17;:26;;;66834:102;;66915:1;66889:8;66898:13;;;;;;66889:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;66834:102;66407:544;66530:3;;;;;66407:544;;;;67053:11;67043:8;67036:29;67101:8;67094:15;;;;;;;;64549:2579;;;;;;:::o;113519:227::-;113669:8;5278:1;3109:42;5230:45;;;:49;5226:318;;;3109:42;5319;;;5392:4;5420:8;5319:128;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5296:237;;5508:8;5489:28;;;;;;;;;;;:::i;:::-;;;;;;;;5296:237;5226:318;113695:43:::1;113719:8;113729;113695:23;:43::i;:::-;113519:227:::0;;;:::o;114426:258::-;114612:4;4439:1;3109:42;4391:45;;;:49;4387:632;;;4680:10;4672:18;;:4;:18;;;4668:85;;114629:47:::1;114652:4;114658:2;114662:7;114671:4;114629:22;:47::i;:::-;4731:7:::0;;4668:85;3109:42;4790;;;4863:4;4891:10;4790:130;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4767:241;;4981:10;4962:30;;;;;;;;;;;:::i;:::-;;;;;;;;4767:241;4387:632;114629:47:::1;114652:4;114658:2;114662:7;114671:4;114629:22;:47::i;:::-;114426:258:::0;;;;;;:::o;112669:123::-;112733:7;112760:17;:24;112778:5;112760:24;;;;;;;;;;;;;;;;112753:31;;112669:123;;;:::o;62964:478::-;63093:21;;:::i;:::-;63132:31;;:::i;:::-;63188:15;:13;:15::i;:::-;63178:7;:25;:54;;;;63218:14;:12;:14::i;:::-;63207:7;:25;;63178:54;63174:103;;;63256:9;63249:16;;;;;63174:103;63299:21;63312:7;63299:12;:21::i;:::-;63287:33;;63335:9;:16;;;63331:65;;;63375:9;63368:16;;;;;63331:65;63413:21;63426:7;63413:12;:21::i;:::-;63406:28;;;62964:478;;;;:::o;26255:415::-;26373:13;26409:16;26417:7;26409;:16::i;:::-;26404:59;;26434:29;;;;;;;;;;;;;;26404:59;26476:21;26500:10;:8;:10::i;:::-;26476:34;;26566:1;26547:7;26541:21;:26;:121;;;;;;;;;;;;;;;;;26611:7;26620:18;26630:7;26620:9;:18::i;:::-;26594:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;26541:121;26521:141;;;26255:415;;;:::o;33789:214::-;33931:4;33960:18;:25;33979:5;33960:25;;;;;;;;;;;;;;;:35;33986:8;33960:35;;;;;;;;;;;;;;;;;;;;;;;;;33953:42;;33789:214;;;;:::o;44179:2775::-;44252:20;44275:13;;44252:36;;44315:1;44303:8;:13;44299:44;;44325:18;;;;;;;;;;;;;;44299:44;44356:61;44386:1;44390:2;44394:12;44408:8;44356:21;:61::i;:::-;44934:1;16923:2;44904:1;:26;;44903:32;44874:8;:62;44831:18;:22;44850:2;44831:22;;;;;;;;;;;;;;;;:105;;;;;;;;;;;45213:160;45250:2;45325:33;45348:1;45352:2;45356:1;45325:14;:33::i;:::-;45271:30;45292:8;45271:20;:30::i;:::-;:87;45213:18;:160::i;:::-;45179:17;:31;45197:12;45179:31;;;;;;;;;;;:194;;;;45390:16;45421:11;45450:8;45435:12;:23;45421:37;;45971:16;45967:2;45963:25;45951:37;;46343:12;46303:8;46262:1;46200:25;46141:1;46080;46053:335;46468:1;46454:12;46450:20;46408:346;46509:3;46500:7;46497:16;46408:346;;46727:7;46717:8;46714:1;46687:25;46684:1;46681;46676:59;46562:1;46553:7;46549:15;46538:26;;46408:346;;;46412:77;46799:1;46787:8;:13;46783:45;;46809:19;;;;;;;;;;;;;;46783:45;46861:3;46845:13;:19;;;;44605:2271;;46886:60;46915:1;46919:2;46923:12;46937:8;46886:20;:60::i;:::-;44241:2713;44179:2775;;:::o;34261:282::-;34326:4;34382:7;34363:15;:13;:15::i;:::-;:26;;:66;;;;;34416:13;;34406:7;:23;34363:66;:153;;;;;34515:1;17561:8;34467:17;:26;34485:7;34467:26;;;;;;;;;;;;:44;:49;34363:153;34343:173;;34261:282;;;:::o;32199:400::-;32280:13;32296:16;32304:7;32296;:16::i;:::-;32280:32;;32352:5;32329:28;;:19;:17;:19::i;:::-;:28;;;32325:175;;32377:44;32394:5;32401:19;:17;:19::i;:::-;32377:16;:44::i;:::-;32372:128;;32449:35;;;;;;;;;;;;;;32372:128;32325:175;32545:2;32512:15;:24;32528:7;32512:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;32583:7;32579:2;32563:28;;32572:5;32563:28;;;;;;;;;;;;32269:330;32199:400;;:::o;112800:93::-;112857:7;112884:1;112877:8;;112800:93;:::o;36529:2995::-;36663:27;36693;36712:7;36693:18;:27::i;:::-;36663:57;;36778:4;36737:45;;36753:19;36737:45;;;36733:99;;36804:28;;;;;;;;;;;;;;36733:99;36860:27;36902:23;36939:35;36966:7;36939:26;:35::i;:::-;36845:129;;;;37088:134;37131:15;37165:4;37188:19;:17;:19::i;:::-;37088:24;:134::i;:::-;37069:287;;37252:43;37269:4;37275:19;:17;:19::i;:::-;37252:16;:43::i;:::-;37247:109;;37321:35;;;;;;;;;;;;;;37247:109;37069:287;37387:1;37373:16;;:2;:16;;;37369:52;;37398:23;;;;;;;;;;;;;;37369:52;37434:43;37456:4;37462:2;37466:7;37475:1;37434:21;:43::i;:::-;37570:15;37567:160;;;37710:1;37689:19;37682:30;37567:160;38107:18;:24;38126:4;38107:24;;;;;;;;;;;;;;;;38105:26;;;;;;;;;;;;38176:18;:22;38195:2;38176:22;;;;;;;;;;;;;;;;38174:24;;;;;;;;;;;38498:167;38535:2;38605:45;38620:4;38626:2;38630:19;38605:14;:45::i;:::-;17841:8;38556:94;38498:18;:167::i;:::-;38469:17;:26;38487:7;38469:26;;;;;;;;;;;:196;;;;38836:1;17841:8;38785:19;:47;:52;38781:627;;38858:19;38890:1;38880:7;:11;38858:33;;39047:1;39013:17;:30;39031:11;39013:30;;;;;;;;;;;;:35;39009:384;;39151:13;;39136:11;:28;39132:242;;39331:19;39298:17;:30;39316:11;39298:30;;;;;;;;;;;:52;;;;39132:242;39009:384;38839:569;38781:627;39455:7;39451:2;39436:27;;39445:4;39436:27;;;;;;;;;;;;39474:42;39495:4;39501:2;39505:7;39514:1;39474:20;:42::i;:::-;36652:2872;;;36529:2995;;;:::o;39620:185::-;39758:39;39775:4;39781:2;39785:7;39758:39;;;;;;;;;;;;:16;:39::i;:::-;39620:185;;;:::o;28646:1307::-;28740:7;28765:12;28780:7;28765:22;;28848:4;28829:15;:13;:15::i;:::-;:23;28825:1061;;28882:13;;28875:4;:20;28871:1015;;;28920:14;28937:17;:23;28955:4;28937:23;;;;;;;;;;;;28920:40;;29054:1;17561:8;29026:6;:24;:29;29022:845;;29691:113;29708:1;29698:6;:11;29691:113;;29751:17;:25;29769:6;;;;;;;29751:25;;;;;;;;;;;;29742:34;;29691:113;;;29837:6;29830:13;;;;;;29022:845;28897:989;28871:1015;28825:1061;29914:31;;;;;;;;;;;;;;28646:1307;;;;:::o;28053:202::-;28157:21;;:::i;:::-;28203:44;28222:17;:24;28240:5;28222:24;;;;;;;;;;;;28203:18;:44::i;:::-;28196:51;;28053:202;;;:::o;21129:103::-;21184:7;21211:13;;21204:20;;21129:103;:::o;33366:266::-;33545:8;33493:18;:39;33512:19;:17;:19::i;:::-;33493:39;;;;;;;;;;;;;;;:49;33533:8;33493:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;33605:8;33569:55;;33584:19;:17;:19::i;:::-;33569:55;;;33615:8;33569:55;;;;;;:::i;:::-;;;;;;;;33366:266;;:::o;40403:399::-;40570:31;40583:4;40589:2;40593:7;40570:12;:31::i;:::-;40634:1;40616:2;:14;;;:19;40612:183;;40655:56;40686:4;40692:2;40696:7;40705:5;40655:30;:56::i;:::-;40650:145;;40739:40;;;;;;;;;;;;;;40650:145;40612:183;40403:399;;;;:::o;27750:207::-;27856:21;;:::i;:::-;27902:47;27921:27;27940:7;27921:18;:27::i;:::-;27902:18;:47::i;:::-;27895:54;;27750:207;;;:::o;112901:105::-;112953:13;112986:12;112979:19;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;112901:105;:::o;57415:1786::-;57516:17;57955:4;57948;57942:11;57938:22;58047:1;58041:4;58034:15;58122:4;58119:1;58115:12;58108:19;;58204:1;58199:3;58192:14;58308:3;58547:5;58529:428;58555:1;58529:428;;;58595:1;58590:3;58586:11;58579:18;;58766:2;58760:4;58756:13;58752:2;58748:22;58743:3;58735:36;58860:2;58854:4;58850:13;58842:21;;58927:4;58529:428;58917:25;58529:428;58533:21;58996:3;58991;58987:13;59111:4;59106:3;59102:14;59095:21;;59176:6;59171:3;59164:19;57560:1634;;;57415:1786;;;:::o;41464:159::-;;;;;:::o;56517:311::-;56652:7;56672:16;17965:3;56698:19;:41;;56672:68;;17965:3;56766:31;56777:4;56783:2;56787:9;56766:10;:31::i;:::-;56758:40;;:62;;56751:69;;;56517:311;;;;;:::o;31166:356::-;31263:14;31501:1;31491:8;31488:15;31462:24;31458:46;31448:56;;31166:356;;;:::o;30533:531::-;30640:14;30813:16;30806:5;30802:28;30793:37;;31025:5;31011:11;30986:23;30982:41;30979:52;30955:5;30934:112;30924:122;;30533:531;;;;:::o;42288:158::-;;;;;:::o;57208:105::-;57268:7;57295:10;57288:17;;57208:105;:::o;35424:485::-;35526:27;35555:23;35596:38;35637:15;:24;35653:7;35637:24;;;;;;;;;;;35596:65;;35814:18;35791:41;;35871:19;35865:26;35846:45;;35776:126;35424:485;;;:::o;34652:659::-;34801:11;34966:16;34959:5;34955:28;34946:37;;35126:16;35115:9;35111:32;35098:45;;35276:15;35265:9;35262:30;35254:5;35243:9;35240:20;35237:56;35227:66;;34652:659;;;;;:::o;30052:398::-;30145:31;;:::i;:::-;30227:6;30194:9;:14;;:41;;;;;;;;;;;17444:3;30280:6;:33;;30246:9;:24;;:68;;;;;;;;;;;30372:1;17561:8;30344:6;:24;:29;;30325:9;:16;;:48;;;;;;;;;;;17965:3;30413:6;:28;;30384:9;:19;;:58;;;;;;;;;;;30052:398;;;:::o;42886:831::-;43049:4;43108:2;43083:45;;;43147:19;:17;:19::i;:::-;43185:4;43208:7;43234:5;43083:171;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;43066:644;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43485:1;43468:6;:13;:18;43464:235;;43514:40;;;;;;;;;;;;;;43464:235;43657:6;43651:13;43642:6;43638:2;43634:15;43627:38;43066:644;43354:54;;;43327:81;;;:6;:81;;;;43303:105;;;42886:831;;;;;;:::o;56218:147::-;56355:6;56218:147;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::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:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:149::-;1061:7;1101:66;1094:5;1090:78;1079:89;;1025:149;;;:::o;1180:120::-;1252:23;1269:5;1252:23;:::i;:::-;1245:5;1242:34;1232:62;;1290:1;1287;1280:12;1232:62;1180:120;:::o;1306:137::-;1351:5;1389:6;1376:20;1367:29;;1405:32;1431:5;1405:32;:::i;:::-;1306:137;;;;:::o;1449:327::-;1507:6;1556:2;1544:9;1535:7;1531:23;1527:32;1524:119;;;1562:79;;:::i;:::-;1524:119;1682:1;1707:52;1751:7;1742:6;1731:9;1727:22;1707:52;:::i;:::-;1697:62;;1653:116;1449:327;;;;:::o;1782:90::-;1816:7;1859:5;1852:13;1845:21;1834:32;;1782:90;;;:::o;1878:109::-;1959:21;1974:5;1959:21;:::i;:::-;1954:3;1947:34;1878:109;;:::o;1993:210::-;2080:4;2118:2;2107:9;2103:18;2095:26;;2131:65;2193:1;2182:9;2178:17;2169:6;2131:65;:::i;:::-;1993:210;;;;:::o;2209:99::-;2261:6;2295:5;2289:12;2279:22;;2209:99;;;:::o;2314:169::-;2398:11;2432:6;2427:3;2420:19;2472:4;2467:3;2463:14;2448:29;;2314:169;;;;:::o;2489:307::-;2557:1;2567:113;2581:6;2578:1;2575:13;2567:113;;;2666:1;2661:3;2657:11;2651:18;2647:1;2642:3;2638:11;2631:39;2603:2;2600:1;2596:10;2591:15;;2567:113;;;2698:6;2695:1;2692:13;2689:101;;;2778:1;2769:6;2764:3;2760:16;2753:27;2689:101;2538:258;2489:307;;;:::o;2802:102::-;2843:6;2894:2;2890:7;2885:2;2878:5;2874:14;2870:28;2860:38;;2802:102;;;:::o;2910:364::-;2998:3;3026:39;3059:5;3026:39;:::i;:::-;3081:71;3145:6;3140:3;3081:71;:::i;:::-;3074:78;;3161:52;3206:6;3201:3;3194:4;3187:5;3183:16;3161:52;:::i;:::-;3238:29;3260:6;3238:29;:::i;:::-;3233:3;3229:39;3222:46;;3002:272;2910:364;;;;:::o;3280:313::-;3393:4;3431:2;3420:9;3416:18;3408:26;;3480:9;3474:4;3470:20;3466:1;3455:9;3451:17;3444:47;3508:78;3581:4;3572:6;3508:78;:::i;:::-;3500:86;;3280:313;;;;:::o;3599:126::-;3636:7;3676:42;3669:5;3665:54;3654:65;;3599:126;;;:::o;3731:96::-;3768:7;3797:24;3815:5;3797:24;:::i;:::-;3786:35;;3731:96;;;:::o;3833:118::-;3920:24;3938:5;3920:24;:::i;:::-;3915:3;3908:37;3833:118;;:::o;3957:222::-;4050:4;4088:2;4077:9;4073:18;4065:26;;4101:71;4169:1;4158:9;4154:17;4145:6;4101:71;:::i;:::-;3957:222;;;;:::o;4185:122::-;4258:24;4276:5;4258:24;:::i;:::-;4251:5;4248:35;4238:63;;4297:1;4294;4287:12;4238:63;4185:122;:::o;4313:139::-;4359:5;4397:6;4384:20;4375:29;;4413:33;4440:5;4413:33;:::i;:::-;4313:139;;;;:::o;4458:474::-;4526:6;4534;4583:2;4571:9;4562:7;4558:23;4554:32;4551:119;;;4589:79;;:::i;:::-;4551:119;4709:1;4734:53;4779:7;4770:6;4759:9;4755:22;4734:53;:::i;:::-;4724:63;;4680:117;4836:2;4862:53;4907:7;4898:6;4887:9;4883:22;4862:53;:::i;:::-;4852:63;;4807:118;4458:474;;;;;:::o;4938:329::-;4997:6;5046:2;5034:9;5025:7;5021:23;5017:32;5014:119;;;5052:79;;:::i;:::-;5014:119;5172:1;5197:53;5242:7;5233:6;5222:9;5218:22;5197:53;:::i;:::-;5187:63;;5143:117;4938:329;;;;:::o;5273:118::-;5360:24;5378:5;5360:24;:::i;:::-;5355:3;5348:37;5273:118;;:::o;5397:222::-;5490:4;5528:2;5517:9;5513:18;5505:26;;5541:71;5609:1;5598:9;5594:17;5585:6;5541:71;:::i;:::-;5397:222;;;;:::o;5625:619::-;5702:6;5710;5718;5767:2;5755:9;5746:7;5742:23;5738:32;5735:119;;;5773:79;;:::i;:::-;5735:119;5893:1;5918:53;5963:7;5954:6;5943:9;5939:22;5918:53;:::i;:::-;5908:63;;5864:117;6020:2;6046:53;6091:7;6082:6;6071:9;6067:22;6046:53;:::i;:::-;6036:63;;5991:118;6148:2;6174:53;6219:7;6210:6;6199:9;6195:22;6174:53;:::i;:::-;6164:63;;6119:118;5625:619;;;;;:::o;6250:117::-;6359:1;6356;6349:12;6373:117;6482:1;6479;6472:12;6496:117;6605:1;6602;6595:12;6633:553;6691:8;6701:6;6751:3;6744:4;6736:6;6732:17;6728:27;6718:122;;6759:79;;:::i;:::-;6718:122;6872:6;6859:20;6849:30;;6902:18;6894:6;6891:30;6888:117;;;6924:79;;:::i;:::-;6888:117;7038:4;7030:6;7026:17;7014:29;;7092:3;7084:4;7076:6;7072:17;7062:8;7058:32;7055:41;7052:128;;;7099:79;;:::i;:::-;7052:128;6633:553;;;;;:::o;7192:529::-;7263:6;7271;7320:2;7308:9;7299:7;7295:23;7291:32;7288:119;;;7326:79;;:::i;:::-;7288:119;7474:1;7463:9;7459:17;7446:31;7504:18;7496:6;7493:30;7490:117;;;7526:79;;:::i;:::-;7490:117;7639:65;7696:7;7687:6;7676:9;7672:22;7639:65;:::i;:::-;7621:83;;;;7417:297;7192:529;;;;;:::o;7744:568::-;7817:8;7827:6;7877:3;7870:4;7862:6;7858:17;7854:27;7844:122;;7885:79;;:::i;:::-;7844:122;7998:6;7985:20;7975:30;;8028:18;8020:6;8017:30;8014:117;;;8050:79;;:::i;:::-;8014:117;8164:4;8156:6;8152:17;8140:29;;8218:3;8210:4;8202:6;8198:17;8188:8;8184:32;8181:41;8178:128;;;8225:79;;:::i;:::-;8178:128;7744:568;;;;;:::o;8318:559::-;8404:6;8412;8461:2;8449:9;8440:7;8436:23;8432:32;8429:119;;;8467:79;;:::i;:::-;8429:119;8615:1;8604:9;8600:17;8587:31;8645:18;8637:6;8634:30;8631:117;;;8667:79;;:::i;:::-;8631:117;8780:80;8852:7;8843:6;8832:9;8828:22;8780:80;:::i;:::-;8762:98;;;;8558:312;8318:559;;;;;:::o;8883:145::-;8981:6;9015:5;9009:12;8999:22;;8883:145;;;:::o;9034:215::-;9164:11;9198:6;9193:3;9186:19;9238:4;9233:3;9229:14;9214:29;;9034:215;;;;:::o;9255:163::-;9353:4;9376:3;9368:11;;9406:4;9401:3;9397:14;9389:22;;9255:163;;;:::o;9424:108::-;9501:24;9519:5;9501:24;:::i;:::-;9496:3;9489:37;9424:108;;:::o;9538:101::-;9574:7;9614:18;9607:5;9603:30;9592:41;;9538:101;;;:::o;9645:105::-;9720:23;9737:5;9720:23;:::i;:::-;9715:3;9708:36;9645:105;;:::o;9756:99::-;9827:21;9842:5;9827:21;:::i;:::-;9822:3;9815:34;9756:99;;:::o;9861:91::-;9897:7;9937:8;9930:5;9926:20;9915:31;;9861:91;;;:::o;9958:105::-;10033:23;10050:5;10033:23;:::i;:::-;10028:3;10021:36;9958:105;;:::o;10141:864::-;10290:4;10285:3;10281:14;10377:4;10370:5;10366:16;10360:23;10396:63;10453:4;10448:3;10444:14;10430:12;10396:63;:::i;:::-;10305:164;10561:4;10554:5;10550:16;10544:23;10580:61;10635:4;10630:3;10626:14;10612:12;10580:61;:::i;:::-;10479:172;10735:4;10728:5;10724:16;10718:23;10754:57;10805:4;10800:3;10796:14;10782:12;10754:57;:::i;:::-;10661:160;10908:4;10901:5;10897:16;10891:23;10927:61;10982:4;10977:3;10973:14;10959:12;10927:61;:::i;:::-;10831:167;10259:746;10141:864;;:::o;11011:303::-;11142:10;11163:108;11267:3;11259:6;11163:108;:::i;:::-;11303:4;11298:3;11294:14;11280:28;;11011:303;;;;:::o;11320:144::-;11421:4;11453;11448:3;11444:14;11436:22;;11320:144;;;:::o;11546:980::-;11727:3;11756:85;11835:5;11756:85;:::i;:::-;11857:117;11967:6;11962:3;11857:117;:::i;:::-;11850:124;;11998:87;12079:5;11998:87;:::i;:::-;12108:7;12139:1;12124:377;12149:6;12146:1;12143:13;12124:377;;;12225:6;12219:13;12252:125;12373:3;12358:13;12252:125;:::i;:::-;12245:132;;12400:91;12484:6;12400:91;:::i;:::-;12390:101;;12184:317;12171:1;12168;12164:9;12159:14;;12124:377;;;12128:14;12517:3;12510:10;;11732:794;;;11546:980;;;;:::o;12532:497::-;12737:4;12775:2;12764:9;12760:18;12752:26;;12824:9;12818:4;12814:20;12810:1;12799:9;12795:17;12788:47;12852:170;13017:4;13008:6;12852:170;:::i;:::-;12844:178;;12532:497;;;;:::o;13035:114::-;13102:6;13136:5;13130:12;13120:22;;13035:114;;;:::o;13155:184::-;13254:11;13288:6;13283:3;13276:19;13328:4;13323:3;13319:14;13304:29;;13155:184;;;;:::o;13345:132::-;13412:4;13435:3;13427:11;;13465:4;13460:3;13456:14;13448:22;;13345:132;;;:::o;13483:108::-;13560:24;13578:5;13560:24;:::i;:::-;13555:3;13548:37;13483:108;;:::o;13597:179::-;13666:10;13687:46;13729:3;13721:6;13687:46;:::i;:::-;13765:4;13760:3;13756:14;13742:28;;13597:179;;;;:::o;13782:113::-;13852:4;13884;13879:3;13875:14;13867:22;;13782:113;;;:::o;13931:732::-;14050:3;14079:54;14127:5;14079:54;:::i;:::-;14149:86;14228:6;14223:3;14149:86;:::i;:::-;14142:93;;14259:56;14309:5;14259:56;:::i;:::-;14338:7;14369:1;14354:284;14379:6;14376:1;14373:13;14354:284;;;14455:6;14449:13;14482:63;14541:3;14526:13;14482:63;:::i;:::-;14475:70;;14568:60;14621:6;14568:60;:::i;:::-;14558:70;;14414:224;14401:1;14398;14394:9;14389:14;;14354:284;;;14358:14;14654:3;14647:10;;14055:608;;;13931:732;;;;:::o;14669:373::-;14812:4;14850:2;14839:9;14835:18;14827:26;;14899:9;14893:4;14889:20;14885:1;14874:9;14870:17;14863:47;14927:108;15030:4;15021:6;14927:108;:::i;:::-;14919:116;;14669:373;;;;:::o;15048:619::-;15125:6;15133;15141;15190:2;15178:9;15169:7;15165:23;15161:32;15158:119;;;15196:79;;:::i;:::-;15158:119;15316:1;15341:53;15386:7;15377:6;15366:9;15362:22;15341:53;:::i;:::-;15331:63;;15287:117;15443:2;15469:53;15514:7;15505:6;15494:9;15490:22;15469:53;:::i;:::-;15459:63;;15414:118;15571:2;15597:53;15642:7;15633:6;15622:9;15618:22;15597:53;:::i;:::-;15587:63;;15542:118;15048:619;;;;;:::o;15673:116::-;15743:21;15758:5;15743:21;:::i;:::-;15736:5;15733:32;15723:60;;15779:1;15776;15769:12;15723:60;15673:116;:::o;15795:133::-;15838:5;15876:6;15863:20;15854:29;;15892:30;15916:5;15892:30;:::i;:::-;15795:133;;;;:::o;15934:468::-;15999:6;16007;16056:2;16044:9;16035:7;16031:23;16027:32;16024:119;;;16062:79;;:::i;:::-;16024:119;16182:1;16207:53;16252:7;16243:6;16232:9;16228:22;16207:53;:::i;:::-;16197:63;;16153:117;16309:2;16335:50;16377:7;16368:6;16357:9;16353:22;16335:50;:::i;:::-;16325:60;;16280:115;15934:468;;;;;:::o;16408:117::-;16517:1;16514;16507:12;16531:180;16579:77;16576:1;16569:88;16676:4;16673:1;16666:15;16700:4;16697:1;16690:15;16717:281;16800:27;16822:4;16800:27;:::i;:::-;16792:6;16788:40;16930:6;16918:10;16915:22;16894:18;16882:10;16879:34;16876:62;16873:88;;;16941:18;;:::i;:::-;16873:88;16981:10;16977:2;16970:22;16760:238;16717:281;;:::o;17004:129::-;17038:6;17065:20;;:::i;:::-;17055:30;;17094:33;17122:4;17114:6;17094:33;:::i;:::-;17004:129;;;:::o;17139:307::-;17200:4;17290:18;17282:6;17279:30;17276:56;;;17312:18;;:::i;:::-;17276:56;17350:29;17372:6;17350:29;:::i;:::-;17342:37;;17434:4;17428;17424:15;17416:23;;17139:307;;;:::o;17452:154::-;17536:6;17531:3;17526;17513:30;17598:1;17589:6;17584:3;17580:16;17573:27;17452:154;;;:::o;17612:410::-;17689:5;17714:65;17730:48;17771:6;17730:48;:::i;:::-;17714:65;:::i;:::-;17705:74;;17802:6;17795:5;17788:21;17840:4;17833:5;17829:16;17878:3;17869:6;17864:3;17860:16;17857:25;17854:112;;;17885:79;;:::i;:::-;17854:112;17975:41;18009:6;18004:3;17999;17975:41;:::i;:::-;17695:327;17612:410;;;;;:::o;18041:338::-;18096:5;18145:3;18138:4;18130:6;18126:17;18122:27;18112:122;;18153:79;;:::i;:::-;18112:122;18270:6;18257:20;18295:78;18369:3;18361:6;18354:4;18346:6;18342:17;18295:78;:::i;:::-;18286:87;;18102:277;18041:338;;;;:::o;18385:943::-;18480:6;18488;18496;18504;18553:3;18541:9;18532:7;18528:23;18524:33;18521:120;;;18560:79;;:::i;:::-;18521:120;18680:1;18705:53;18750:7;18741:6;18730:9;18726:22;18705:53;:::i;:::-;18695:63;;18651:117;18807:2;18833:53;18878:7;18869:6;18858:9;18854:22;18833:53;:::i;:::-;18823:63;;18778:118;18935:2;18961:53;19006:7;18997:6;18986:9;18982:22;18961:53;:::i;:::-;18951:63;;18906:118;19091:2;19080:9;19076:18;19063:32;19122:18;19114:6;19111:30;19108:117;;;19144:79;;:::i;:::-;19108:117;19249:62;19303:7;19294:6;19283:9;19279:22;19249:62;:::i;:::-;19239:72;;19034:287;18385:943;;;;;;;:::o;19406:874::-;19565:4;19560:3;19556:14;19652:4;19645:5;19641:16;19635:23;19671:63;19728:4;19723:3;19719:14;19705:12;19671:63;:::i;:::-;19580:164;19836:4;19829:5;19825:16;19819:23;19855:61;19910:4;19905:3;19901:14;19887:12;19855:61;:::i;:::-;19754:172;20010:4;20003:5;19999:16;19993:23;20029:57;20080:4;20075:3;20071:14;20057:12;20029:57;:::i;:::-;19936:160;20183:4;20176:5;20172:16;20166:23;20202:61;20257:4;20252:3;20248:14;20234:12;20202:61;:::i;:::-;20106:167;19534:746;19406:874;;:::o;20286:347::-;20441:4;20479:3;20468:9;20464:19;20456:27;;20493:133;20623:1;20612:9;20608:17;20599:6;20493:133;:::i;:::-;20286:347;;;;:::o;20639:474::-;20707:6;20715;20764:2;20752:9;20743:7;20739:23;20735:32;20732:119;;;20770:79;;:::i;:::-;20732:119;20890:1;20915:53;20960:7;20951:6;20940:9;20936:22;20915:53;:::i;:::-;20905:63;;20861:117;21017:2;21043:53;21088:7;21079:6;21068:9;21064:22;21043:53;:::i;:::-;21033:63;;20988:118;20639:474;;;;;:::o;21119:164::-;21259:16;21255:1;21247:6;21243:14;21236:40;21119:164;:::o;21289:366::-;21431:3;21452:67;21516:2;21511:3;21452:67;:::i;:::-;21445:74;;21528:93;21617:3;21528:93;:::i;:::-;21646:2;21641:3;21637:12;21630:19;;21289:366;;;:::o;21661:419::-;21827:4;21865:2;21854:9;21850:18;21842:26;;21914:9;21908:4;21904:20;21900:1;21889:9;21885:17;21878:47;21942:131;22068:4;21942:131;:::i;:::-;21934:139;;21661:419;;;:::o;22086:169::-;22226:21;22222:1;22214:6;22210:14;22203:45;22086:169;:::o;22261:366::-;22403:3;22424:67;22488:2;22483:3;22424:67;:::i;:::-;22417:74;;22500:93;22589:3;22500:93;:::i;:::-;22618:2;22613:3;22609:12;22602:19;;22261:366;;;:::o;22633:419::-;22799:4;22837:2;22826:9;22822:18;22814:26;;22886:9;22880:4;22876:20;22872:1;22861:9;22857:17;22850:47;22914:131;23040:4;22914:131;:::i;:::-;22906:139;;22633:419;;;:::o;23058:168::-;23198:20;23194:1;23186:6;23182:14;23175:44;23058:168;:::o;23232:366::-;23374:3;23395:67;23459:2;23454:3;23395:67;:::i;:::-;23388:74;;23471:93;23560:3;23471:93;:::i;:::-;23589:2;23584:3;23580:12;23573:19;;23232:366;;;:::o;23604:419::-;23770:4;23808:2;23797:9;23793:18;23785:26;;23857:9;23851:4;23847:20;23843:1;23832:9;23828:17;23821:47;23885:131;24011:4;23885:131;:::i;:::-;23877:139;;23604:419;;;:::o;24029:170::-;24169:22;24165:1;24157:6;24153:14;24146:46;24029:170;:::o;24205:366::-;24347:3;24368:67;24432:2;24427:3;24368:67;:::i;:::-;24361:74;;24444:93;24533:3;24444:93;:::i;:::-;24562:2;24557:3;24553:12;24546:19;;24205:366;;;:::o;24577:419::-;24743:4;24781:2;24770:9;24766:18;24758:26;;24830:9;24824:4;24820:20;24816:1;24805:9;24801:17;24794:47;24858:131;24984:4;24858:131;:::i;:::-;24850:139;;24577:419;;;:::o;25002:162::-;25142:14;25138:1;25130:6;25126:14;25119:38;25002:162;:::o;25170:366::-;25312:3;25333:67;25397:2;25392:3;25333:67;:::i;:::-;25326:74;;25409:93;25498:3;25409:93;:::i;:::-;25527:2;25522:3;25518:12;25511:19;;25170:366;;;:::o;25542:419::-;25708:4;25746:2;25735:9;25731:18;25723:26;;25795:9;25789:4;25785:20;25781:1;25770:9;25766:17;25759:47;25823:131;25949:4;25823:131;:::i;:::-;25815:139;;25542:419;;;:::o;25967:164::-;26107:16;26103:1;26095:6;26091:14;26084:40;25967:164;:::o;26137:366::-;26279:3;26300:67;26364:2;26359:3;26300:67;:::i;:::-;26293:74;;26376:93;26465:3;26376:93;:::i;:::-;26494:2;26489:3;26485:12;26478:19;;26137:366;;;:::o;26509:419::-;26675:4;26713:2;26702:9;26698:18;26690:26;;26762:9;26756:4;26752:20;26748:1;26737:9;26733:17;26726:47;26790:131;26916:4;26790:131;:::i;:::-;26782:139;;26509:419;;;:::o;26934:180::-;26982:77;26979:1;26972:88;27079:4;27076:1;27069:15;27103:4;27100:1;27093:15;27120:320;27164:6;27201:1;27195:4;27191:12;27181:22;;27248:1;27242:4;27238:12;27269:18;27259:81;;27325:4;27317:6;27313:17;27303:27;;27259:81;27387:2;27379:6;27376:14;27356:18;27353:38;27350:84;;27406:18;;:::i;:::-;27350:84;27171:269;27120:320;;;:::o;27446:332::-;27567:4;27605:2;27594:9;27590:18;27582:26;;27618:71;27686:1;27675:9;27671:17;27662:6;27618:71;:::i;:::-;27699:72;27767:2;27756:9;27752:18;27743:6;27699:72;:::i;:::-;27446:332;;;;;:::o;27784:137::-;27838:5;27869:6;27863:13;27854:22;;27885:30;27909:5;27885:30;:::i;:::-;27784:137;;;;:::o;27927:345::-;27994:6;28043:2;28031:9;28022:7;28018:23;28014:32;28011:119;;;28049:79;;:::i;:::-;28011:119;28169:1;28194:61;28247:7;28238:6;28227:9;28223:22;28194:61;:::i;:::-;28184:71;;28140:125;27927:345;;;;:::o;28278:162::-;28418:14;28414:1;28406:6;28402:14;28395:38;28278:162;:::o;28446:366::-;28588:3;28609:67;28673:2;28668:3;28609:67;:::i;:::-;28602:74;;28685:93;28774:3;28685:93;:::i;:::-;28803:2;28798:3;28794:12;28787:19;;28446:366;;;:::o;28818:419::-;28984:4;29022:2;29011:9;29007:18;28999:26;;29071:9;29065:4;29061:20;29057:1;29046:9;29042:17;29035:47;29099:131;29225:4;29099:131;:::i;:::-;29091:139;;28818:419;;;:::o;29243:180::-;29291:77;29288:1;29281:88;29388:4;29385:1;29378:15;29412:4;29409:1;29402:15;29429:148;29531:11;29568:3;29553:18;;29429:148;;;;:::o;29583:377::-;29689:3;29717:39;29750:5;29717:39;:::i;:::-;29772:89;29854:6;29849:3;29772:89;:::i;:::-;29765:96;;29870:52;29915:6;29910:3;29903:4;29896:5;29892:16;29870:52;:::i;:::-;29947:6;29942:3;29938:16;29931:23;;29693:267;29583:377;;;;:::o;29966:435::-;30146:3;30168:95;30259:3;30250:6;30168:95;:::i;:::-;30161:102;;30280:95;30371:3;30362:6;30280:95;:::i;:::-;30273:102;;30392:3;30385:10;;29966:435;;;;;:::o;30407:98::-;30458:6;30492:5;30486:12;30476:22;;30407:98;;;:::o;30511:168::-;30594:11;30628:6;30623:3;30616:19;30668:4;30663:3;30659:14;30644:29;;30511:168;;;;:::o;30685:360::-;30771:3;30799:38;30831:5;30799:38;:::i;:::-;30853:70;30916:6;30911:3;30853:70;:::i;:::-;30846:77;;30932:52;30977:6;30972:3;30965:4;30958:5;30954:16;30932:52;:::i;:::-;31009:29;31031:6;31009:29;:::i;:::-;31004:3;31000:39;30993:46;;30775:270;30685:360;;;;:::o;31051:640::-;31246:4;31284:3;31273:9;31269:19;31261:27;;31298:71;31366:1;31355:9;31351:17;31342:6;31298:71;:::i;:::-;31379:72;31447:2;31436:9;31432:18;31423:6;31379:72;:::i;:::-;31461;31529:2;31518:9;31514:18;31505:6;31461:72;:::i;:::-;31580:9;31574:4;31570:20;31565:2;31554:9;31550:18;31543:48;31608:76;31679:4;31670:6;31608:76;:::i;:::-;31600:84;;31051:640;;;;;;;:::o;31697:141::-;31753:5;31784:6;31778:13;31769:22;;31800:32;31826:5;31800:32;:::i;:::-;31697:141;;;;:::o;31844:349::-;31913:6;31962:2;31950:9;31941:7;31937:23;31933:32;31930:119;;;31968:79;;:::i;:::-;31930:119;32088:1;32113:63;32168:7;32159:6;32148:9;32144:22;32113:63;:::i;:::-;32103:73;;32059:127;31844:349;;;;:::o
Swarm Source
ipfs://364ecf356f55b0bfde7180c6ce0a6043d653237481f2c7a45da0fbf1a2741494
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.