Feature Tip: Add private address tag to any address under My Name Tag !
Overview
TokenID
3784
Total Transfers
-
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 0 Decimals)
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
PinkBox
Compiler Version
v0.8.7+commit.e28d00a7
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-05-28 */ // SPDX-License-Identifier: MIT // File: contracts/CatBox/IOperatorFilterRegistry.sol pragma solidity ^0.8.0; 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: contracts/CatBox/OperatorFilterer.sol pragma solidity ^0.8.0; /** * @title OperatorFilterer * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another * registrant's entries in the OperatorFilterRegistry. * @dev This smart contract is meant to be inherited by token contracts so they can use the following: * - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods. * - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods. */ abstract contract OperatorFilterer { error OperatorNotAllowed(address operator); IOperatorFilterRegistry public 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 { // 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) { _checkFilterOperator(msg.sender); } _; } modifier onlyAllowedOperatorApproval(address operator) virtual { _checkFilterOperator(operator); _; } function _checkFilterOperator(address operator) internal view 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: contracts/CatBox/DefaultOperatorFilterer.sol pragma solidity ^0.8.0; /** * @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: erc721a/contracts/IERC721A.sol // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); } // File: erc721a/contracts/ERC721A.sol // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr) if (curr < _currentIndex) { uint256 packed = _packedOwnerships[curr]; // If not burned. if (packed & _BITMASK_BURNED == 0) { // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `curr` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) public payable virtual override { address owner = ownerOf(tokenId); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned. } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 toMasked; uint256 end = startTokenId + quantity; // Use assembly to loop and emit the `Transfer` event for gas savings. // The duplicated `log4` removes an extra check and reduces stack juggling. // The assembly, together with the surrounding Solidity code, have been // delicately arranged to nudge the compiler into producing optimized opcodes. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. startTokenId // `tokenId`. ) // The `iszero(eq(,))` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. // The compiler will optimize the `iszero` away for performance. for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } if (toMasked == 0) revert MintToZeroAddress(); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } } // File: @openzeppelin/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: @openzeppelin/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: @openzeppelin/contracts/interfaces/IERC2981.sol // OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.0; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. * * _Available since v4.5._ */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address receiver, uint256 royaltyAmount); } // File: @openzeppelin/contracts/token/common/ERC2981.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the * fee is specified in basis points by default. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. * * _Available since v4.5._ */ abstract contract ERC2981 is IERC2981, ERC165 { struct RoyaltyInfo { address receiver; uint96 royaltyFraction; } RoyaltyInfo private _defaultRoyaltyInfo; mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } /** * @inheritdoc IERC2981 */ function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) { RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId]; if (royalty.receiver == address(0)) { royalty = _defaultRoyaltyInfo; } uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator(); return (royalty.receiver, royaltyAmount); } /** * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an * override. */ function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /** * @dev Sets the royalty information that all ids in this contract will default to. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); require(receiver != address(0), "ERC2981: invalid receiver"); _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Removes default royalty information. */ function _deleteDefaultRoyalty() internal virtual { delete _defaultRoyaltyInfo; } /** * @dev Sets the royalty information for a specific token id, overriding the global default. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setTokenRoyalty( uint256 tokenId, address receiver, uint96 feeNumerator ) internal virtual { require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); require(receiver != address(0), "ERC2981: Invalid parameters"); _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Resets royalty information for the token id back to the global default. */ function _resetTokenRoyalty(uint256 tokenId) internal virtual { delete _tokenRoyaltyInfo[tokenId]; } } // File: @openzeppelin/contracts/utils/math/SafeMath.sol // OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @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); } } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: contracts/CatBox/PinkBox.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; contract PinkBox is ERC721A, ERC2981, Ownable, DefaultOperatorFilterer { using SafeMath for uint256; uint256 public constant MAX_SUPPLY = 100000; uint256 public constant FREE_SUPPLY = 3; uint256 public constant PAID_SUPPLY = 10; uint256 private _flag; string private _defTokenURI = "https://ipfs.io/ipfs/QmZ4mfVaEm8S6v7ACQXFgTmob6ntratgajx8cjPFGZxT1n"; string private _baseTokenURI = ""; mapping(address => bool) private _hasMinted; event NewMint(address indexed msgSender, uint256 indexed mintQuantity); constructor() ERC721A("PinkBox", "PBX") { _setDefaultRoyalty(msg.sender, 0); } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721A, ERC2981) returns (bool) { return super.supportsInterface(interfaceId); } function _startTokenId() internal view override virtual returns (uint256) { return 1; } function transferOut(address _to) public onlyOwner { uint256 balance = address(this).balance; payable(_to).transfer(balance); } function changeTokenURIFlag(uint256 flag) external onlyOwner { _flag = flag; } function changeDefURI(string calldata _tokenURI) external onlyOwner { _defTokenURI = _tokenURI; } function changeURI(string calldata _tokenURI) external onlyOwner { _baseTokenURI = _tokenURI; } function _baseURI() internal view virtual override returns (string memory) { return _baseTokenURI; } function tokenURI(uint256 tokenId) public view override returns (string memory) { if (_flag == 0) { return _defTokenURI; } else { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); return string(abi.encodePacked(_baseTokenURI, Strings.toString(tokenId))); } } function mint(uint256 quantity) public payable { require(totalSupply() + quantity <= MAX_SUPPLY, "ERC721: Exceeds maximum supply"); require(quantity == 1 || quantity == FREE_SUPPLY || quantity == PAID_SUPPLY, "ERC721: Invalid quantity"); if (quantity <= FREE_SUPPLY ) { _safeMint(msg.sender,quantity); } else { require(msg.value >= 0.0001 ether, "ERC721: Insufficient payment"); _safeMint(msg.sender,quantity); } emit NewMint(msg.sender, quantity); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"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":"msgSender","type":"address"},{"indexed":true,"internalType":"uint256","name":"mintQuantity","type":"uint256"}],"name":"NewMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"FREE_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAID_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_tokenURI","type":"string"}],"name":"changeDefURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"flag","type":"uint256"}],"name":"changeTokenURIFlag","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_tokenURI","type":"string"}],"name":"changeURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"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","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":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"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":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"transferOut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526040518060800160405280604381526020016200392860439139600c908051906020019062000035929190620005ee565b5060405180602001604052806000815250600d90805190602001906200005d929190620005ee565b503480156200006b57600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600781526020017f50696e6b426f78000000000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f5042580000000000000000000000000000000000000000000000000000000000815250816002908051906020019062000107929190620005ee565b50806003908051906020019062000120929190620005ee565b50620001316200036960201b60201c565b6000819055505050620001596200014d6200037260201b60201c565b6200037a60201b60201c565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156200034e57801562000214576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b8152600401620001da9291906200071a565b600060405180830381600087803b158015620001f557600080fd5b505af11580156200020a573d6000803e3d6000fd5b505050506200034d565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620002ce576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b8152600401620002949291906200071a565b600060405180830381600087803b158015620002af57600080fd5b505af1158015620002c4573d6000803e3d6000fd5b505050506200034c565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b8152600401620003179190620006fd565b600060405180830381600087803b1580156200033257600080fd5b505af115801562000347573d6000803e3d6000fd5b505050505b5b5b5050620003633360006200044060201b60201c565b620008ad565b60006001905090565b600033905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b62000450620005e460201b60201c565b6bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115620004b1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004a89062000747565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141562000524576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200051b9062000769565b60405180910390fd5b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff16815250600860008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055509050505050565b6000612710905090565b828054620005fc90620007d0565b90600052602060002090601f0160209004810192826200062057600085556200066c565b82601f106200063b57805160ff19168380011785556200066c565b828001600101855582156200066c579182015b828111156200066b5782518255916020019190600101906200064e565b5b5090506200067b91906200067f565b5090565b5b808211156200069a57600081600090555060010162000680565b5090565b620006a9816200079c565b82525050565b6000620006be602a836200078b565b9150620006cb8262000835565b604082019050919050565b6000620006e56019836200078b565b9150620006f28262000884565b602082019050919050565b60006020820190506200071460008301846200069e565b92915050565b60006040820190506200073160008301856200069e565b6200074060208301846200069e565b9392505050565b600060208201905081810360008301526200076281620006af565b9050919050565b600060208201905081810360008301526200078481620006d6565b9050919050565b600082825260208201905092915050565b6000620007a982620007b0565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006002820490506001821680620007e957607f821691505b602082108114156200080057620007ff62000806565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f455243323938313a20726f79616c7479206665652077696c6c2065786365656460008201527f2073616c65507269636500000000000000000000000000000000000000000000602082015250565b7f455243323938313a20696e76616c696420726563656976657200000000000000600082015250565b61306b80620008bd6000396000f3fe60806040526004361061019c5760003560e01c806370a08231116100ec578063a22cb4651161008a578063e5e01c1111610064578063e5e01c1114610584578063e985e9c5146105ad578063f2fde38b146105ea578063fe878b1d146106135761019c565b8063a22cb46514610502578063b88d4fde1461052b578063c87b56dd146105475761019c565b806395d89b41116100c657806395d89b41146104675780639858cf19146104925780639894ba7c146104bd578063a0712d68146104e65761019c565b806370a08231146103e8578063715018a6146104255780638da5cb5b1461043c5761019c565b806323b872dd1161015957806341f434341161013357806341f434341461033b57806342842e0e14610366578063528c06cc146103825780636352211e146103ab5761019c565b806323b872dd146102b65780632a55205a146102d257806332cb6b0c146103105761019c565b806301ffc9a7146101a157806306fdde03146101de578063081812fc14610209578063095ea7b3146102465780630e5c19191461026257806318160ddd1461028b575b600080fd5b3480156101ad57600080fd5b506101c860048036038101906101c391906124c6565b61063e565b6040516101d591906128be565b60405180910390f35b3480156101ea57600080fd5b506101f3610650565b60405161020091906128f4565b60405180910390f35b34801561021557600080fd5b50610230600480360381019061022b919061256d565b6106e2565b60405161023d919061282e565b60405180910390f35b610260600480360381019061025b9190612486565b610761565b005b34801561026e57600080fd5b5061028960048036038101906102849190612520565b6108a5565b005b34801561029757600080fd5b506102a0610937565b6040516102ad91906129d6565b60405180910390f35b6102d060048036038101906102cb9190612370565b61094e565b005b3480156102de57600080fd5b506102f960048036038101906102f4919061259a565b610c73565b604051610307929190612895565b60405180910390f35b34801561031c57600080fd5b50610325610e5e565b60405161033291906129d6565b60405180910390f35b34801561034757600080fd5b50610350610e65565b60405161035d91906128d9565b60405180910390f35b610380600480360381019061037b9190612370565b610e77565b005b34801561038e57600080fd5b506103a960048036038101906103a4919061256d565b610e97565b005b3480156103b757600080fd5b506103d260048036038101906103cd919061256d565b610f1d565b6040516103df919061282e565b60405180910390f35b3480156103f457600080fd5b5061040f600480360381019061040a9190612303565b610f2f565b60405161041c91906129d6565b60405180910390f35b34801561043157600080fd5b5061043a610fe8565b005b34801561044857600080fd5b50610451611070565b60405161045e919061282e565b60405180910390f35b34801561047357600080fd5b5061047c61109a565b60405161048991906128f4565b60405180910390f35b34801561049e57600080fd5b506104a761112c565b6040516104b491906129d6565b60405180910390f35b3480156104c957600080fd5b506104e460048036038101906104df9190612303565b611131565b005b61050060048036038101906104fb919061256d565b6111fd565b005b34801561050e57600080fd5b5061052960048036038101906105249190612446565b611360565b005b610545600480360381019061054091906123c3565b61146b565b005b34801561055357600080fd5b5061056e6004803603810190610569919061256d565b6114de565b60405161057b91906128f4565b60405180910390f35b34801561059057600080fd5b506105ab60048036038101906105a69190612520565b6115f8565b005b3480156105b957600080fd5b506105d460048036038101906105cf9190612330565b61168a565b6040516105e191906128be565b60405180910390f35b3480156105f657600080fd5b50610611600480360381019061060c9190612303565b61171e565b005b34801561061f57600080fd5b50610628611816565b60405161063591906129d6565b60405180910390f35b60006106498261181b565b9050919050565b60606002805461065f90612ca0565b80601f016020809104026020016040519081016040528092919081815260200182805461068b90612ca0565b80156106d85780601f106106ad576101008083540402835291602001916106d8565b820191906000526020600020905b8154815290600101906020018083116106bb57829003601f168201915b5050505050905090565b60006106ed82611895565b610723576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061076c82610f1d565b90508073ffffffffffffffffffffffffffffffffffffffff1661078d6118f4565b73ffffffffffffffffffffffffffffffffffffffff16146107f0576107b9816107b46118f4565b61168a565b6107ef576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6108ad6118fc565b73ffffffffffffffffffffffffffffffffffffffff166108cb611070565b73ffffffffffffffffffffffffffffffffffffffff1614610921576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091890612976565b60405180910390fd5b8181600c9190610932929190612131565b505050565b6000610941611904565b6001546000540303905090565b60006109598261190d565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109c0576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806109cc846119db565b915091506109e281876109dd6118f4565b611a02565b610a2e576109f7866109f26118f4565b61168a565b610a2d576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610a95576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610aa28686866001611a46565b8015610aad57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610b7b85610b57888887611a4c565b7c020000000000000000000000000000000000000000000000000000000017611a74565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084161415610c03576000600185019050600060046000838152602001908152602001600020541415610c01576000548114610c00578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610c6b8686866001611a9f565b505050505050565b6000806000600960008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161415610e095760086040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000610e13611aa5565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610e3f9190612b26565b610e499190612af5565b90508160000151819350935050509250929050565b620186a081565b6daaeb6d7670e522a718067333cd4e81565b610e928383836040518060200160405280600081525061146b565b505050565b610e9f6118fc565b73ffffffffffffffffffffffffffffffffffffffff16610ebd611070565b73ffffffffffffffffffffffffffffffffffffffff1614610f13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0a90612976565b60405180910390fd5b80600b8190555050565b6000610f288261190d565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f97576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b610ff06118fc565b73ffffffffffffffffffffffffffffffffffffffff1661100e611070565b73ffffffffffffffffffffffffffffffffffffffff1614611064576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105b90612976565b60405180910390fd5b61106e6000611aaf565b565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600380546110a990612ca0565b80601f01602080910402602001604051908101604052809291908181526020018280546110d590612ca0565b80156111225780601f106110f757610100808354040283529160200191611122565b820191906000526020600020905b81548152906001019060200180831161110557829003601f168201915b5050505050905090565b600381565b6111396118fc565b73ffffffffffffffffffffffffffffffffffffffff16611157611070565b73ffffffffffffffffffffffffffffffffffffffff16146111ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a490612976565b60405180910390fd5b60004790508173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156111f8573d6000803e3d6000fd5b505050565b620186a08161120a610937565b6112149190612a9f565b1115611255576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124c90612956565b60405180910390fd5b60018114806112645750600381145b8061126f5750600a81145b6112ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112a5906129b6565b60405180910390fd5b600381116112c5576112c03382611b75565b611319565b655af3107a400034101561130e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130590612936565b60405180910390fd5b6113183382611b75565b5b803373ffffffffffffffffffffffffffffffffffffffff167f52277f0b4a9b555c5aa96900a13546f972bda413737ec164aac947c87eec602460405160405180910390a350565b806007600061136d6118f4565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661141a6118f4565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161145f91906128be565b60405180910390a35050565b61147684848461094e565b60008373ffffffffffffffffffffffffffffffffffffffff163b146114d8576114a184848484611b93565b6114d7576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b60606000600b54141561157d57600c80546114f890612ca0565b80601f016020809104026020016040519081016040528092919081815260200182805461152490612ca0565b80156115715780601f1061154657610100808354040283529160200191611571565b820191906000526020600020905b81548152906001019060200180831161155457829003601f168201915b505050505090506115f3565b61158682611895565b6115c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bc90612996565b60405180910390fd5b600d6115d083611cf3565b6040516020016115e192919061280a565b60405160208183030381529060405290505b919050565b6116006118fc565b73ffffffffffffffffffffffffffffffffffffffff1661161e611070565b73ffffffffffffffffffffffffffffffffffffffff1614611674576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166b90612976565b60405180910390fd5b8181600d9190611685929190612131565b505050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6117266118fc565b73ffffffffffffffffffffffffffffffffffffffff16611744611070565b73ffffffffffffffffffffffffffffffffffffffff161461179a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179190612976565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561180a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180190612916565b60405180910390fd5b61181381611aaf565b50565b600a81565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061188e575061188d82611e54565b5b9050919050565b6000816118a0611904565b111580156118af575060005482105b80156118ed575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b600033905090565b60006001905090565b6000808290508061191c611904565b116119a4576000548110156119a35760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821614156119a1575b600081141561199757600460008360019003935083815260200190815260200160002054905061196c565b80925050506119d6565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611a63868684611ebe565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000612710905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611b8f828260405180602001604052806000815250611ec7565b5050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611bb96118f4565b8786866040518563ffffffff1660e01b8152600401611bdb9493929190612849565b602060405180830381600087803b158015611bf557600080fd5b505af1925050508015611c2657506040513d601f19601f82011682018060405250810190611c2391906124f3565b60015b611ca0573d8060008114611c56576040519150601f19603f3d011682016040523d82523d6000602084013e611c5b565b606091505b50600081511415611c98576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606000821415611d3b576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611e4f565b600082905060005b60008214611d6d578080611d5690612d03565b915050600a82611d669190612af5565b9150611d43565b60008167ffffffffffffffff811115611d8957611d88612e39565b5b6040519080825280601f01601f191660200182016040528015611dbb5781602001600182028036833780820191505090505b5090505b60008514611e4857600182611dd49190612b80565b9150600a85611de39190612d4c565b6030611def9190612a9f565b60f81b818381518110611e0557611e04612e0a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85611e419190612af5565b9450611dbf565b8093505050505b919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60009392505050565b611ed18383611f64565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611f5f57600080549050600083820390505b611f116000868380600101945086611b93565b611f47576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110611efe578160005414611f5c57600080fd5b50505b505050565b6000805490506000821415611fa5576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611fb26000848385611a46565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506120298361201a6000866000611a4c565b61202385612121565b17611a74565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146120ca57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460018101905061208f565b506000821415612106576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061211c6000848385611a9f565b505050565b60006001821460e11b9050919050565b82805461213d90612ca0565b90600052602060002090601f01602090048101928261215f57600085556121a6565b82601f1061217857803560ff19168380011785556121a6565b828001600101855582156121a6579182015b828111156121a557823582559160200191906001019061218a565b5b5090506121b391906121b7565b5090565b5b808211156121d05760008160009055506001016121b8565b5090565b60006121e76121e284612a16565b6129f1565b90508281526020810184848401111561220357612202612e77565b5b61220e848285612c5e565b509392505050565b60008135905061222581612fd9565b92915050565b60008135905061223a81612ff0565b92915050565b60008135905061224f81613007565b92915050565b60008151905061226481613007565b92915050565b600082601f83011261227f5761227e612e6d565b5b813561228f8482602086016121d4565b91505092915050565b60008083601f8401126122ae576122ad612e6d565b5b8235905067ffffffffffffffff8111156122cb576122ca612e68565b5b6020830191508360018202830111156122e7576122e6612e72565b5b9250929050565b6000813590506122fd8161301e565b92915050565b60006020828403121561231957612318612e81565b5b600061232784828501612216565b91505092915050565b6000806040838503121561234757612346612e81565b5b600061235585828601612216565b925050602061236685828601612216565b9150509250929050565b60008060006060848603121561238957612388612e81565b5b600061239786828701612216565b93505060206123a886828701612216565b92505060406123b9868287016122ee565b9150509250925092565b600080600080608085870312156123dd576123dc612e81565b5b60006123eb87828801612216565b94505060206123fc87828801612216565b935050604061240d878288016122ee565b925050606085013567ffffffffffffffff81111561242e5761242d612e7c565b5b61243a8782880161226a565b91505092959194509250565b6000806040838503121561245d5761245c612e81565b5b600061246b85828601612216565b925050602061247c8582860161222b565b9150509250929050565b6000806040838503121561249d5761249c612e81565b5b60006124ab85828601612216565b92505060206124bc858286016122ee565b9150509250929050565b6000602082840312156124dc576124db612e81565b5b60006124ea84828501612240565b91505092915050565b60006020828403121561250957612508612e81565b5b600061251784828501612255565b91505092915050565b6000806020838503121561253757612536612e81565b5b600083013567ffffffffffffffff81111561255557612554612e7c565b5b61256185828601612298565b92509250509250929050565b60006020828403121561258357612582612e81565b5b6000612591848285016122ee565b91505092915050565b600080604083850312156125b1576125b0612e81565b5b60006125bf858286016122ee565b92505060206125d0858286016122ee565b9150509250929050565b6125e381612bb4565b82525050565b6125f281612bc6565b82525050565b600061260382612a5c565b61260d8185612a72565b935061261d818560208601612c6d565b61262681612e86565b840191505092915050565b61263a81612c28565b82525050565b600061264b82612a67565b6126558185612a83565b9350612665818560208601612c6d565b61266e81612e86565b840191505092915050565b600061268482612a67565b61268e8185612a94565b935061269e818560208601612c6d565b80840191505092915050565b600081546126b781612ca0565b6126c18186612a94565b945060018216600081146126dc57600181146126ed57612720565b60ff19831686528186019350612720565b6126f685612a47565b60005b83811015612718578154818901526001820191506020810190506126f9565b838801955050505b50505092915050565b6000612736602683612a83565b915061274182612e97565b604082019050919050565b6000612759601c83612a83565b915061276482612ee6565b602082019050919050565b600061277c601e83612a83565b915061278782612f0f565b602082019050919050565b600061279f602083612a83565b91506127aa82612f38565b602082019050919050565b60006127c2602f83612a83565b91506127cd82612f61565b604082019050919050565b60006127e5601883612a83565b91506127f082612fb0565b602082019050919050565b61280481612c1e565b82525050565b600061281682856126aa565b91506128228284612679565b91508190509392505050565b600060208201905061284360008301846125da565b92915050565b600060808201905061285e60008301876125da565b61286b60208301866125da565b61287860408301856127fb565b818103606083015261288a81846125f8565b905095945050505050565b60006040820190506128aa60008301856125da565b6128b760208301846127fb565b9392505050565b60006020820190506128d360008301846125e9565b92915050565b60006020820190506128ee6000830184612631565b92915050565b6000602082019050818103600083015261290e8184612640565b905092915050565b6000602082019050818103600083015261292f81612729565b9050919050565b6000602082019050818103600083015261294f8161274c565b9050919050565b6000602082019050818103600083015261296f8161276f565b9050919050565b6000602082019050818103600083015261298f81612792565b9050919050565b600060208201905081810360008301526129af816127b5565b9050919050565b600060208201905081810360008301526129cf816127d8565b9050919050565b60006020820190506129eb60008301846127fb565b92915050565b60006129fb612a0c565b9050612a078282612cd2565b919050565b6000604051905090565b600067ffffffffffffffff821115612a3157612a30612e39565b5b612a3a82612e86565b9050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000612aaa82612c1e565b9150612ab583612c1e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612aea57612ae9612d7d565b5b828201905092915050565b6000612b0082612c1e565b9150612b0b83612c1e565b925082612b1b57612b1a612dac565b5b828204905092915050565b6000612b3182612c1e565b9150612b3c83612c1e565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612b7557612b74612d7d565b5b828202905092915050565b6000612b8b82612c1e565b9150612b9683612c1e565b925082821015612ba957612ba8612d7d565b5b828203905092915050565b6000612bbf82612bfe565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000612c3382612c3a565b9050919050565b6000612c4582612c4c565b9050919050565b6000612c5782612bfe565b9050919050565b82818337600083830152505050565b60005b83811015612c8b578082015181840152602081019050612c70565b83811115612c9a576000848401525b50505050565b60006002820490506001821680612cb857607f821691505b60208210811415612ccc57612ccb612ddb565b5b50919050565b612cdb82612e86565b810181811067ffffffffffffffff82111715612cfa57612cf9612e39565b5b80604052505050565b6000612d0e82612c1e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d4157612d40612d7d565b5b600182019050919050565b6000612d5782612c1e565b9150612d6283612c1e565b925082612d7257612d71612dac565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20496e73756666696369656e74207061796d656e7400000000600082015250565b7f4552433732313a2045786365656473206d6178696d756d20737570706c790000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b7f4552433732313a20496e76616c6964207175616e746974790000000000000000600082015250565b612fe281612bb4565b8114612fed57600080fd5b50565b612ff981612bc6565b811461300457600080fd5b50565b61301081612bd2565b811461301b57600080fd5b50565b61302781612c1e565b811461303257600080fd5b5056fea264697066735822122041fc91651827f370973a98bcda3eaf0f57d0ff1ddf68280a1c7fc5a1f1fcb90464736f6c6343000807003368747470733a2f2f697066732e696f2f697066732f516d5a346d665661456d3853367637414351584667546d6f62366e7472617467616a7838636a5046475a7854316e
Deployed Bytecode
0x60806040526004361061019c5760003560e01c806370a08231116100ec578063a22cb4651161008a578063e5e01c1111610064578063e5e01c1114610584578063e985e9c5146105ad578063f2fde38b146105ea578063fe878b1d146106135761019c565b8063a22cb46514610502578063b88d4fde1461052b578063c87b56dd146105475761019c565b806395d89b41116100c657806395d89b41146104675780639858cf19146104925780639894ba7c146104bd578063a0712d68146104e65761019c565b806370a08231146103e8578063715018a6146104255780638da5cb5b1461043c5761019c565b806323b872dd1161015957806341f434341161013357806341f434341461033b57806342842e0e14610366578063528c06cc146103825780636352211e146103ab5761019c565b806323b872dd146102b65780632a55205a146102d257806332cb6b0c146103105761019c565b806301ffc9a7146101a157806306fdde03146101de578063081812fc14610209578063095ea7b3146102465780630e5c19191461026257806318160ddd1461028b575b600080fd5b3480156101ad57600080fd5b506101c860048036038101906101c391906124c6565b61063e565b6040516101d591906128be565b60405180910390f35b3480156101ea57600080fd5b506101f3610650565b60405161020091906128f4565b60405180910390f35b34801561021557600080fd5b50610230600480360381019061022b919061256d565b6106e2565b60405161023d919061282e565b60405180910390f35b610260600480360381019061025b9190612486565b610761565b005b34801561026e57600080fd5b5061028960048036038101906102849190612520565b6108a5565b005b34801561029757600080fd5b506102a0610937565b6040516102ad91906129d6565b60405180910390f35b6102d060048036038101906102cb9190612370565b61094e565b005b3480156102de57600080fd5b506102f960048036038101906102f4919061259a565b610c73565b604051610307929190612895565b60405180910390f35b34801561031c57600080fd5b50610325610e5e565b60405161033291906129d6565b60405180910390f35b34801561034757600080fd5b50610350610e65565b60405161035d91906128d9565b60405180910390f35b610380600480360381019061037b9190612370565b610e77565b005b34801561038e57600080fd5b506103a960048036038101906103a4919061256d565b610e97565b005b3480156103b757600080fd5b506103d260048036038101906103cd919061256d565b610f1d565b6040516103df919061282e565b60405180910390f35b3480156103f457600080fd5b5061040f600480360381019061040a9190612303565b610f2f565b60405161041c91906129d6565b60405180910390f35b34801561043157600080fd5b5061043a610fe8565b005b34801561044857600080fd5b50610451611070565b60405161045e919061282e565b60405180910390f35b34801561047357600080fd5b5061047c61109a565b60405161048991906128f4565b60405180910390f35b34801561049e57600080fd5b506104a761112c565b6040516104b491906129d6565b60405180910390f35b3480156104c957600080fd5b506104e460048036038101906104df9190612303565b611131565b005b61050060048036038101906104fb919061256d565b6111fd565b005b34801561050e57600080fd5b5061052960048036038101906105249190612446565b611360565b005b610545600480360381019061054091906123c3565b61146b565b005b34801561055357600080fd5b5061056e6004803603810190610569919061256d565b6114de565b60405161057b91906128f4565b60405180910390f35b34801561059057600080fd5b506105ab60048036038101906105a69190612520565b6115f8565b005b3480156105b957600080fd5b506105d460048036038101906105cf9190612330565b61168a565b6040516105e191906128be565b60405180910390f35b3480156105f657600080fd5b50610611600480360381019061060c9190612303565b61171e565b005b34801561061f57600080fd5b50610628611816565b60405161063591906129d6565b60405180910390f35b60006106498261181b565b9050919050565b60606002805461065f90612ca0565b80601f016020809104026020016040519081016040528092919081815260200182805461068b90612ca0565b80156106d85780601f106106ad576101008083540402835291602001916106d8565b820191906000526020600020905b8154815290600101906020018083116106bb57829003601f168201915b5050505050905090565b60006106ed82611895565b610723576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061076c82610f1d565b90508073ffffffffffffffffffffffffffffffffffffffff1661078d6118f4565b73ffffffffffffffffffffffffffffffffffffffff16146107f0576107b9816107b46118f4565b61168a565b6107ef576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6108ad6118fc565b73ffffffffffffffffffffffffffffffffffffffff166108cb611070565b73ffffffffffffffffffffffffffffffffffffffff1614610921576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091890612976565b60405180910390fd5b8181600c9190610932929190612131565b505050565b6000610941611904565b6001546000540303905090565b60006109598261190d565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109c0576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806109cc846119db565b915091506109e281876109dd6118f4565b611a02565b610a2e576109f7866109f26118f4565b61168a565b610a2d576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610a95576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610aa28686866001611a46565b8015610aad57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610b7b85610b57888887611a4c565b7c020000000000000000000000000000000000000000000000000000000017611a74565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084161415610c03576000600185019050600060046000838152602001908152602001600020541415610c01576000548114610c00578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610c6b8686866001611a9f565b505050505050565b6000806000600960008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161415610e095760086040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000610e13611aa5565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610e3f9190612b26565b610e499190612af5565b90508160000151819350935050509250929050565b620186a081565b6daaeb6d7670e522a718067333cd4e81565b610e928383836040518060200160405280600081525061146b565b505050565b610e9f6118fc565b73ffffffffffffffffffffffffffffffffffffffff16610ebd611070565b73ffffffffffffffffffffffffffffffffffffffff1614610f13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0a90612976565b60405180910390fd5b80600b8190555050565b6000610f288261190d565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f97576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b610ff06118fc565b73ffffffffffffffffffffffffffffffffffffffff1661100e611070565b73ffffffffffffffffffffffffffffffffffffffff1614611064576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105b90612976565b60405180910390fd5b61106e6000611aaf565b565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600380546110a990612ca0565b80601f01602080910402602001604051908101604052809291908181526020018280546110d590612ca0565b80156111225780601f106110f757610100808354040283529160200191611122565b820191906000526020600020905b81548152906001019060200180831161110557829003601f168201915b5050505050905090565b600381565b6111396118fc565b73ffffffffffffffffffffffffffffffffffffffff16611157611070565b73ffffffffffffffffffffffffffffffffffffffff16146111ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a490612976565b60405180910390fd5b60004790508173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156111f8573d6000803e3d6000fd5b505050565b620186a08161120a610937565b6112149190612a9f565b1115611255576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124c90612956565b60405180910390fd5b60018114806112645750600381145b8061126f5750600a81145b6112ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112a5906129b6565b60405180910390fd5b600381116112c5576112c03382611b75565b611319565b655af3107a400034101561130e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130590612936565b60405180910390fd5b6113183382611b75565b5b803373ffffffffffffffffffffffffffffffffffffffff167f52277f0b4a9b555c5aa96900a13546f972bda413737ec164aac947c87eec602460405160405180910390a350565b806007600061136d6118f4565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661141a6118f4565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161145f91906128be565b60405180910390a35050565b61147684848461094e565b60008373ffffffffffffffffffffffffffffffffffffffff163b146114d8576114a184848484611b93565b6114d7576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b60606000600b54141561157d57600c80546114f890612ca0565b80601f016020809104026020016040519081016040528092919081815260200182805461152490612ca0565b80156115715780601f1061154657610100808354040283529160200191611571565b820191906000526020600020905b81548152906001019060200180831161155457829003601f168201915b505050505090506115f3565b61158682611895565b6115c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bc90612996565b60405180910390fd5b600d6115d083611cf3565b6040516020016115e192919061280a565b60405160208183030381529060405290505b919050565b6116006118fc565b73ffffffffffffffffffffffffffffffffffffffff1661161e611070565b73ffffffffffffffffffffffffffffffffffffffff1614611674576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166b90612976565b60405180910390fd5b8181600d9190611685929190612131565b505050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6117266118fc565b73ffffffffffffffffffffffffffffffffffffffff16611744611070565b73ffffffffffffffffffffffffffffffffffffffff161461179a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179190612976565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561180a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180190612916565b60405180910390fd5b61181381611aaf565b50565b600a81565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061188e575061188d82611e54565b5b9050919050565b6000816118a0611904565b111580156118af575060005482105b80156118ed575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b600033905090565b60006001905090565b6000808290508061191c611904565b116119a4576000548110156119a35760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821614156119a1575b600081141561199757600460008360019003935083815260200190815260200160002054905061196c565b80925050506119d6565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611a63868684611ebe565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000612710905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611b8f828260405180602001604052806000815250611ec7565b5050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611bb96118f4565b8786866040518563ffffffff1660e01b8152600401611bdb9493929190612849565b602060405180830381600087803b158015611bf557600080fd5b505af1925050508015611c2657506040513d601f19601f82011682018060405250810190611c2391906124f3565b60015b611ca0573d8060008114611c56576040519150601f19603f3d011682016040523d82523d6000602084013e611c5b565b606091505b50600081511415611c98576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606000821415611d3b576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611e4f565b600082905060005b60008214611d6d578080611d5690612d03565b915050600a82611d669190612af5565b9150611d43565b60008167ffffffffffffffff811115611d8957611d88612e39565b5b6040519080825280601f01601f191660200182016040528015611dbb5781602001600182028036833780820191505090505b5090505b60008514611e4857600182611dd49190612b80565b9150600a85611de39190612d4c565b6030611def9190612a9f565b60f81b818381518110611e0557611e04612e0a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85611e419190612af5565b9450611dbf565b8093505050505b919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60009392505050565b611ed18383611f64565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611f5f57600080549050600083820390505b611f116000868380600101945086611b93565b611f47576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110611efe578160005414611f5c57600080fd5b50505b505050565b6000805490506000821415611fa5576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611fb26000848385611a46565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506120298361201a6000866000611a4c565b61202385612121565b17611a74565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146120ca57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460018101905061208f565b506000821415612106576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061211c6000848385611a9f565b505050565b60006001821460e11b9050919050565b82805461213d90612ca0565b90600052602060002090601f01602090048101928261215f57600085556121a6565b82601f1061217857803560ff19168380011785556121a6565b828001600101855582156121a6579182015b828111156121a557823582559160200191906001019061218a565b5b5090506121b391906121b7565b5090565b5b808211156121d05760008160009055506001016121b8565b5090565b60006121e76121e284612a16565b6129f1565b90508281526020810184848401111561220357612202612e77565b5b61220e848285612c5e565b509392505050565b60008135905061222581612fd9565b92915050565b60008135905061223a81612ff0565b92915050565b60008135905061224f81613007565b92915050565b60008151905061226481613007565b92915050565b600082601f83011261227f5761227e612e6d565b5b813561228f8482602086016121d4565b91505092915050565b60008083601f8401126122ae576122ad612e6d565b5b8235905067ffffffffffffffff8111156122cb576122ca612e68565b5b6020830191508360018202830111156122e7576122e6612e72565b5b9250929050565b6000813590506122fd8161301e565b92915050565b60006020828403121561231957612318612e81565b5b600061232784828501612216565b91505092915050565b6000806040838503121561234757612346612e81565b5b600061235585828601612216565b925050602061236685828601612216565b9150509250929050565b60008060006060848603121561238957612388612e81565b5b600061239786828701612216565b93505060206123a886828701612216565b92505060406123b9868287016122ee565b9150509250925092565b600080600080608085870312156123dd576123dc612e81565b5b60006123eb87828801612216565b94505060206123fc87828801612216565b935050604061240d878288016122ee565b925050606085013567ffffffffffffffff81111561242e5761242d612e7c565b5b61243a8782880161226a565b91505092959194509250565b6000806040838503121561245d5761245c612e81565b5b600061246b85828601612216565b925050602061247c8582860161222b565b9150509250929050565b6000806040838503121561249d5761249c612e81565b5b60006124ab85828601612216565b92505060206124bc858286016122ee565b9150509250929050565b6000602082840312156124dc576124db612e81565b5b60006124ea84828501612240565b91505092915050565b60006020828403121561250957612508612e81565b5b600061251784828501612255565b91505092915050565b6000806020838503121561253757612536612e81565b5b600083013567ffffffffffffffff81111561255557612554612e7c565b5b61256185828601612298565b92509250509250929050565b60006020828403121561258357612582612e81565b5b6000612591848285016122ee565b91505092915050565b600080604083850312156125b1576125b0612e81565b5b60006125bf858286016122ee565b92505060206125d0858286016122ee565b9150509250929050565b6125e381612bb4565b82525050565b6125f281612bc6565b82525050565b600061260382612a5c565b61260d8185612a72565b935061261d818560208601612c6d565b61262681612e86565b840191505092915050565b61263a81612c28565b82525050565b600061264b82612a67565b6126558185612a83565b9350612665818560208601612c6d565b61266e81612e86565b840191505092915050565b600061268482612a67565b61268e8185612a94565b935061269e818560208601612c6d565b80840191505092915050565b600081546126b781612ca0565b6126c18186612a94565b945060018216600081146126dc57600181146126ed57612720565b60ff19831686528186019350612720565b6126f685612a47565b60005b83811015612718578154818901526001820191506020810190506126f9565b838801955050505b50505092915050565b6000612736602683612a83565b915061274182612e97565b604082019050919050565b6000612759601c83612a83565b915061276482612ee6565b602082019050919050565b600061277c601e83612a83565b915061278782612f0f565b602082019050919050565b600061279f602083612a83565b91506127aa82612f38565b602082019050919050565b60006127c2602f83612a83565b91506127cd82612f61565b604082019050919050565b60006127e5601883612a83565b91506127f082612fb0565b602082019050919050565b61280481612c1e565b82525050565b600061281682856126aa565b91506128228284612679565b91508190509392505050565b600060208201905061284360008301846125da565b92915050565b600060808201905061285e60008301876125da565b61286b60208301866125da565b61287860408301856127fb565b818103606083015261288a81846125f8565b905095945050505050565b60006040820190506128aa60008301856125da565b6128b760208301846127fb565b9392505050565b60006020820190506128d360008301846125e9565b92915050565b60006020820190506128ee6000830184612631565b92915050565b6000602082019050818103600083015261290e8184612640565b905092915050565b6000602082019050818103600083015261292f81612729565b9050919050565b6000602082019050818103600083015261294f8161274c565b9050919050565b6000602082019050818103600083015261296f8161276f565b9050919050565b6000602082019050818103600083015261298f81612792565b9050919050565b600060208201905081810360008301526129af816127b5565b9050919050565b600060208201905081810360008301526129cf816127d8565b9050919050565b60006020820190506129eb60008301846127fb565b92915050565b60006129fb612a0c565b9050612a078282612cd2565b919050565b6000604051905090565b600067ffffffffffffffff821115612a3157612a30612e39565b5b612a3a82612e86565b9050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000612aaa82612c1e565b9150612ab583612c1e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612aea57612ae9612d7d565b5b828201905092915050565b6000612b0082612c1e565b9150612b0b83612c1e565b925082612b1b57612b1a612dac565b5b828204905092915050565b6000612b3182612c1e565b9150612b3c83612c1e565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612b7557612b74612d7d565b5b828202905092915050565b6000612b8b82612c1e565b9150612b9683612c1e565b925082821015612ba957612ba8612d7d565b5b828203905092915050565b6000612bbf82612bfe565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000612c3382612c3a565b9050919050565b6000612c4582612c4c565b9050919050565b6000612c5782612bfe565b9050919050565b82818337600083830152505050565b60005b83811015612c8b578082015181840152602081019050612c70565b83811115612c9a576000848401525b50505050565b60006002820490506001821680612cb857607f821691505b60208210811415612ccc57612ccb612ddb565b5b50919050565b612cdb82612e86565b810181811067ffffffffffffffff82111715612cfa57612cf9612e39565b5b80604052505050565b6000612d0e82612c1e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d4157612d40612d7d565b5b600182019050919050565b6000612d5782612c1e565b9150612d6283612c1e565b925082612d7257612d71612dac565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20496e73756666696369656e74207061796d656e7400000000600082015250565b7f4552433732313a2045786365656473206d6178696d756d20737570706c790000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b7f4552433732313a20496e76616c6964207175616e746974790000000000000000600082015250565b612fe281612bb4565b8114612fed57600080fd5b50565b612ff981612bc6565b811461300457600080fd5b50565b61301081612bd2565b811461301b57600080fd5b50565b61302781612c1e565b811461303257600080fd5b5056fea264697066735822122041fc91651827f370973a98bcda3eaf0f57d0ff1ddf68280a1c7fc5a1f1fcb90464736f6c63430008070033
Deployed Bytecode Sourcemap
76589:2502:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77254:174;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24719:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31210:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30643:408;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;77803:111;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;20470:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34849:2825;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;61348:442;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;76702:43;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2932:143;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37770:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;77703:92;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;26112:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21654:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75616:103;;;;;;;;;;;;;:::i;:::-;;74965:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24895:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76752:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77545:150;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;78526:560;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;31768:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;38561:407;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;78161:357;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77922:109;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;32159:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75874:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76798:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77254:174;77362:4;77384:36;77408:11;77384:23;:36::i;:::-;77377:43;;77254:174;;;:::o;24719:100::-;24773:13;24806:5;24799:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24719:100;:::o;31210:218::-;31286:7;31311:16;31319:7;31311;:16::i;:::-;31306:64;;31336:34;;;;;;;;;;;;;;31306:64;31390:15;:24;31406:7;31390:24;;;;;;;;;;;:30;;;;;;;;;;;;31383:37;;31210:218;;;:::o;30643:408::-;30732:13;30748:16;30756:7;30748;:16::i;:::-;30732:32;;30804:5;30781:28;;:19;:17;:19::i;:::-;:28;;;30777:175;;30829:44;30846:5;30853:19;:17;:19::i;:::-;30829:16;:44::i;:::-;30824:128;;30901:35;;;;;;;;;;;;;;30824:128;30777:175;30997:2;30964:15;:24;30980:7;30964:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;31035:7;31031:2;31015:28;;31024:5;31015:28;;;;;;;;;;;;30721:330;30643:408;;:::o;77803:111::-;75196:12;:10;:12::i;:::-;75185:23;;:7;:5;:7::i;:::-;:23;;;75177:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;77897:9:::1;;77882:12;:24;;;;;;;:::i;:::-;;77803:111:::0;;:::o;20470:323::-;20531:7;20759:15;:13;:15::i;:::-;20744:12;;20728:13;;:28;:46;20721:53;;20470:323;:::o;34849:2825::-;34991:27;35021;35040:7;35021:18;:27::i;:::-;34991:57;;35106:4;35065:45;;35081:19;35065:45;;;35061:86;;35119:28;;;;;;;;;;;;;;35061:86;35161:27;35190:23;35217:35;35244:7;35217:26;:35::i;:::-;35160:92;;;;35352:68;35377:15;35394:4;35400:19;:17;:19::i;:::-;35352:24;:68::i;:::-;35347:180;;35440:43;35457:4;35463:19;:17;:19::i;:::-;35440:16;:43::i;:::-;35435:92;;35492:35;;;;;;;;;;;;;;35435:92;35347:180;35558:1;35544:16;;:2;:16;;;35540:52;;;35569:23;;;;;;;;;;;;;;35540:52;35605:43;35627:4;35633:2;35637:7;35646:1;35605:21;:43::i;:::-;35741:15;35738:160;;;35881:1;35860:19;35853:30;35738:160;36278:18;:24;36297:4;36278:24;;;;;;;;;;;;;;;;36276:26;;;;;;;;;;;;36347:18;:22;36366:2;36347:22;;;;;;;;;;;;;;;;36345:24;;;;;;;;;;;36669:146;36706:2;36755:45;36770:4;36776:2;36780:19;36755:14;:45::i;:::-;16869:8;36727:73;36669:18;:146::i;:::-;36640:17;:26;36658:7;36640:26;;;;;;;;;;;:175;;;;36986:1;16869:8;36935:19;:47;:52;36931:627;;;37008:19;37040:1;37030:7;:11;37008:33;;37197:1;37163:17;:30;37181:11;37163:30;;;;;;;;;;;;:35;37159:384;;;37301:13;;37286:11;:28;37282:242;;37481:19;37448:17;:30;37466:11;37448:30;;;;;;;;;;;:52;;;;37282:242;37159:384;36989:569;36931:627;37605:7;37601:2;37586:27;;37595:4;37586:27;;;;;;;;;;;;37624:42;37645:4;37651:2;37655:7;37664:1;37624:20;:42::i;:::-;34980:2694;;;34849:2825;;;:::o;61348:442::-;61445:7;61454;61474:26;61503:17;:27;61521:8;61503:27;;;;;;;;;;;61474:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61575:1;61547:30;;:7;:16;;;:30;;;61543:92;;;61604:19;61594:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61543:92;61647:21;61712:17;:15;:17::i;:::-;61671:58;;61685:7;:23;;;61672:36;;:10;:36;;;;:::i;:::-;61671:58;;;;:::i;:::-;61647:82;;61750:7;:16;;;61768:13;61742:40;;;;;;61348:442;;;;;:::o;76702:43::-;76739:6;76702:43;:::o;2932:143::-;3032:42;2932:143;:::o;37770:193::-;37916:39;37933:4;37939:2;37943:7;37916:39;;;;;;;;;;;;:16;:39::i;:::-;37770:193;;;:::o;77703:92::-;75196:12;:10;:12::i;:::-;75185:23;;:7;:5;:7::i;:::-;:23;;;75177:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;77783:4:::1;77775:5;:12;;;;77703:92:::0;:::o;26112:152::-;26184:7;26227:27;26246:7;26227:18;:27::i;:::-;26204:52;;26112:152;;;:::o;21654:233::-;21726:7;21767:1;21750:19;;:5;:19;;;21746:60;;;21778:28;;;;;;;;;;;;;;21746:60;15813:13;21824:18;:25;21843:5;21824:25;;;;;;;;;;;;;;;;:55;21817:62;;21654:233;;;:::o;75616:103::-;75196:12;:10;:12::i;:::-;75185:23;;:7;:5;:7::i;:::-;:23;;;75177:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;75681:30:::1;75708:1;75681:18;:30::i;:::-;75616:103::o:0;74965:87::-;75011:7;75038:6;;;;;;;;;;;75031:13;;74965:87;:::o;24895:104::-;24951:13;24984:7;24977:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24895:104;:::o;76752:39::-;76790:1;76752:39;:::o;77545:150::-;75196:12;:10;:12::i;:::-;75185:23;;:7;:5;:7::i;:::-;:23;;;75177:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;77607:15:::1;77625:21;77607:39;;77665:3;77657:21;;:30;77679:7;77657:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;77596:99;77545:150:::0;:::o;78526:560::-;76739:6;78608:8;78592:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:38;;78584:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;78696:1;78684:8;:13;:40;;;;76790:1;78701:8;:23;78684:40;:67;;;;76836:2;78728:8;:23;78684:67;78676:104;;;;;;;;;;;;:::i;:::-;;;;;;;;;76790:1;78797:8;:23;78793:231;;78838:30;78848:10;78859:8;78838:9;:30::i;:::-;78793:231;;;78922:12;78909:9;:25;;78901:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;78982:30;78992:10;79003:8;78982:9;:30::i;:::-;78793:231;79069:8;79057:10;79049:29;;;;;;;;;;;;78526:560;:::o;31768:234::-;31915:8;31863:18;:39;31882:19;:17;:19::i;:::-;31863:39;;;;;;;;;;;;;;;:49;31903:8;31863:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;31975:8;31939:55;;31954:19;:17;:19::i;:::-;31939:55;;;31985:8;31939:55;;;;;;:::i;:::-;;;;;;;;31768:234;;:::o;38561:407::-;38736:31;38749:4;38755:2;38759:7;38736:12;:31::i;:::-;38800:1;38782:2;:14;;;:19;38778:183;;38821:56;38852:4;38858:2;38862:7;38871:5;38821:30;:56::i;:::-;38816:145;;38905:40;;;;;;;;;;;;;;38816:145;38778:183;38561:407;;;;:::o;78161:357::-;78226:13;78265:1;78256:5;;:10;78252:259;;;78290:12;78283:19;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78252:259;78343:16;78351:7;78343;:16::i;:::-;78335:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;78457:13;78472:25;78489:7;78472:16;:25::i;:::-;78440:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;78426:73;;78161:357;;;;:::o;77922:109::-;75196:12;:10;:12::i;:::-;75185:23;;:7;:5;:7::i;:::-;:23;;;75177:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;78014:9:::1;;77998:13;:25;;;;;;;:::i;:::-;;77922:109:::0;;:::o;32159:164::-;32256:4;32280:18;:25;32299:5;32280:25;;;;;;;;;;;;;;;:35;32306:8;32280:35;;;;;;;;;;;;;;;;;;;;;;;;;32273:42;;32159:164;;;;:::o;75874:201::-;75196:12;:10;:12::i;:::-;75185:23;;:7;:5;:7::i;:::-;:23;;;75177:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;75983:1:::1;75963:22;;:8;:22;;;;75955:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;76039:28;76058:8;76039:18;:28::i;:::-;75874:201:::0;:::o;76798:40::-;76836:2;76798:40;:::o;61078:215::-;61180:4;61219:26;61204:41;;;:11;:41;;;;:81;;;;61249:36;61273:11;61249:23;:36::i;:::-;61204:81;61197:88;;61078:215;;;:::o;32581:282::-;32646:4;32702:7;32683:15;:13;:15::i;:::-;:26;;:66;;;;;32736:13;;32726:7;:23;32683:66;:153;;;;;32835:1;16589:8;32787:17;:26;32805:7;32787:26;;;;;;;;;;;;:44;:49;32683:153;32663:173;;32581:282;;;:::o;54889:105::-;54949:7;54976:10;54969:17;;54889:105;:::o;73689:98::-;73742:7;73769:10;73762:17;;73689:98;:::o;77436:101::-;77501:7;77528:1;77521:8;;77436:101;:::o;27267:1275::-;27334:7;27354:12;27369:7;27354:22;;27437:4;27418:15;:13;:15::i;:::-;:23;27414:1061;;27471:13;;27464:4;:20;27460:1015;;;27509:14;27526:17;:23;27544:4;27526:23;;;;;;;;;;;;27509:40;;27643:1;16589:8;27615:6;:24;:29;27611:845;;;28280:113;28297:1;28287:6;:11;28280:113;;;28340:17;:25;28358:6;;;;;;;28340:25;;;;;;;;;;;;28331:34;;28280:113;;;28426:6;28419:13;;;;;;27611:845;27486:989;27460:1015;27414:1061;28503:31;;;;;;;;;;;;;;27267:1275;;;;:::o;33744:485::-;33846:27;33875:23;33916:38;33957:15;:24;33973:7;33957:24;;;;;;;;;;;33916:65;;34134:18;34111:41;;34191:19;34185:26;34166:45;;34096:126;33744:485;;;:::o;32972:659::-;33121:11;33286:16;33279:5;33275:28;33266:37;;33446:16;33435:9;33431:32;33418:45;;33596:15;33585:9;33582:30;33574:5;33563:9;33560:20;33557:56;33547:66;;32972:659;;;;;:::o;39630:159::-;;;;;:::o;54198:311::-;54333:7;54353:16;16993:3;54379:19;:41;;54353:68;;16993:3;54447:31;54458:4;54464:2;54468:9;54447:10;:31::i;:::-;54439:40;;:62;;54432:69;;;54198:311;;;;;:::o;29090:450::-;29170:14;29338:16;29331:5;29327:28;29318:37;;29515:5;29501:11;29476:23;29472:41;29469:52;29462:5;29459:63;29449:73;;29090:450;;;;:::o;40454:158::-;;;;;:::o;62072:97::-;62130:6;62156:5;62149:12;;62072:97;:::o;76235:191::-;76309:16;76328:6;;;;;;;;;;;76309:25;;76354:8;76345:6;;:17;;;;;;;;;;;;;;;;;;76409:8;76378:40;;76399:8;76378:40;;;;;;;;;;;;76298:128;76235:191;:::o;48721:112::-;48798:27;48808:2;48812:8;48798:27;;;;;;;;;;;;:9;:27::i;:::-;48721:112;;:::o;41052:716::-;41215:4;41261:2;41236:45;;;41282:19;:17;:19::i;:::-;41303:4;41309:7;41318:5;41236:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;41232:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41536:1;41519:6;:13;:18;41515:235;;;41565:40;;;;;;;;;;;;;;41515:235;41708:6;41702:13;41693:6;41689:2;41685:15;41678:38;41232:529;41405:54;;;41395:64;;;:6;:64;;;;41388:71;;;41052:716;;;;;;:::o;71251:723::-;71307:13;71537:1;71528:5;:10;71524:53;;;71555:10;;;;;;;;;;;;;;;;;;;;;71524:53;71587:12;71602:5;71587:20;;71618:14;71643:78;71658:1;71650:4;:9;71643:78;;71676:8;;;;;:::i;:::-;;;;71707:2;71699:10;;;;;:::i;:::-;;;71643:78;;;71731:19;71763:6;71753:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71731:39;;71781:154;71797:1;71788:5;:10;71781:154;;71825:1;71815:11;;;;;:::i;:::-;;;71892:2;71884:5;:10;;;;:::i;:::-;71871:2;:24;;;;:::i;:::-;71858:39;;71841:6;71848;71841:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;71921:2;71912:11;;;;;:::i;:::-;;;71781:154;;;71959:6;71945:21;;;;;71251:723;;;;:::o;58630:157::-;58715:4;58754:25;58739:40;;;:11;:40;;;;58732:47;;58630:157;;;:::o;53899:147::-;54036:6;53899:147;;;;;:::o;47948:689::-;48079:19;48085:2;48089:8;48079:5;:19::i;:::-;48158:1;48140:2;:14;;;:19;48136:483;;48180:11;48194:13;;48180:27;;48226:13;48248:8;48242:3;:14;48226:30;;48275:233;48306:62;48345:1;48349:2;48353:7;;;;;;48362:5;48306:30;:62::i;:::-;48301:167;;48404:40;;;;;;;;;;;;;;48301:167;48503:3;48495:5;:11;48275:233;;48590:3;48573:13;;:20;48569:34;;48595:8;;;48569:34;48161:458;;48136:483;47948:689;;;:::o;42230:2966::-;42303:20;42326:13;;42303:36;;42366:1;42354:8;:13;42350:44;;;42376:18;;;;;;;;;;;;;;42350:44;42407:61;42437:1;42441:2;42445:12;42459:8;42407:21;:61::i;:::-;42951:1;15951:2;42921:1;:26;;42920:32;42908:8;:45;42882:18;:22;42901:2;42882:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;43230:139;43267:2;43321:33;43344:1;43348:2;43352:1;43321:14;:33::i;:::-;43288:30;43309:8;43288:20;:30::i;:::-;:66;43230:18;:139::i;:::-;43196:17;:31;43214:12;43196:31;;;;;;;;;;;:173;;;;43386:16;43417:11;43446:8;43431:12;:23;43417:37;;43967:16;43963:2;43959:25;43947:37;;44339:12;44299:8;44258:1;44196:25;44137:1;44076;44049:335;44710:1;44696:12;44692:20;44650:346;44751:3;44742:7;44739:16;44650:346;;44969:7;44959:8;44956:1;44929:25;44926:1;44923;44918:59;44804:1;44795:7;44791:15;44780:26;;44650:346;;;44654:77;45041:1;45029:8;:13;45025:45;;;45051:19;;;;;;;;;;;;;;45025:45;45103:3;45087:13;:19;;;;42656:2462;;45128:60;45157:1;45161:2;45165:12;45179:8;45128:20;:60::i;:::-;42292:2904;42230:2966;;:::o;29642:324::-;29712:14;29945:1;29935:8;29932:15;29906:24;29902:46;29892:56;;29642:324;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:410:1:-;84:5;109:65;125:48;166:6;125:48;:::i;:::-;109:65;:::i;:::-;100:74;;197:6;190:5;183:21;235:4;228:5;224:16;273:3;264:6;259:3;255:16;252:25;249:112;;;280:79;;:::i;:::-;249:112;370:41;404:6;399:3;394;370:41;:::i;:::-;90:327;7:410;;;;;:::o;423:139::-;469:5;507:6;494:20;485:29;;523:33;550:5;523:33;:::i;:::-;423:139;;;;:::o;568:133::-;611:5;649:6;636:20;627:29;;665:30;689:5;665:30;:::i;:::-;568:133;;;;:::o;707:137::-;752:5;790:6;777:20;768:29;;806:32;832:5;806:32;:::i;:::-;707:137;;;;:::o;850:141::-;906:5;937:6;931:13;922:22;;953:32;979:5;953:32;:::i;:::-;850:141;;;;:::o;1010:338::-;1065:5;1114:3;1107:4;1099:6;1095:17;1091:27;1081:122;;1122:79;;:::i;:::-;1081:122;1239:6;1226:20;1264:78;1338:3;1330:6;1323:4;1315:6;1311:17;1264:78;:::i;:::-;1255:87;;1071:277;1010:338;;;;:::o;1368:553::-;1426:8;1436:6;1486:3;1479:4;1471:6;1467:17;1463:27;1453:122;;1494:79;;:::i;:::-;1453:122;1607:6;1594:20;1584:30;;1637:18;1629:6;1626:30;1623:117;;;1659:79;;:::i;:::-;1623:117;1773:4;1765:6;1761:17;1749:29;;1827:3;1819:4;1811:6;1807:17;1797:8;1793:32;1790:41;1787:128;;;1834:79;;:::i;:::-;1787:128;1368:553;;;;;:::o;1927:139::-;1973:5;2011:6;1998:20;1989:29;;2027:33;2054:5;2027:33;:::i;:::-;1927:139;;;;:::o;2072:329::-;2131:6;2180:2;2168:9;2159:7;2155:23;2151:32;2148:119;;;2186:79;;:::i;:::-;2148:119;2306:1;2331:53;2376:7;2367:6;2356:9;2352:22;2331:53;:::i;:::-;2321:63;;2277:117;2072:329;;;;:::o;2407:474::-;2475:6;2483;2532:2;2520:9;2511:7;2507:23;2503:32;2500:119;;;2538:79;;:::i;:::-;2500:119;2658:1;2683:53;2728:7;2719:6;2708:9;2704:22;2683:53;:::i;:::-;2673:63;;2629:117;2785:2;2811:53;2856:7;2847:6;2836:9;2832:22;2811:53;:::i;:::-;2801:63;;2756:118;2407:474;;;;;:::o;2887:619::-;2964:6;2972;2980;3029:2;3017:9;3008:7;3004:23;3000:32;2997:119;;;3035:79;;:::i;:::-;2997:119;3155:1;3180:53;3225:7;3216:6;3205:9;3201:22;3180:53;:::i;:::-;3170:63;;3126:117;3282:2;3308:53;3353:7;3344:6;3333:9;3329:22;3308:53;:::i;:::-;3298:63;;3253:118;3410:2;3436:53;3481:7;3472:6;3461:9;3457:22;3436:53;:::i;:::-;3426:63;;3381:118;2887:619;;;;;:::o;3512:943::-;3607:6;3615;3623;3631;3680:3;3668:9;3659:7;3655:23;3651:33;3648:120;;;3687:79;;:::i;:::-;3648:120;3807:1;3832:53;3877:7;3868:6;3857:9;3853:22;3832:53;:::i;:::-;3822:63;;3778:117;3934:2;3960:53;4005:7;3996:6;3985:9;3981:22;3960:53;:::i;:::-;3950:63;;3905:118;4062:2;4088:53;4133:7;4124:6;4113:9;4109:22;4088:53;:::i;:::-;4078:63;;4033:118;4218:2;4207:9;4203:18;4190:32;4249:18;4241:6;4238:30;4235:117;;;4271:79;;:::i;:::-;4235:117;4376:62;4430:7;4421:6;4410:9;4406:22;4376:62;:::i;:::-;4366:72;;4161:287;3512:943;;;;;;;:::o;4461:468::-;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:50;4904:7;4895:6;4884:9;4880:22;4862:50;:::i;:::-;4852:60;;4807:115;4461:468;;;;;:::o;4935:474::-;5003:6;5011;5060:2;5048:9;5039:7;5035:23;5031:32;5028:119;;;5066:79;;:::i;:::-;5028:119;5186:1;5211:53;5256:7;5247:6;5236:9;5232:22;5211:53;:::i;:::-;5201:63;;5157:117;5313:2;5339:53;5384:7;5375:6;5364:9;5360:22;5339:53;:::i;:::-;5329:63;;5284:118;4935:474;;;;;:::o;5415:327::-;5473:6;5522:2;5510:9;5501:7;5497:23;5493:32;5490:119;;;5528:79;;:::i;:::-;5490:119;5648:1;5673:52;5717:7;5708:6;5697:9;5693:22;5673:52;:::i;:::-;5663:62;;5619:116;5415:327;;;;:::o;5748:349::-;5817:6;5866:2;5854:9;5845:7;5841:23;5837:32;5834:119;;;5872:79;;:::i;:::-;5834:119;5992:1;6017:63;6072:7;6063:6;6052:9;6048:22;6017:63;:::i;:::-;6007:73;;5963:127;5748:349;;;;:::o;6103:529::-;6174:6;6182;6231:2;6219:9;6210:7;6206:23;6202:32;6199:119;;;6237:79;;:::i;:::-;6199:119;6385:1;6374:9;6370:17;6357:31;6415:18;6407:6;6404:30;6401:117;;;6437:79;;:::i;:::-;6401:117;6550:65;6607:7;6598:6;6587:9;6583:22;6550:65;:::i;:::-;6532:83;;;;6328:297;6103:529;;;;;:::o;6638:329::-;6697:6;6746:2;6734:9;6725:7;6721:23;6717:32;6714:119;;;6752:79;;:::i;:::-;6714:119;6872:1;6897:53;6942:7;6933:6;6922:9;6918:22;6897:53;:::i;:::-;6887:63;;6843:117;6638:329;;;;:::o;6973:474::-;7041:6;7049;7098:2;7086:9;7077:7;7073:23;7069:32;7066:119;;;7104:79;;:::i;:::-;7066:119;7224:1;7249:53;7294:7;7285:6;7274:9;7270:22;7249:53;:::i;:::-;7239:63;;7195:117;7351:2;7377:53;7422:7;7413:6;7402:9;7398:22;7377:53;:::i;:::-;7367:63;;7322:118;6973:474;;;;;:::o;7453:118::-;7540:24;7558:5;7540:24;:::i;:::-;7535:3;7528:37;7453:118;;:::o;7577:109::-;7658:21;7673:5;7658:21;:::i;:::-;7653:3;7646:34;7577:109;;:::o;7692:360::-;7778:3;7806:38;7838:5;7806:38;:::i;:::-;7860:70;7923:6;7918:3;7860:70;:::i;:::-;7853:77;;7939:52;7984:6;7979:3;7972:4;7965:5;7961:16;7939:52;:::i;:::-;8016:29;8038:6;8016:29;:::i;:::-;8011:3;8007:39;8000:46;;7782:270;7692:360;;;;:::o;8058:193::-;8176:68;8238:5;8176:68;:::i;:::-;8171:3;8164:81;8058:193;;:::o;8257:364::-;8345:3;8373:39;8406:5;8373:39;:::i;:::-;8428:71;8492:6;8487:3;8428:71;:::i;:::-;8421:78;;8508:52;8553:6;8548:3;8541:4;8534:5;8530:16;8508:52;:::i;:::-;8585:29;8607:6;8585:29;:::i;:::-;8580:3;8576:39;8569:46;;8349:272;8257:364;;;;:::o;8627:377::-;8733:3;8761:39;8794:5;8761:39;:::i;:::-;8816:89;8898:6;8893:3;8816:89;:::i;:::-;8809:96;;8914:52;8959:6;8954:3;8947:4;8940:5;8936:16;8914:52;:::i;:::-;8991:6;8986:3;8982:16;8975:23;;8737:267;8627:377;;;;:::o;9034:845::-;9137:3;9174:5;9168:12;9203:36;9229:9;9203:36;:::i;:::-;9255:89;9337:6;9332:3;9255:89;:::i;:::-;9248:96;;9375:1;9364:9;9360:17;9391:1;9386:137;;;;9537:1;9532:341;;;;9353:520;;9386:137;9470:4;9466:9;9455;9451:25;9446:3;9439:38;9506:6;9501:3;9497:16;9490:23;;9386:137;;9532:341;9599:38;9631:5;9599:38;:::i;:::-;9659:1;9673:154;9687:6;9684:1;9681:13;9673:154;;;9761:7;9755:14;9751:1;9746:3;9742:11;9735:35;9811:1;9802:7;9798:15;9787:26;;9709:4;9706:1;9702:12;9697:17;;9673:154;;;9856:6;9851:3;9847:16;9840:23;;9539:334;;9353:520;;9141:738;;9034:845;;;;:::o;9885:366::-;10027:3;10048:67;10112:2;10107:3;10048:67;:::i;:::-;10041:74;;10124:93;10213:3;10124:93;:::i;:::-;10242:2;10237:3;10233:12;10226:19;;9885:366;;;:::o;10257:::-;10399:3;10420:67;10484:2;10479:3;10420:67;:::i;:::-;10413:74;;10496:93;10585:3;10496:93;:::i;:::-;10614:2;10609:3;10605:12;10598:19;;10257:366;;;:::o;10629:::-;10771:3;10792:67;10856:2;10851:3;10792:67;:::i;:::-;10785:74;;10868:93;10957:3;10868:93;:::i;:::-;10986:2;10981:3;10977:12;10970:19;;10629:366;;;:::o;11001:::-;11143:3;11164:67;11228:2;11223:3;11164:67;:::i;:::-;11157:74;;11240:93;11329:3;11240:93;:::i;:::-;11358:2;11353:3;11349:12;11342:19;;11001:366;;;:::o;11373:::-;11515:3;11536:67;11600:2;11595:3;11536:67;:::i;:::-;11529:74;;11612:93;11701:3;11612:93;:::i;:::-;11730:2;11725:3;11721:12;11714:19;;11373:366;;;:::o;11745:::-;11887:3;11908:67;11972:2;11967:3;11908:67;:::i;:::-;11901:74;;11984:93;12073:3;11984:93;:::i;:::-;12102:2;12097:3;12093:12;12086:19;;11745:366;;;:::o;12117:118::-;12204:24;12222:5;12204:24;:::i;:::-;12199:3;12192:37;12117:118;;:::o;12241:429::-;12418:3;12440:92;12528:3;12519:6;12440:92;:::i;:::-;12433:99;;12549:95;12640:3;12631:6;12549:95;:::i;:::-;12542:102;;12661:3;12654:10;;12241:429;;;;;:::o;12676:222::-;12769:4;12807:2;12796:9;12792:18;12784:26;;12820:71;12888:1;12877:9;12873:17;12864:6;12820:71;:::i;:::-;12676:222;;;;:::o;12904:640::-;13099:4;13137:3;13126:9;13122:19;13114:27;;13151:71;13219:1;13208:9;13204:17;13195:6;13151:71;:::i;:::-;13232:72;13300:2;13289:9;13285:18;13276:6;13232:72;:::i;:::-;13314;13382:2;13371:9;13367:18;13358:6;13314:72;:::i;:::-;13433:9;13427:4;13423:20;13418:2;13407:9;13403:18;13396:48;13461:76;13532:4;13523:6;13461:76;:::i;:::-;13453:84;;12904:640;;;;;;;:::o;13550:332::-;13671:4;13709:2;13698:9;13694:18;13686:26;;13722:71;13790:1;13779:9;13775:17;13766:6;13722:71;:::i;:::-;13803:72;13871:2;13860:9;13856:18;13847:6;13803:72;:::i;:::-;13550:332;;;;;:::o;13888:210::-;13975:4;14013:2;14002:9;13998:18;13990:26;;14026:65;14088:1;14077:9;14073:17;14064:6;14026:65;:::i;:::-;13888:210;;;;:::o;14104:284::-;14228:4;14266:2;14255:9;14251:18;14243:26;;14279:102;14378:1;14367:9;14363:17;14354:6;14279:102;:::i;:::-;14104:284;;;;:::o;14394:313::-;14507:4;14545:2;14534:9;14530:18;14522:26;;14594:9;14588:4;14584:20;14580:1;14569:9;14565:17;14558:47;14622:78;14695:4;14686:6;14622:78;:::i;:::-;14614:86;;14394:313;;;;:::o;14713:419::-;14879:4;14917:2;14906:9;14902:18;14894:26;;14966:9;14960:4;14956:20;14952:1;14941:9;14937:17;14930:47;14994:131;15120:4;14994:131;:::i;:::-;14986:139;;14713:419;;;:::o;15138:::-;15304:4;15342:2;15331:9;15327:18;15319:26;;15391:9;15385:4;15381:20;15377:1;15366:9;15362:17;15355:47;15419:131;15545:4;15419:131;:::i;:::-;15411:139;;15138:419;;;:::o;15563:::-;15729:4;15767:2;15756:9;15752:18;15744:26;;15816:9;15810:4;15806:20;15802:1;15791:9;15787:17;15780:47;15844:131;15970:4;15844:131;:::i;:::-;15836:139;;15563:419;;;:::o;15988:::-;16154:4;16192:2;16181:9;16177:18;16169:26;;16241:9;16235:4;16231:20;16227:1;16216:9;16212:17;16205:47;16269:131;16395:4;16269:131;:::i;:::-;16261:139;;15988:419;;;:::o;16413:::-;16579:4;16617:2;16606:9;16602:18;16594:26;;16666:9;16660:4;16656:20;16652:1;16641:9;16637:17;16630:47;16694:131;16820:4;16694:131;:::i;:::-;16686:139;;16413:419;;;:::o;16838:::-;17004:4;17042:2;17031:9;17027:18;17019:26;;17091:9;17085:4;17081:20;17077:1;17066:9;17062:17;17055:47;17119:131;17245:4;17119:131;:::i;:::-;17111:139;;16838:419;;;:::o;17263:222::-;17356:4;17394:2;17383:9;17379:18;17371:26;;17407:71;17475:1;17464:9;17460:17;17451:6;17407:71;:::i;:::-;17263:222;;;;:::o;17491:129::-;17525:6;17552:20;;:::i;:::-;17542:30;;17581:33;17609:4;17601:6;17581:33;:::i;:::-;17491:129;;;:::o;17626:75::-;17659:6;17692:2;17686:9;17676:19;;17626:75;:::o;17707:307::-;17768:4;17858:18;17850:6;17847:30;17844:56;;;17880:18;;:::i;:::-;17844:56;17918:29;17940:6;17918:29;:::i;:::-;17910:37;;18002:4;17996;17992:15;17984:23;;17707:307;;;:::o;18020:141::-;18069:4;18092:3;18084:11;;18115:3;18112:1;18105:14;18149:4;18146:1;18136:18;18128:26;;18020:141;;;:::o;18167:98::-;18218:6;18252:5;18246:12;18236:22;;18167:98;;;:::o;18271:99::-;18323:6;18357:5;18351:12;18341:22;;18271:99;;;:::o;18376:168::-;18459:11;18493:6;18488:3;18481:19;18533:4;18528:3;18524:14;18509:29;;18376:168;;;;:::o;18550:169::-;18634:11;18668:6;18663:3;18656:19;18708:4;18703:3;18699:14;18684:29;;18550:169;;;;:::o;18725:148::-;18827:11;18864:3;18849:18;;18725:148;;;;:::o;18879:305::-;18919:3;18938:20;18956:1;18938:20;:::i;:::-;18933:25;;18972:20;18990:1;18972:20;:::i;:::-;18967:25;;19126:1;19058:66;19054:74;19051:1;19048:81;19045:107;;;19132:18;;:::i;:::-;19045:107;19176:1;19173;19169:9;19162:16;;18879:305;;;;:::o;19190:185::-;19230:1;19247:20;19265:1;19247:20;:::i;:::-;19242:25;;19281:20;19299:1;19281:20;:::i;:::-;19276:25;;19320:1;19310:35;;19325:18;;:::i;:::-;19310:35;19367:1;19364;19360:9;19355:14;;19190:185;;;;:::o;19381:348::-;19421:7;19444:20;19462:1;19444:20;:::i;:::-;19439:25;;19478:20;19496:1;19478:20;:::i;:::-;19473:25;;19666:1;19598:66;19594:74;19591:1;19588:81;19583:1;19576:9;19569:17;19565:105;19562:131;;;19673:18;;:::i;:::-;19562:131;19721:1;19718;19714:9;19703:20;;19381:348;;;;:::o;19735:191::-;19775:4;19795:20;19813:1;19795:20;:::i;:::-;19790:25;;19829:20;19847:1;19829:20;:::i;:::-;19824:25;;19868:1;19865;19862:8;19859:34;;;19873:18;;:::i;:::-;19859:34;19918:1;19915;19911:9;19903:17;;19735:191;;;;:::o;19932:96::-;19969:7;19998:24;20016:5;19998:24;:::i;:::-;19987:35;;19932:96;;;:::o;20034:90::-;20068:7;20111:5;20104:13;20097:21;20086:32;;20034:90;;;:::o;20130:149::-;20166:7;20206:66;20199:5;20195:78;20184:89;;20130:149;;;:::o;20285:126::-;20322:7;20362:42;20355:5;20351:54;20340:65;;20285:126;;;:::o;20417:77::-;20454:7;20483:5;20472:16;;20417:77;;;:::o;20500:157::-;20581:9;20614:37;20645:5;20614:37;:::i;:::-;20601:50;;20500:157;;;:::o;20663:126::-;20713:9;20746:37;20777:5;20746:37;:::i;:::-;20733:50;;20663:126;;;:::o;20795:113::-;20845:9;20878:24;20896:5;20878:24;:::i;:::-;20865:37;;20795:113;;;:::o;20914:154::-;20998:6;20993:3;20988;20975:30;21060:1;21051:6;21046:3;21042:16;21035:27;20914:154;;;:::o;21074:307::-;21142:1;21152:113;21166:6;21163:1;21160:13;21152:113;;;21251:1;21246:3;21242:11;21236:18;21232:1;21227:3;21223:11;21216:39;21188:2;21185:1;21181:10;21176:15;;21152:113;;;21283:6;21280:1;21277:13;21274:101;;;21363:1;21354:6;21349:3;21345:16;21338:27;21274:101;21123:258;21074:307;;;:::o;21387:320::-;21431:6;21468:1;21462:4;21458:12;21448:22;;21515:1;21509:4;21505:12;21536:18;21526:81;;21592:4;21584:6;21580:17;21570:27;;21526:81;21654:2;21646:6;21643:14;21623:18;21620:38;21617:84;;;21673:18;;:::i;:::-;21617:84;21438:269;21387:320;;;:::o;21713:281::-;21796:27;21818:4;21796:27;:::i;:::-;21788:6;21784:40;21926:6;21914:10;21911:22;21890:18;21878:10;21875:34;21872:62;21869:88;;;21937:18;;:::i;:::-;21869:88;21977:10;21973:2;21966:22;21756:238;21713:281;;:::o;22000:233::-;22039:3;22062:24;22080:5;22062:24;:::i;:::-;22053:33;;22108:66;22101:5;22098:77;22095:103;;;22178:18;;:::i;:::-;22095:103;22225:1;22218:5;22214:13;22207:20;;22000:233;;;:::o;22239:176::-;22271:1;22288:20;22306:1;22288:20;:::i;:::-;22283:25;;22322:20;22340:1;22322:20;:::i;:::-;22317:25;;22361:1;22351:35;;22366:18;;:::i;:::-;22351:35;22407:1;22404;22400:9;22395:14;;22239:176;;;;:::o;22421:180::-;22469:77;22466:1;22459:88;22566:4;22563:1;22556:15;22590:4;22587:1;22580:15;22607:180;22655:77;22652:1;22645:88;22752:4;22749:1;22742:15;22776:4;22773:1;22766:15;22793:180;22841:77;22838:1;22831:88;22938:4;22935:1;22928:15;22962:4;22959:1;22952:15;22979:180;23027:77;23024:1;23017:88;23124:4;23121:1;23114:15;23148:4;23145:1;23138:15;23165:180;23213:77;23210:1;23203:88;23310:4;23307:1;23300:15;23334:4;23331:1;23324:15;23351:117;23460:1;23457;23450:12;23474:117;23583:1;23580;23573:12;23597:117;23706:1;23703;23696:12;23720:117;23829:1;23826;23819:12;23843:117;23952:1;23949;23942:12;23966:117;24075:1;24072;24065:12;24089:102;24130:6;24181:2;24177:7;24172:2;24165:5;24161:14;24157:28;24147:38;;24089:102;;;:::o;24197:225::-;24337:34;24333:1;24325:6;24321:14;24314:58;24406:8;24401:2;24393:6;24389:15;24382:33;24197:225;:::o;24428:178::-;24568:30;24564:1;24556:6;24552:14;24545:54;24428:178;:::o;24612:180::-;24752:32;24748:1;24740:6;24736:14;24729:56;24612:180;:::o;24798:182::-;24938:34;24934:1;24926:6;24922:14;24915:58;24798:182;:::o;24986:234::-;25126:34;25122:1;25114:6;25110:14;25103:58;25195:17;25190:2;25182:6;25178:15;25171:42;24986:234;:::o;25226:174::-;25366:26;25362:1;25354:6;25350:14;25343:50;25226:174;:::o;25406:122::-;25479:24;25497:5;25479:24;:::i;:::-;25472:5;25469:35;25459:63;;25518:1;25515;25508:12;25459:63;25406:122;:::o;25534:116::-;25604:21;25619:5;25604:21;:::i;:::-;25597:5;25594:32;25584:60;;25640:1;25637;25630:12;25584:60;25534:116;:::o;25656:120::-;25728:23;25745:5;25728:23;:::i;:::-;25721:5;25718:34;25708:62;;25766:1;25763;25756:12;25708:62;25656:120;:::o;25782:122::-;25855:24;25873:5;25855:24;:::i;:::-;25848:5;25845:35;25835:63;;25894:1;25891;25884:12;25835:63;25782:122;:::o
Swarm Source
ipfs://41fc91651827f370973a98bcda3eaf0f57d0ff1ddf68280a1c7fc5a1f1fcb904
Loading...
Loading
Loading...
Loading
[ 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.