ERC-721
Overview
Max Total Supply
605 LMC
Holders
76
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
5 LMCLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
LullabyMultiverseClub
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/interfaces/IERC20.sol"; import "@openzeppelin/contracts/utils/Context.sol"; import "@openzeppelin/contracts/token/common/ERC2981.sol"; import "@openzeppelin/contracts/interfaces/IERC2981.sol"; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import "erc721a/contracts/ERC721A.sol"; import "erc721a/contracts/extensions/ERC721AQueryable.sol"; import "operator-filter-registry/src/DefaultOperatorFilterer.sol"; error SaleNotActive(); error AddressNotWhitelisted(); error SoldOut(); error MaxPresalePerTransactionExceeded(); error MaxPerTransactionExceeded(); error MaxPresaleNumber(); error MaxMintNumber(); error ZeroBalance(); error IncorrectETHValueSent(); contract LullabyMultiverseClub is DefaultOperatorFilterer, ERC2981, ERC721AQueryable, Ownable, ReentrancyGuard { address private openSeaConduitAddress = 0x1E0049783F008A0085193E00003D00cd54003c71; uint256 public constant MAX_LMC_PER_WALLET_LIMIT = 10; uint256 public constant MAX_LMC_PER_TRANSACTION = 10; uint256 public constant MAX_LMC_PRESALE_PER_WALLET_LIMIT = 3; uint256 public constant MAX_LMC_PRESALE_PER_TRANSACTION = 3; uint256 public constant PRESALE_MINT_PRICE = 0.0069 ether; uint256 public constant MINT_PRICE = 0.0089 ether; using MerkleProof for bytes32[]; bytes32 public whitelistMerkleRoot; bool public preSaleActive; bool public publicSaleActive; bool private isOpenSeaConduitActive = true; uint256 public constant SUPPLY = 5555; string public baseURI; mapping(address => uint256) public presaleMintAmount; mapping(address => uint256) public mintAmount; constructor() ERC721A("LullabyMultiverseClub", "LMC") {} /* ADMIN FUNCTIONS */ function togglePublicSale() external onlyOwner { publicSaleActive = !publicSaleActive; } function togglePresale() external onlyOwner { preSaleActive = !preSaleActive; } function setOpenSeaConduitAddress(address _openSeaConduitAddress) external onlyOwner { openSeaConduitAddress = _openSeaConduitAddress; } function setIsOpenSeaConduitActive(bool _isOpenSeaConduitActive) external onlyOwner { isOpenSeaConduitActive = _isOpenSeaConduitActive; } function withdraw() external onlyOwner nonReentrant { uint256 balance = address(this).balance; if (balance == 0) { revert ZeroBalance(); } address owner = payable(msg.sender); (bool success, ) = owner.call{value: address(this).balance}(""); require(success, "Failed to Withdraw."); } function withdrawTokens(IERC20 token) external onlyOwner nonReentrant { uint256 balance = token.balanceOf(address(this)); token.transfer(msg.sender, balance); } function setBaseUri(string memory _uri) external onlyOwner { baseURI = _uri; } function setMerkleRoot(bytes32 root) external onlyOwner { whitelistMerkleRoot = root; } function adminMint(address wallet, uint256 count) external onlyOwner { if (SUPPLY < (totalSupply() + count)) { revert SoldOut(); } _mint(wallet, count); } /* END ADMIN FUNCTIONS */ function presaleMint(uint256 count, bytes32[] memory proof) public payable { if (!preSaleActive) { revert SaleNotActive(); } if (msg.value != PRESALE_MINT_PRICE * count) { revert IncorrectETHValueSent(); } if (SUPPLY < (totalSupply() + count)) { revert SoldOut(); } if (count > MAX_LMC_PRESALE_PER_TRANSACTION) { revert MaxPresalePerTransactionExceeded(); } if (!_verify(_leaf(msg.sender), whitelistMerkleRoot, proof)) { revert AddressNotWhitelisted(); } if ( presaleMintAmount[msg.sender] + count > MAX_LMC_PRESALE_PER_WALLET_LIMIT ) { revert MaxPresaleNumber(); } presaleMintAmount[msg.sender] += count; _mint(msg.sender, count); } function mint(uint256 count) public payable nonReentrant { if (!publicSaleActive) { revert SaleNotActive(); } if (SUPPLY < (totalSupply() + count)) { revert SoldOut(); } if (msg.value != MINT_PRICE * count) { revert IncorrectETHValueSent(); } if (count > MAX_LMC_PER_TRANSACTION) { revert MaxPerTransactionExceeded(); } if (mintAmount[msg.sender] + count > MAX_LMC_PER_WALLET_LIMIT) { revert MaxMintNumber(); } mintAmount[msg.sender] += count; _mint(msg.sender, count); } function _leaf(address account) internal pure returns (bytes32) { return keccak256(bytes.concat(keccak256(abi.encode(account)))); } function _verify( bytes32 leaf, bytes32 root, bytes32[] memory proof ) internal pure returns (bool) { return MerkleProof.verify(proof, root, leaf); } function _baseURI() internal view virtual override returns (string memory) { return baseURI; } function setApprovalForAll( address operator, bool approved ) public override(ERC721A, IERC721A) onlyAllowedOperatorApproval(operator) { super.setApprovalForAll(operator, approved); } function approve( address operator, uint256 tokenId ) public payable override(ERC721A, IERC721A) onlyAllowedOperatorApproval(operator) { super.approve(operator, tokenId); } /** * @dev Override isApprovedForAll to allowlist user's OpenSea proxy accounts to enable gas-less listings. */ function isApprovedForAll(address owner, address operator) public view override(ERC721A, IERC721A) returns (bool) { if ( isOpenSeaConduitActive && address(openSeaConduitAddress) == operator ) { return true; } return super.isApprovedForAll(owner, operator); } function transferFrom( address from, address to, uint256 tokenId ) public payable override(ERC721A, IERC721A) onlyAllowedOperator(from) { super.transferFrom(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId ) public payable override(ERC721A, IERC721A) onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public payable override(ERC721A, IERC721A) onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId, data); } function supportsInterface( bytes4 interfaceId ) public view virtual override(ERC721A, IERC721A, ERC2981) returns (bool) { return ERC721A.supportsInterface(interfaceId) || ERC2981.supportsInterface(interfaceId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { 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); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165.sol"; /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/common/ERC2981.sol) pragma solidity ^0.8.0; import "../../interfaces/IERC2981.sol"; import "../../utils/introspection/ERC165.sol"; /** * @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]; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // 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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.2) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} * * _Available since v4.7._ */ function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} * * _Available since v4.7._ */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * _Available since v4.7._ */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { require(proofPos == proofLen, "MerkleProof: invalid multiproof"); unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { require(proofPos == proofLen, "MerkleProof: invalid multiproof"); unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @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; } }
// SPDX-License-Identifier: MIT // 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); }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; import './IERC721A.sol'; /** * @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) } } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; import './IERC721AQueryable.sol'; import '../ERC721A.sol'; /** * @title ERC721AQueryable. * * @dev ERC721A subclass with convenience query functions. */ abstract contract ERC721AQueryable is ERC721A, IERC721AQueryable { /** * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting. * * If the `tokenId` is out of bounds: * * - `addr = address(0)` * - `startTimestamp = 0` * - `burned = false` * - `extraData = 0` * * If the `tokenId` is burned: * * - `addr = <Address of owner before token was burned>` * - `startTimestamp = <Timestamp when token was burned>` * - `burned = true` * - `extraData = <Extra data when token was burned>` * * Otherwise: * * - `addr = <Address of owner>` * - `startTimestamp = <Timestamp of start of ownership>` * - `burned = false` * - `extraData = <Extra data at start of ownership>` */ function explicitOwnershipOf(uint256 tokenId) public view virtual override returns (TokenOwnership memory) { TokenOwnership memory ownership; if (tokenId < _startTokenId() || tokenId >= _nextTokenId()) { return ownership; } ownership = _ownershipAt(tokenId); if (ownership.burned) { return ownership; } return _ownershipOf(tokenId); } /** * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order. * See {ERC721AQueryable-explicitOwnershipOf} */ function explicitOwnershipsOf(uint256[] calldata tokenIds) external view virtual override returns (TokenOwnership[] memory) { unchecked { uint256 tokenIdsLength = tokenIds.length; TokenOwnership[] memory ownerships = new TokenOwnership[](tokenIdsLength); for (uint256 i; i != tokenIdsLength; ++i) { ownerships[i] = explicitOwnershipOf(tokenIds[i]); } return ownerships; } } /** * @dev Returns an array of token IDs owned by `owner`, * in the range [`start`, `stop`) * (i.e. `start <= tokenId < stop`). * * This function allows for tokens to be queried if the collection * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}. * * Requirements: * * - `start < stop` */ function tokensOfOwnerIn( address owner, uint256 start, uint256 stop ) external view virtual override returns (uint256[] memory) { unchecked { if (start >= stop) revert InvalidQueryRange(); uint256 tokenIdsIdx; uint256 stopLimit = _nextTokenId(); // Set `start = max(start, _startTokenId())`. if (start < _startTokenId()) { start = _startTokenId(); } // Set `stop = min(stop, stopLimit)`. if (stop > stopLimit) { stop = stopLimit; } uint256 tokenIdsMaxLength = balanceOf(owner); // Set `tokenIdsMaxLength = min(balanceOf(owner), stop - start)`, // to cater for cases where `balanceOf(owner)` is too big. if (start < stop) { uint256 rangeLength = stop - start; if (rangeLength < tokenIdsMaxLength) { tokenIdsMaxLength = rangeLength; } } else { tokenIdsMaxLength = 0; } uint256[] memory tokenIds = new uint256[](tokenIdsMaxLength); if (tokenIdsMaxLength == 0) { return tokenIds; } // We need to call `explicitOwnershipOf(start)`, // because the slot at `start` may not be initialized. TokenOwnership memory ownership = explicitOwnershipOf(start); address currOwnershipAddr; // If the starting slot exists (i.e. not burned), initialize `currOwnershipAddr`. // `ownership.address` will not be zero, as `start` is clamped to the valid token ID range. if (!ownership.burned) { currOwnershipAddr = ownership.addr; } for (uint256 i = start; i != stop && tokenIdsIdx != tokenIdsMaxLength; ++i) { ownership = _ownershipAt(i); if (ownership.burned) { continue; } if (ownership.addr != address(0)) { currOwnershipAddr = ownership.addr; } if (currOwnershipAddr == owner) { tokenIds[tokenIdsIdx++] = i; } } // Downsize the array to fit. assembly { mstore(tokenIds, tokenIdsIdx) } return tokenIds; } } /** * @dev Returns an array of token IDs owned by `owner`. * * This function scans the ownership mapping and is O(`totalSupply`) in complexity. * It is meant to be called off-chain. * * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into * multiple smaller scans if the collection is large enough to cause * an out-of-gas error (10K collections should be fine). */ function tokensOfOwner(address owner) external view virtual override returns (uint256[] memory) { unchecked { uint256 tokenIdsIdx; address currOwnershipAddr; uint256 tokenIdsLength = balanceOf(owner); uint256[] memory tokenIds = new uint256[](tokenIdsLength); TokenOwnership memory ownership; for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) { ownership = _ownershipAt(i); if (ownership.burned) { continue; } if (ownership.addr != address(0)) { currOwnershipAddr = ownership.addr; } if (currOwnershipAddr == owner) { tokenIds[tokenIdsIdx++] = i; } } return tokenIds; } } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; import '../IERC721A.sol'; /** * @dev Interface of ERC721AQueryable. */ interface IERC721AQueryable is IERC721A { /** * Invalid query range (`start` >= `stop`). */ error InvalidQueryRange(); /** * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting. * * If the `tokenId` is out of bounds: * * - `addr = address(0)` * - `startTimestamp = 0` * - `burned = false` * - `extraData = 0` * * If the `tokenId` is burned: * * - `addr = <Address of owner before token was burned>` * - `startTimestamp = <Timestamp when token was burned>` * - `burned = true` * - `extraData = <Extra data when token was burned>` * * Otherwise: * * - `addr = <Address of owner>` * - `startTimestamp = <Timestamp of start of ownership>` * - `burned = false` * - `extraData = <Extra data at start of ownership>` */ function explicitOwnershipOf(uint256 tokenId) external view returns (TokenOwnership memory); /** * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order. * See {ERC721AQueryable-explicitOwnershipOf} */ function explicitOwnershipsOf(uint256[] memory tokenIds) external view returns (TokenOwnership[] memory); /** * @dev Returns an array of token IDs owned by `owner`, * in the range [`start`, `stop`) * (i.e. `start <= tokenId < stop`). * * This function allows for tokens to be queried if the collection * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}. * * Requirements: * * - `start < stop` */ function tokensOfOwnerIn( address owner, uint256 start, uint256 stop ) external view returns (uint256[] memory); /** * @dev Returns an array of token IDs owned by `owner`. * * This function scans the ownership mapping and is O(`totalSupply`) in complexity. * It is meant to be called off-chain. * * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into * multiple smaller scans if the collection is large enough to cause * an out-of-gas error (10K collections should be fine). */ function tokensOfOwner(address owner) external view returns (uint256[] memory); }
// SPDX-License-Identifier: MIT // 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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {OperatorFilterer} from "./OperatorFilterer.sol"; import {CANONICAL_CORI_SUBSCRIPTION} from "./lib/Constants.sol"; /** * @title DefaultOperatorFilterer * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription. * @dev Please note that if your token contract does not provide an owner with EIP-173, it must provide * administration methods on the contract itself to interact with the registry otherwise the subscription * will be locked to the options set during construction. */ abstract contract DefaultOperatorFilterer is OperatorFilterer { /// @dev The constructor that is called when the contract is being deployed. constructor() OperatorFilterer(CANONICAL_CORI_SUBSCRIPTION, true) {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IOperatorFilterRegistry { /** * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns * true if supplied registrant address is not registered. */ function isOperatorAllowed(address registrant, address operator) external view returns (bool); /** * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner. */ function register(address registrant) external; /** * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes. */ function registerAndSubscribe(address registrant, address subscription) external; /** * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another * address without subscribing. */ function registerAndCopyEntries(address registrant, address registrantToCopy) external; /** * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner. * Note that this does not remove any filtered addresses or codeHashes. * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes. */ function unregister(address addr) external; /** * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered. */ function updateOperator(address registrant, address operator, bool filtered) external; /** * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates. */ function updateOperators(address registrant, address[] calldata operators, bool filtered) external; /** * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered. */ function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external; /** * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates. */ function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external; /** * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous * subscription if present. * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case, * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be * used. */ function subscribe(address registrant, address registrantToSubscribe) external; /** * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes. */ function unsubscribe(address registrant, bool copyExistingEntries) external; /** * @notice Get the subscription address of a given registrant, if any. */ function subscriptionOf(address addr) external returns (address registrant); /** * @notice Get the set of addresses subscribed to a given registrant. * Note that order is not guaranteed as updates are made. */ function subscribers(address registrant) external returns (address[] memory); /** * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant. * Note that order is not guaranteed as updates are made. */ function subscriberAt(address registrant, uint256 index) external returns (address); /** * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr. */ function copyEntriesOf(address registrant, address registrantToCopy) external; /** * @notice Returns true if operator is filtered by a given address or its subscription. */ function isOperatorFiltered(address registrant, address operator) external returns (bool); /** * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription. */ function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); /** * @notice Returns true if a codeHash is filtered by a given address or its subscription. */ function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); /** * @notice Returns a list of filtered operators for a given address or its subscription. */ function filteredOperators(address addr) external returns (address[] memory); /** * @notice Returns the set of filtered codeHashes for a given address or its subscription. * Note that order is not guaranteed as updates are made. */ function filteredCodeHashes(address addr) external returns (bytes32[] memory); /** * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or * its subscription. * Note that order is not guaranteed as updates are made. */ function filteredOperatorAt(address registrant, uint256 index) external returns (address); /** * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or * its subscription. * Note that order is not guaranteed as updates are made. */ function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); /** * @notice Returns true if an address has registered */ function isRegistered(address addr) external returns (bool); /** * @dev Convenience method to compute the code hash of an arbitrary contract */ function codeHashOf(address addr) external returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E; address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol"; import {CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS} from "./lib/Constants.sol"; /** * @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. * Please note that if your token contract does not provide an owner with EIP-173, it must provide * administration methods on the contract itself to interact with the registry otherwise the subscription * will be locked to the options set during construction. */ abstract contract OperatorFilterer { /// @dev Emitted when an operator is not allowed. error OperatorNotAllowed(address operator); IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY = IOperatorFilterRegistry(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS); /// @dev The constructor that is called when the contract is being deployed. 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)); } } } } /** * @dev A helper function to check if an operator is allowed. */ 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); } _; } /** * @dev A helper function to check if an operator approval is allowed. */ modifier onlyAllowedOperatorApproval(address operator) virtual { _checkFilterOperator(operator); _; } /** * @dev A helper function to check if an operator is allowed. */ 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) { // under normal circumstances, this function will revert rather than return false, but inheriting contracts // may specify their own OperatorFilterRegistry implementations, which may behave differently if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) { revert OperatorNotAllowed(operator); } } } }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressNotWhitelisted","type":"error"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"IncorrectETHValueSent","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MaxMintNumber","type":"error"},{"inputs":[],"name":"MaxPerTransactionExceeded","type":"error"},{"inputs":[],"name":"MaxPresaleNumber","type":"error"},{"inputs":[],"name":"MaxPresalePerTransactionExceeded","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":"SaleNotActive","type":"error"},{"inputs":[],"name":"SoldOut","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"},{"inputs":[],"name":"ZeroBalance","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_LMC_PER_TRANSACTION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_LMC_PER_WALLET_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_LMC_PRESALE_PER_TRANSACTION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_LMC_PRESALE_PER_WALLET_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_PRICE","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":"PRESALE_MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"adminMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":"count","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"preSaleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"presaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"presaleMintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSaleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isOpenSeaConduitActive","type":"bool"}],"name":"setIsOpenSeaConduitActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_openSeaConduitAddress","type":"address"}],"name":"setOpenSeaConduitAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"togglePresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"togglePublicSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"whitelistMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052731e0049783f008a0085193e00003d00cd54003c71600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600e60026101000a81548160ff0219169083151502179055503480156200008157600080fd5b506040518060400160405280601581526020017f4c756c6c6162794d756c74697665727365436c756200000000000000000000008152506040518060400160405280600381526020017f4c4d430000000000000000000000000000000000000000000000000000000000815250733cc6cdda760b79bafa08df41ecfa224f810dceb6600160006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115620002fa578015620001c0576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b8152600401620001869291906200047e565b600060405180830381600087803b158015620001a157600080fd5b505af1158015620001b6573d6000803e3d6000fd5b50505050620002f9565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146200027a576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b8152600401620002409291906200047e565b600060405180830381600087803b1580156200025b57600080fd5b505af115801562000270573d6000803e3d6000fd5b50505050620002f8565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b8152600401620002c39190620004ab565b600060405180830381600087803b158015620002de57600080fd5b505af1158015620002f3573d6000803e3d6000fd5b505050505b5b5b505081600490816200030d919062000742565b5080600590816200031f919062000742565b50620003306200036660201b60201c565b6002819055505050620003586200034c6200036b60201b60201c565b6200037360201b60201c565b6001600b8190555062000829565b600090565b600033905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620004668262000439565b9050919050565b620004788162000459565b82525050565b60006040820190506200049560008301856200046d565b620004a460208301846200046d565b9392505050565b6000602082019050620004c260008301846200046d565b92915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200054a57607f821691505b60208210810362000560576200055f62000502565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620005ca7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200058b565b620005d686836200058b565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620006236200061d6200061784620005ee565b620005f8565b620005ee565b9050919050565b6000819050919050565b6200063f8362000602565b620006576200064e826200062a565b84845462000598565b825550505050565b600090565b6200066e6200065f565b6200067b81848462000634565b505050565b5b81811015620006a3576200069760008262000664565b60018101905062000681565b5050565b601f821115620006f257620006bc8162000566565b620006c7846200057b565b81016020851015620006d7578190505b620006ef620006e6856200057b565b83018262000680565b50505b505050565b600082821c905092915050565b60006200071760001984600802620006f7565b1980831691505092915050565b600062000732838362000704565b9150826002028217905092915050565b6200074d82620004c8565b67ffffffffffffffff811115620007695762000768620004d3565b5b62000775825462000531565b62000782828285620006a7565b600060209050601f831160018114620007ba5760008415620007a5578287015190505b620007b1858262000724565b86555062000821565b601f198416620007ca8662000566565b60005b82811015620007f457848901518255600182019150602085019450602081019050620007cd565b8683101562000814578489015162000810601f89168262000704565b8355505b6001600288020188555050505b505050505050565b61497d80620008396000396000f3fe6080604052600436106102885760003560e01c8063715018a61161015a578063ba3bd421116100c1578063c87b56dd1161007a578063c87b56dd146109a4578063e222c7f9146109e1578063e3e1e8ef146109f8578063e58306f914610a14578063e985e9c514610a3d578063f2fde38b14610a7a57610288565b8063ba3bd42114610890578063bc8893b4146108bb578063c002d23d146108e6578063c23dc68f14610911578063c50497ae1461094e578063c873b8a01461097957610288565b806399a2557a1161011357806399a2557a1461079e578063a0712d68146107db578063a0bcfc7f146107f7578063a22cb46514610820578063aa98e0c614610849578063b88d4fde1461087457610288565b8063715018a6146106a05780637cb64759146106b757806384494708146106e05780638462151c1461070b5780638da5cb5b1461074857806395d89b411461077357610288565b80633ccfd60b116101fe57806353714f69116101b757806353714f69146105585780635bbb2177146105955780636352211e146105d25780636c0360eb1461060f578063707a561c1461063a57806370a082311461066357610288565b80633ccfd60b1461047d57806341f434341461049457806342842e0e146104bf57806348a826d5146104db57806349df728c146105065780635232ac351461052f57610288565b80630d6fc6c3116102505780630d6fc6c31461038b57806318160ddd146103b657806323b872dd146103e15780632a234e57146103fd5780632a55205a14610428578063343937431461046657610288565b806301ffc9a71461028d578063055d822c146102ca57806306fdde0314610307578063081812fc14610332578063095ea7b31461036f575b600080fd5b34801561029957600080fd5b506102b460048036038101906102af919061337b565b610aa3565b6040516102c191906133c3565b60405180910390f35b3480156102d657600080fd5b506102f160048036038101906102ec919061343c565b610ac5565b6040516102fe9190613482565b60405180910390f35b34801561031357600080fd5b5061031c610add565b604051610329919061352d565b60405180910390f35b34801561033e57600080fd5b506103596004803603810190610354919061357b565b610b6f565b60405161036691906135b7565b60405180910390f35b610389600480360381019061038491906135d2565b610bee565b005b34801561039757600080fd5b506103a0610c07565b6040516103ad9190613482565b60405180910390f35b3480156103c257600080fd5b506103cb610c0c565b6040516103d89190613482565b60405180910390f35b6103fb60048036038101906103f69190613612565b610c23565b005b34801561040957600080fd5b50610412610c72565b60405161041f9190613482565b60405180910390f35b34801561043457600080fd5b5061044f600480360381019061044a9190613665565b610c7d565b60405161045d9291906136a5565b60405180910390f35b34801561047257600080fd5b5061047b610e67565b005b34801561048957600080fd5b50610492610e9b565b005b3480156104a057600080fd5b506104a9610fa8565b6040516104b6919061372d565b60405180910390f35b6104d960048036038101906104d49190613612565b610fba565b005b3480156104e757600080fd5b506104f0611009565b6040516104fd9190613482565b60405180910390f35b34801561051257600080fd5b5061052d60048036038101906105289190613786565b61100e565b005b34801561053b57600080fd5b50610556600480360381019061055191906137df565b611127565b005b34801561056457600080fd5b5061057f600480360381019061057a919061343c565b61114c565b60405161058c9190613482565b60405180910390f35b3480156105a157600080fd5b506105bc60048036038101906105b79190613871565b611164565b6040516105c99190613a21565b60405180910390f35b3480156105de57600080fd5b506105f960048036038101906105f4919061357b565b611227565b60405161060691906135b7565b60405180910390f35b34801561061b57600080fd5b50610624611239565b604051610631919061352d565b60405180910390f35b34801561064657600080fd5b50610661600480360381019061065c919061343c565b6112c7565b005b34801561066f57600080fd5b5061068a6004803603810190610685919061343c565b611313565b6040516106979190613482565b60405180910390f35b3480156106ac57600080fd5b506106b56113cb565b005b3480156106c357600080fd5b506106de60048036038101906106d99190613a79565b6113df565b005b3480156106ec57600080fd5b506106f56113f1565b60405161070291906133c3565b60405180910390f35b34801561071757600080fd5b50610732600480360381019061072d919061343c565b611404565b60405161073f9190613b64565b60405180910390f35b34801561075457600080fd5b5061075d611547565b60405161076a91906135b7565b60405180910390f35b34801561077f57600080fd5b50610788611571565b604051610795919061352d565b60405180910390f35b3480156107aa57600080fd5b506107c560048036038101906107c09190613b86565b611603565b6040516107d29190613b64565b60405180910390f35b6107f560048036038101906107f0919061357b565b61180f565b005b34801561080357600080fd5b5061081e60048036038101906108199190613d09565b611a21565b005b34801561082c57600080fd5b5061084760048036038101906108429190613d52565b611a3c565b005b34801561085557600080fd5b5061085e611a55565b60405161086b9190613da1565b60405180910390f35b61088e60048036038101906108899190613e5d565b611a5b565b005b34801561089c57600080fd5b506108a5611aac565b6040516108b29190613482565b60405180910390f35b3480156108c757600080fd5b506108d0611ab1565b6040516108dd91906133c3565b60405180910390f35b3480156108f257600080fd5b506108fb611ac4565b6040516109089190613482565b60405180910390f35b34801561091d57600080fd5b506109386004803603810190610933919061357b565b611acf565b6040516109459190613f35565b60405180910390f35b34801561095a57600080fd5b50610963611b39565b6040516109709190613482565b60405180910390f35b34801561098557600080fd5b5061098e611b3f565b60405161099b9190613482565b60405180910390f35b3480156109b057600080fd5b506109cb60048036038101906109c6919061357b565b611b44565b6040516109d8919061352d565b60405180910390f35b3480156109ed57600080fd5b506109f6611be2565b005b610a126004803603810190610a0d9190614013565b611c16565b005b348015610a2057600080fd5b50610a3b6004803603810190610a3691906135d2565b611e64565b005b348015610a4957600080fd5b50610a646004803603810190610a5f919061406f565b611ec8565b604051610a7191906133c3565b60405180910390f35b348015610a8657600080fd5b50610aa16004803603810190610a9c919061343c565b611f54565b005b6000610aae82611fd7565b80610abe5750610abd82612069565b5b9050919050565b60116020528060005260406000206000915090505481565b606060048054610aec906140de565b80601f0160208091040260200160405190810160405280929190818152602001828054610b18906140de565b8015610b655780601f10610b3a57610100808354040283529160200191610b65565b820191906000526020600020905b815481529060010190602001808311610b4857829003601f168201915b5050505050905090565b6000610b7a826120e3565b610bb0576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610bf881612142565b610c02838361223f565b505050565b600381565b6000610c16612383565b6003546002540303905090565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c6157610c6033612142565b5b610c6c848484612388565b50505050565b6618838370f3400081565b6000806000600160008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610e125760006040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000610e1c6126aa565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610e48919061413e565b610e5291906141af565b90508160000151819350935050509250929050565b610e6f6126b4565b600e60009054906101000a900460ff1615600e60006101000a81548160ff021916908315150217905550565b610ea36126b4565b610eab612732565b600047905060008103610eea576040517f669567ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600033905060008173ffffffffffffffffffffffffffffffffffffffff1647604051610f1590614211565b60006040518083038185875af1925050503d8060008114610f52576040519150601f19603f3d011682016040523d82523d6000602084013e610f57565b606091505b5050905080610f9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9290614272565b60405180910390fd5b505050610fa6612781565b565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ff857610ff733612142565b5b61100384848461278b565b50505050565b600381565b6110166126b4565b61101e612732565b60008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161105991906135b7565b602060405180830381865afa158015611076573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109a91906142a7565b90508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b81526004016110d79291906136a5565b6020604051808303816000875af11580156110f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061111a91906142e9565b5050611124612781565b50565b61112f6126b4565b80600e60026101000a81548160ff02191690831515021790555050565b60106020528060005260406000206000915090505481565b6060600083839050905060008167ffffffffffffffff81111561118a57611189613bde565b5b6040519080825280602002602001820160405280156111c357816020015b6111b06132c0565b8152602001906001900390816111a85790505b50905060005b82811461121b576111f28686838181106111e6576111e5614316565b5b90506020020135611acf565b82828151811061120557611204614316565b5b60200260200101819052508060010190506111c9565b50809250505092915050565b6000611232826127ab565b9050919050565b600f8054611246906140de565b80601f0160208091040260200160405190810160405280929190818152602001828054611272906140de565b80156112bf5780601f10611294576101008083540402835291602001916112bf565b820191906000526020600020905b8154815290600101906020018083116112a257829003601f168201915b505050505081565b6112cf6126b4565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361137a576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6113d36126b4565b6113dd6000612877565b565b6113e76126b4565b80600d8190555050565b600e60009054906101000a900460ff1681565b6060600080600061141485611313565b905060008167ffffffffffffffff81111561143257611431613bde565b5b6040519080825280602002602001820160405280156114605781602001602082028036833780820191505090505b50905061146b6132c0565b6000611475612383565b90505b838614611539576114888161293d565b9150816040015161152e57600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16146114d357816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361152d57808387806001019850815181106115205761151f614316565b5b6020026020010181815250505b5b806001019050611478565b508195505050505050919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060058054611580906140de565b80601f01602080910402602001604051908101604052809291908181526020018280546115ac906140de565b80156115f95780601f106115ce576101008083540402835291602001916115f9565b820191906000526020600020905b8154815290600101906020018083116115dc57829003601f168201915b5050505050905090565b606081831061163e576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080611649612968565b9050611653612383565b85101561166557611662612383565b94505b80841115611671578093505b600061167c87611313565b90508486101561169f576000868603905081811015611699578091505b506116a4565b600090505b60008167ffffffffffffffff8111156116c0576116bf613bde565b5b6040519080825280602002602001820160405280156116ee5781602001602082028036833780820191505090505b509050600082036117055780945050505050611808565b600061171088611acf565b90506000816040015161172557816000015190505b60008990505b88811415801561173b5750848714155b156117fa576117498161293d565b925082604001516117ef57600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161461179457826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036117ee57808488806001019950815181106117e1576117e0614316565b5b6020026020010181815250505b5b80600101905061172b565b508583528296505050505050505b9392505050565b611817612732565b600e60019054906101000a900460ff1661185d576040517fb7b2409700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80611866610c0c565b6118709190614345565b6115b310156118ab576040517f52df9fe500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80661f9e80ba8040006118be919061413e565b34146118f6576040517f0c9ccdcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a811115611931576040517f9782cdff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a81601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461197e9190614345565b11156119b6576040517f7dc8c67100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a059190614345565b92505081905550611a163382612972565b611a1e612781565b50565b611a296126b4565b80600f9081611a38919061451b565b5050565b81611a4681612142565b611a508383612b2e565b505050565b600d5481565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611a9957611a9833612142565b5b611aa585858585612c39565b5050505050565b600a81565b600e60019054906101000a900460ff1681565b661f9e80ba80400081565b611ad76132c0565b611adf6132c0565b611ae7612383565b831080611afb5750611af7612968565b8310155b15611b095780915050611b34565b611b128361293d565b9050806040015115611b275780915050611b34565b611b3083612cac565b9150505b919050565b6115b381565b600a81565b6060611b4f826120e3565b611b85576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611b8f612ccc565b90506000815103611baf5760405180602001604052806000815250611bda565b80611bb984612d5e565b604051602001611bca929190614629565b6040516020818303038152906040525b915050919050565b611bea6126b4565b600e60019054906101000a900460ff1615600e60016101000a81548160ff021916908315150217905550565b600e60009054906101000a900460ff16611c5c576040517fb7b2409700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816618838370f34000611c6f919061413e565b3414611ca7576040517f0c9ccdcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81611cb0610c0c565b611cba9190614345565b6115b31015611cf5576040517f52df9fe500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6003821115611d30576040517fd4f7dad500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d45611d3c33612dae565b600d5483612e04565b611d7b576040517fad7acb4700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600382601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611dc89190614345565b1115611e00576040517f12ca1abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611e4f9190614345565b92505081905550611e603383612972565b5050565b611e6c6126b4565b80611e75610c0c565b611e7f9190614345565b6115b31015611eba576040517f52df9fe500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ec48282612972565b5050565b6000600e60029054906101000a900460ff168015611f3357508173ffffffffffffffffffffffffffffffffffffffff16600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b15611f415760019050611f4e565b611f4b8383612e1a565b90505b92915050565b611f5c6126b4565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611fcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fc2906146bf565b60405180910390fd5b611fd481612877565b50565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061203257506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806120625750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806120dc57506120db82612eae565b5b9050919050565b6000816120ee612383565b111580156120fd575060025482105b801561213b575060007c0100000000000000000000000000000000000000000000000000000000600660008581526020019081526020016000205416145b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111561223c576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016121b99291906146df565b602060405180830381865afa1580156121d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121fa91906142e9565b61223b57806040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161223291906135b7565b60405180910390fd5b5b50565b600061224a82611227565b90508073ffffffffffffffffffffffffffffffffffffffff1661226b612f18565b73ffffffffffffffffffffffffffffffffffffffff16146122ce5761229781612292612f18565b611ec8565b6122cd576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826008600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600090565b6000612393826127ab565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146123fa576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061240684612f20565b9150915061241c8187612417612f18565b612f47565b612468576124318661242c612f18565b611ec8565b612467576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036124ce576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124db8686866001612f8b565b80156124e657600082555b600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055506125b485612590888887612f91565b7c020000000000000000000000000000000000000000000000000000000017612fb9565b600660008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361263a5760006001850190506000600660008381526020019081526020016000205403612638576002548114612637578360066000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46126a28686866001612fe4565b505050505050565b6000612710905090565b6126bc612fea565b73ffffffffffffffffffffffffffffffffffffffff166126da611547565b73ffffffffffffffffffffffffffffffffffffffff1614612730576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161272790614754565b60405180910390fd5b565b6002600b5403612777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161276e906147c0565b60405180910390fd5b6002600b81905550565b6001600b81905550565b6127a683838360405180602001604052806000815250611a5b565b505050565b600080829050806127ba612383565b116128405760025481101561283f5760006006600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082160361283d575b60008103612833576006600083600190039350838152602001908152602001600020549050612809565b8092505050612872565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6129456132c0565b6129616006600084815260200190815260200160002054612ff2565b9050919050565b6000600254905090565b60006002549050600082036129b3576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129c06000848385612f8b565b600160406001901b178202600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612a3783612a286000866000612f91565b612a31856130a8565b17612fb9565b6006600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114612ad857808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612a9d565b5060008203612b13576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806002819055505050612b296000848385612fe4565b505050565b8060096000612b3b612f18565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612be8612f18565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612c2d91906133c3565b60405180910390a35050565b612c44848484610c23565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612ca657612c6f848484846130b8565b612ca5576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b612cb46132c0565b612cc5612cc0836127ab565b612ff2565b9050919050565b6060600f8054612cdb906140de565b80601f0160208091040260200160405190810160405280929190818152602001828054612d07906140de565b8015612d545780601f10612d2957610100808354040283529160200191612d54565b820191906000526020600020905b815481529060010190602001808311612d3757829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b600115612d9957600184039350600a81066030018453600a8104905080612d77575b50828103602084039350808452505050919050565b600081604051602001612dc191906135b7565b60405160208183030381529060405280519060200120604051602001612de79190614801565b604051602081830303815290604052805190602001209050919050565b6000612e11828486613208565b90509392505050565b6000600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b60008060006008600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8612fa886868461321f565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600033905090565b612ffa6132c0565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b60006001821460e11b9050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026130de612f18565b8786866040518563ffffffff1660e01b81526004016131009493929190614871565b6020604051808303816000875af192505050801561313c57506040513d601f19601f8201168201806040525081019061313991906148d2565b60015b6131b5573d806000811461316c576040519150601f19603f3d011682016040523d82523d6000602084013e613171565b606091505b5060008151036131ad576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6000826132158584613228565b1490509392505050565b60009392505050565b60008082905060005b84518110156132735761325e8286838151811061325157613250614316565b5b602002602001015161327e565b9150808061326b906148ff565b915050613231565b508091505092915050565b60008183106132965761329182846132a9565b6132a1565b6132a083836132a9565b5b905092915050565b600082600052816020526040600020905092915050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61335881613323565b811461336357600080fd5b50565b6000813590506133758161334f565b92915050565b60006020828403121561339157613390613319565b5b600061339f84828501613366565b91505092915050565b60008115159050919050565b6133bd816133a8565b82525050565b60006020820190506133d860008301846133b4565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613409826133de565b9050919050565b613419816133fe565b811461342457600080fd5b50565b60008135905061343681613410565b92915050565b60006020828403121561345257613451613319565b5b600061346084828501613427565b91505092915050565b6000819050919050565b61347c81613469565b82525050565b60006020820190506134976000830184613473565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156134d75780820151818401526020810190506134bc565b60008484015250505050565b6000601f19601f8301169050919050565b60006134ff8261349d565b61350981856134a8565b93506135198185602086016134b9565b613522816134e3565b840191505092915050565b6000602082019050818103600083015261354781846134f4565b905092915050565b61355881613469565b811461356357600080fd5b50565b6000813590506135758161354f565b92915050565b60006020828403121561359157613590613319565b5b600061359f84828501613566565b91505092915050565b6135b1816133fe565b82525050565b60006020820190506135cc60008301846135a8565b92915050565b600080604083850312156135e9576135e8613319565b5b60006135f785828601613427565b925050602061360885828601613566565b9150509250929050565b60008060006060848603121561362b5761362a613319565b5b600061363986828701613427565b935050602061364a86828701613427565b925050604061365b86828701613566565b9150509250925092565b6000806040838503121561367c5761367b613319565b5b600061368a85828601613566565b925050602061369b85828601613566565b9150509250929050565b60006040820190506136ba60008301856135a8565b6136c76020830184613473565b9392505050565b6000819050919050565b60006136f36136ee6136e9846133de565b6136ce565b6133de565b9050919050565b6000613705826136d8565b9050919050565b6000613717826136fa565b9050919050565b6137278161370c565b82525050565b6000602082019050613742600083018461371e565b92915050565b6000613753826133fe565b9050919050565b61376381613748565b811461376e57600080fd5b50565b6000813590506137808161375a565b92915050565b60006020828403121561379c5761379b613319565b5b60006137aa84828501613771565b91505092915050565b6137bc816133a8565b81146137c757600080fd5b50565b6000813590506137d9816137b3565b92915050565b6000602082840312156137f5576137f4613319565b5b6000613803848285016137ca565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126138315761383061380c565b5b8235905067ffffffffffffffff81111561384e5761384d613811565b5b60208301915083602082028301111561386a57613869613816565b5b9250929050565b6000806020838503121561388857613887613319565b5b600083013567ffffffffffffffff8111156138a6576138a561331e565b5b6138b28582860161381b565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6138f3816133fe565b82525050565b600067ffffffffffffffff82169050919050565b613916816138f9565b82525050565b613925816133a8565b82525050565b600062ffffff82169050919050565b6139438161392b565b82525050565b60808201600082015161395f60008501826138ea565b506020820151613972602085018261390d565b506040820151613985604085018261391c565b506060820151613998606085018261393a565b50505050565b60006139aa8383613949565b60808301905092915050565b6000602082019050919050565b60006139ce826138be565b6139d881856138c9565b93506139e3836138da565b8060005b83811015613a145781516139fb888261399e565b9750613a06836139b6565b9250506001810190506139e7565b5085935050505092915050565b60006020820190508181036000830152613a3b81846139c3565b905092915050565b6000819050919050565b613a5681613a43565b8114613a6157600080fd5b50565b600081359050613a7381613a4d565b92915050565b600060208284031215613a8f57613a8e613319565b5b6000613a9d84828501613a64565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613adb81613469565b82525050565b6000613aed8383613ad2565b60208301905092915050565b6000602082019050919050565b6000613b1182613aa6565b613b1b8185613ab1565b9350613b2683613ac2565b8060005b83811015613b57578151613b3e8882613ae1565b9750613b4983613af9565b925050600181019050613b2a565b5085935050505092915050565b60006020820190508181036000830152613b7e8184613b06565b905092915050565b600080600060608486031215613b9f57613b9e613319565b5b6000613bad86828701613427565b9350506020613bbe86828701613566565b9250506040613bcf86828701613566565b9150509250925092565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613c16826134e3565b810181811067ffffffffffffffff82111715613c3557613c34613bde565b5b80604052505050565b6000613c4861330f565b9050613c548282613c0d565b919050565b600067ffffffffffffffff821115613c7457613c73613bde565b5b613c7d826134e3565b9050602081019050919050565b82818337600083830152505050565b6000613cac613ca784613c59565b613c3e565b905082815260208101848484011115613cc857613cc7613bd9565b5b613cd3848285613c8a565b509392505050565b600082601f830112613cf057613cef61380c565b5b8135613d00848260208601613c99565b91505092915050565b600060208284031215613d1f57613d1e613319565b5b600082013567ffffffffffffffff811115613d3d57613d3c61331e565b5b613d4984828501613cdb565b91505092915050565b60008060408385031215613d6957613d68613319565b5b6000613d7785828601613427565b9250506020613d88858286016137ca565b9150509250929050565b613d9b81613a43565b82525050565b6000602082019050613db66000830184613d92565b92915050565b600067ffffffffffffffff821115613dd757613dd6613bde565b5b613de0826134e3565b9050602081019050919050565b6000613e00613dfb84613dbc565b613c3e565b905082815260208101848484011115613e1c57613e1b613bd9565b5b613e27848285613c8a565b509392505050565b600082601f830112613e4457613e4361380c565b5b8135613e54848260208601613ded565b91505092915050565b60008060008060808587031215613e7757613e76613319565b5b6000613e8587828801613427565b9450506020613e9687828801613427565b9350506040613ea787828801613566565b925050606085013567ffffffffffffffff811115613ec857613ec761331e565b5b613ed487828801613e2f565b91505092959194509250565b608082016000820151613ef660008501826138ea565b506020820151613f09602085018261390d565b506040820151613f1c604085018261391c565b506060820151613f2f606085018261393a565b50505050565b6000608082019050613f4a6000830184613ee0565b92915050565b600067ffffffffffffffff821115613f6b57613f6a613bde565b5b602082029050602081019050919050565b6000613f8f613f8a84613f50565b613c3e565b90508083825260208201905060208402830185811115613fb257613fb1613816565b5b835b81811015613fdb5780613fc78882613a64565b845260208401935050602081019050613fb4565b5050509392505050565b600082601f830112613ffa57613ff961380c565b5b813561400a848260208601613f7c565b91505092915050565b6000806040838503121561402a57614029613319565b5b600061403885828601613566565b925050602083013567ffffffffffffffff8111156140595761405861331e565b5b61406585828601613fe5565b9150509250929050565b6000806040838503121561408657614085613319565b5b600061409485828601613427565b92505060206140a585828601613427565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806140f657607f821691505b602082108103614109576141086140af565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061414982613469565b915061415483613469565b925082820261416281613469565b915082820484148315176141795761417861410f565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006141ba82613469565b91506141c583613469565b9250826141d5576141d4614180565b5b828204905092915050565b600081905092915050565b50565b60006141fb6000836141e0565b9150614206826141eb565b600082019050919050565b600061421c826141ee565b9150819050919050565b7f4661696c656420746f2057697468647261772e00000000000000000000000000600082015250565b600061425c6013836134a8565b915061426782614226565b602082019050919050565b6000602082019050818103600083015261428b8161424f565b9050919050565b6000815190506142a18161354f565b92915050565b6000602082840312156142bd576142bc613319565b5b60006142cb84828501614292565b91505092915050565b6000815190506142e3816137b3565b92915050565b6000602082840312156142ff576142fe613319565b5b600061430d848285016142d4565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061435082613469565b915061435b83613469565b92508282019050808211156143735761437261410f565b5b92915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026143db7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261439e565b6143e5868361439e565b95508019841693508086168417925050509392505050565b600061441861441361440e84613469565b6136ce565b613469565b9050919050565b6000819050919050565b614432836143fd565b61444661443e8261441f565b8484546143ab565b825550505050565b600090565b61445b61444e565b614466818484614429565b505050565b5b8181101561448a5761447f600082614453565b60018101905061446c565b5050565b601f8211156144cf576144a081614379565b6144a98461438e565b810160208510156144b8578190505b6144cc6144c48561438e565b83018261446b565b50505b505050565b600082821c905092915050565b60006144f2600019846008026144d4565b1980831691505092915050565b600061450b83836144e1565b9150826002028217905092915050565b6145248261349d565b67ffffffffffffffff81111561453d5761453c613bde565b5b61454782546140de565b61455282828561448e565b600060209050601f8311600181146145855760008415614573578287015190505b61457d85826144ff565b8655506145e5565b601f19841661459386614379565b60005b828110156145bb57848901518255600182019150602085019450602081019050614596565b868310156145d857848901516145d4601f8916826144e1565b8355505b6001600288020188555050505b505050505050565b600081905092915050565b60006146038261349d565b61460d81856145ed565b935061461d8185602086016134b9565b80840191505092915050565b600061463582856145f8565b915061464182846145f8565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006146a96026836134a8565b91506146b48261464d565b604082019050919050565b600060208201905081810360008301526146d88161469c565b9050919050565b60006040820190506146f460008301856135a8565b61470160208301846135a8565b9392505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061473e6020836134a8565b915061474982614708565b602082019050919050565b6000602082019050818103600083015261476d81614731565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006147aa601f836134a8565b91506147b582614774565b602082019050919050565b600060208201905081810360008301526147d98161479d565b9050919050565b6000819050919050565b6147fb6147f682613a43565b6147e0565b82525050565b600061480d82846147ea565b60208201915081905092915050565b600081519050919050565b600082825260208201905092915050565b60006148438261481c565b61484d8185614827565b935061485d8185602086016134b9565b614866816134e3565b840191505092915050565b600060808201905061488660008301876135a8565b61489360208301866135a8565b6148a06040830185613473565b81810360608301526148b28184614838565b905095945050505050565b6000815190506148cc8161334f565b92915050565b6000602082840312156148e8576148e7613319565b5b60006148f6848285016148bd565b91505092915050565b600061490a82613469565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361493c5761493b61410f565b5b60018201905091905056fea2646970667358221220af7e065803e72bc53afc7e2c2c1a3f58689227bd340a8ba7a02685a16761f24464736f6c63430008130033
Deployed Bytecode
0x6080604052600436106102885760003560e01c8063715018a61161015a578063ba3bd421116100c1578063c87b56dd1161007a578063c87b56dd146109a4578063e222c7f9146109e1578063e3e1e8ef146109f8578063e58306f914610a14578063e985e9c514610a3d578063f2fde38b14610a7a57610288565b8063ba3bd42114610890578063bc8893b4146108bb578063c002d23d146108e6578063c23dc68f14610911578063c50497ae1461094e578063c873b8a01461097957610288565b806399a2557a1161011357806399a2557a1461079e578063a0712d68146107db578063a0bcfc7f146107f7578063a22cb46514610820578063aa98e0c614610849578063b88d4fde1461087457610288565b8063715018a6146106a05780637cb64759146106b757806384494708146106e05780638462151c1461070b5780638da5cb5b1461074857806395d89b411461077357610288565b80633ccfd60b116101fe57806353714f69116101b757806353714f69146105585780635bbb2177146105955780636352211e146105d25780636c0360eb1461060f578063707a561c1461063a57806370a082311461066357610288565b80633ccfd60b1461047d57806341f434341461049457806342842e0e146104bf57806348a826d5146104db57806349df728c146105065780635232ac351461052f57610288565b80630d6fc6c3116102505780630d6fc6c31461038b57806318160ddd146103b657806323b872dd146103e15780632a234e57146103fd5780632a55205a14610428578063343937431461046657610288565b806301ffc9a71461028d578063055d822c146102ca57806306fdde0314610307578063081812fc14610332578063095ea7b31461036f575b600080fd5b34801561029957600080fd5b506102b460048036038101906102af919061337b565b610aa3565b6040516102c191906133c3565b60405180910390f35b3480156102d657600080fd5b506102f160048036038101906102ec919061343c565b610ac5565b6040516102fe9190613482565b60405180910390f35b34801561031357600080fd5b5061031c610add565b604051610329919061352d565b60405180910390f35b34801561033e57600080fd5b506103596004803603810190610354919061357b565b610b6f565b60405161036691906135b7565b60405180910390f35b610389600480360381019061038491906135d2565b610bee565b005b34801561039757600080fd5b506103a0610c07565b6040516103ad9190613482565b60405180910390f35b3480156103c257600080fd5b506103cb610c0c565b6040516103d89190613482565b60405180910390f35b6103fb60048036038101906103f69190613612565b610c23565b005b34801561040957600080fd5b50610412610c72565b60405161041f9190613482565b60405180910390f35b34801561043457600080fd5b5061044f600480360381019061044a9190613665565b610c7d565b60405161045d9291906136a5565b60405180910390f35b34801561047257600080fd5b5061047b610e67565b005b34801561048957600080fd5b50610492610e9b565b005b3480156104a057600080fd5b506104a9610fa8565b6040516104b6919061372d565b60405180910390f35b6104d960048036038101906104d49190613612565b610fba565b005b3480156104e757600080fd5b506104f0611009565b6040516104fd9190613482565b60405180910390f35b34801561051257600080fd5b5061052d60048036038101906105289190613786565b61100e565b005b34801561053b57600080fd5b50610556600480360381019061055191906137df565b611127565b005b34801561056457600080fd5b5061057f600480360381019061057a919061343c565b61114c565b60405161058c9190613482565b60405180910390f35b3480156105a157600080fd5b506105bc60048036038101906105b79190613871565b611164565b6040516105c99190613a21565b60405180910390f35b3480156105de57600080fd5b506105f960048036038101906105f4919061357b565b611227565b60405161060691906135b7565b60405180910390f35b34801561061b57600080fd5b50610624611239565b604051610631919061352d565b60405180910390f35b34801561064657600080fd5b50610661600480360381019061065c919061343c565b6112c7565b005b34801561066f57600080fd5b5061068a6004803603810190610685919061343c565b611313565b6040516106979190613482565b60405180910390f35b3480156106ac57600080fd5b506106b56113cb565b005b3480156106c357600080fd5b506106de60048036038101906106d99190613a79565b6113df565b005b3480156106ec57600080fd5b506106f56113f1565b60405161070291906133c3565b60405180910390f35b34801561071757600080fd5b50610732600480360381019061072d919061343c565b611404565b60405161073f9190613b64565b60405180910390f35b34801561075457600080fd5b5061075d611547565b60405161076a91906135b7565b60405180910390f35b34801561077f57600080fd5b50610788611571565b604051610795919061352d565b60405180910390f35b3480156107aa57600080fd5b506107c560048036038101906107c09190613b86565b611603565b6040516107d29190613b64565b60405180910390f35b6107f560048036038101906107f0919061357b565b61180f565b005b34801561080357600080fd5b5061081e60048036038101906108199190613d09565b611a21565b005b34801561082c57600080fd5b5061084760048036038101906108429190613d52565b611a3c565b005b34801561085557600080fd5b5061085e611a55565b60405161086b9190613da1565b60405180910390f35b61088e60048036038101906108899190613e5d565b611a5b565b005b34801561089c57600080fd5b506108a5611aac565b6040516108b29190613482565b60405180910390f35b3480156108c757600080fd5b506108d0611ab1565b6040516108dd91906133c3565b60405180910390f35b3480156108f257600080fd5b506108fb611ac4565b6040516109089190613482565b60405180910390f35b34801561091d57600080fd5b506109386004803603810190610933919061357b565b611acf565b6040516109459190613f35565b60405180910390f35b34801561095a57600080fd5b50610963611b39565b6040516109709190613482565b60405180910390f35b34801561098557600080fd5b5061098e611b3f565b60405161099b9190613482565b60405180910390f35b3480156109b057600080fd5b506109cb60048036038101906109c6919061357b565b611b44565b6040516109d8919061352d565b60405180910390f35b3480156109ed57600080fd5b506109f6611be2565b005b610a126004803603810190610a0d9190614013565b611c16565b005b348015610a2057600080fd5b50610a3b6004803603810190610a3691906135d2565b611e64565b005b348015610a4957600080fd5b50610a646004803603810190610a5f919061406f565b611ec8565b604051610a7191906133c3565b60405180910390f35b348015610a8657600080fd5b50610aa16004803603810190610a9c919061343c565b611f54565b005b6000610aae82611fd7565b80610abe5750610abd82612069565b5b9050919050565b60116020528060005260406000206000915090505481565b606060048054610aec906140de565b80601f0160208091040260200160405190810160405280929190818152602001828054610b18906140de565b8015610b655780601f10610b3a57610100808354040283529160200191610b65565b820191906000526020600020905b815481529060010190602001808311610b4857829003601f168201915b5050505050905090565b6000610b7a826120e3565b610bb0576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610bf881612142565b610c02838361223f565b505050565b600381565b6000610c16612383565b6003546002540303905090565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c6157610c6033612142565b5b610c6c848484612388565b50505050565b6618838370f3400081565b6000806000600160008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610e125760006040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000610e1c6126aa565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610e48919061413e565b610e5291906141af565b90508160000151819350935050509250929050565b610e6f6126b4565b600e60009054906101000a900460ff1615600e60006101000a81548160ff021916908315150217905550565b610ea36126b4565b610eab612732565b600047905060008103610eea576040517f669567ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600033905060008173ffffffffffffffffffffffffffffffffffffffff1647604051610f1590614211565b60006040518083038185875af1925050503d8060008114610f52576040519150601f19603f3d011682016040523d82523d6000602084013e610f57565b606091505b5050905080610f9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9290614272565b60405180910390fd5b505050610fa6612781565b565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ff857610ff733612142565b5b61100384848461278b565b50505050565b600381565b6110166126b4565b61101e612732565b60008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161105991906135b7565b602060405180830381865afa158015611076573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109a91906142a7565b90508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b81526004016110d79291906136a5565b6020604051808303816000875af11580156110f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061111a91906142e9565b5050611124612781565b50565b61112f6126b4565b80600e60026101000a81548160ff02191690831515021790555050565b60106020528060005260406000206000915090505481565b6060600083839050905060008167ffffffffffffffff81111561118a57611189613bde565b5b6040519080825280602002602001820160405280156111c357816020015b6111b06132c0565b8152602001906001900390816111a85790505b50905060005b82811461121b576111f28686838181106111e6576111e5614316565b5b90506020020135611acf565b82828151811061120557611204614316565b5b60200260200101819052508060010190506111c9565b50809250505092915050565b6000611232826127ab565b9050919050565b600f8054611246906140de565b80601f0160208091040260200160405190810160405280929190818152602001828054611272906140de565b80156112bf5780601f10611294576101008083540402835291602001916112bf565b820191906000526020600020905b8154815290600101906020018083116112a257829003601f168201915b505050505081565b6112cf6126b4565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361137a576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6113d36126b4565b6113dd6000612877565b565b6113e76126b4565b80600d8190555050565b600e60009054906101000a900460ff1681565b6060600080600061141485611313565b905060008167ffffffffffffffff81111561143257611431613bde565b5b6040519080825280602002602001820160405280156114605781602001602082028036833780820191505090505b50905061146b6132c0565b6000611475612383565b90505b838614611539576114888161293d565b9150816040015161152e57600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16146114d357816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361152d57808387806001019850815181106115205761151f614316565b5b6020026020010181815250505b5b806001019050611478565b508195505050505050919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060058054611580906140de565b80601f01602080910402602001604051908101604052809291908181526020018280546115ac906140de565b80156115f95780601f106115ce576101008083540402835291602001916115f9565b820191906000526020600020905b8154815290600101906020018083116115dc57829003601f168201915b5050505050905090565b606081831061163e576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080611649612968565b9050611653612383565b85101561166557611662612383565b94505b80841115611671578093505b600061167c87611313565b90508486101561169f576000868603905081811015611699578091505b506116a4565b600090505b60008167ffffffffffffffff8111156116c0576116bf613bde565b5b6040519080825280602002602001820160405280156116ee5781602001602082028036833780820191505090505b509050600082036117055780945050505050611808565b600061171088611acf565b90506000816040015161172557816000015190505b60008990505b88811415801561173b5750848714155b156117fa576117498161293d565b925082604001516117ef57600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161461179457826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036117ee57808488806001019950815181106117e1576117e0614316565b5b6020026020010181815250505b5b80600101905061172b565b508583528296505050505050505b9392505050565b611817612732565b600e60019054906101000a900460ff1661185d576040517fb7b2409700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80611866610c0c565b6118709190614345565b6115b310156118ab576040517f52df9fe500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80661f9e80ba8040006118be919061413e565b34146118f6576040517f0c9ccdcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a811115611931576040517f9782cdff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a81601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461197e9190614345565b11156119b6576040517f7dc8c67100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a059190614345565b92505081905550611a163382612972565b611a1e612781565b50565b611a296126b4565b80600f9081611a38919061451b565b5050565b81611a4681612142565b611a508383612b2e565b505050565b600d5481565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611a9957611a9833612142565b5b611aa585858585612c39565b5050505050565b600a81565b600e60019054906101000a900460ff1681565b661f9e80ba80400081565b611ad76132c0565b611adf6132c0565b611ae7612383565b831080611afb5750611af7612968565b8310155b15611b095780915050611b34565b611b128361293d565b9050806040015115611b275780915050611b34565b611b3083612cac565b9150505b919050565b6115b381565b600a81565b6060611b4f826120e3565b611b85576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611b8f612ccc565b90506000815103611baf5760405180602001604052806000815250611bda565b80611bb984612d5e565b604051602001611bca929190614629565b6040516020818303038152906040525b915050919050565b611bea6126b4565b600e60019054906101000a900460ff1615600e60016101000a81548160ff021916908315150217905550565b600e60009054906101000a900460ff16611c5c576040517fb7b2409700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816618838370f34000611c6f919061413e565b3414611ca7576040517f0c9ccdcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81611cb0610c0c565b611cba9190614345565b6115b31015611cf5576040517f52df9fe500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6003821115611d30576040517fd4f7dad500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d45611d3c33612dae565b600d5483612e04565b611d7b576040517fad7acb4700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600382601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611dc89190614345565b1115611e00576040517f12ca1abe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611e4f9190614345565b92505081905550611e603383612972565b5050565b611e6c6126b4565b80611e75610c0c565b611e7f9190614345565b6115b31015611eba576040517f52df9fe500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ec48282612972565b5050565b6000600e60029054906101000a900460ff168015611f3357508173ffffffffffffffffffffffffffffffffffffffff16600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b15611f415760019050611f4e565b611f4b8383612e1a565b90505b92915050565b611f5c6126b4565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611fcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fc2906146bf565b60405180910390fd5b611fd481612877565b50565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061203257506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806120625750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806120dc57506120db82612eae565b5b9050919050565b6000816120ee612383565b111580156120fd575060025482105b801561213b575060007c0100000000000000000000000000000000000000000000000000000000600660008581526020019081526020016000205416145b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111561223c576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016121b99291906146df565b602060405180830381865afa1580156121d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121fa91906142e9565b61223b57806040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161223291906135b7565b60405180910390fd5b5b50565b600061224a82611227565b90508073ffffffffffffffffffffffffffffffffffffffff1661226b612f18565b73ffffffffffffffffffffffffffffffffffffffff16146122ce5761229781612292612f18565b611ec8565b6122cd576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826008600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600090565b6000612393826127ab565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146123fa576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061240684612f20565b9150915061241c8187612417612f18565b612f47565b612468576124318661242c612f18565b611ec8565b612467576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036124ce576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124db8686866001612f8b565b80156124e657600082555b600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055506125b485612590888887612f91565b7c020000000000000000000000000000000000000000000000000000000017612fb9565b600660008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361263a5760006001850190506000600660008381526020019081526020016000205403612638576002548114612637578360066000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46126a28686866001612fe4565b505050505050565b6000612710905090565b6126bc612fea565b73ffffffffffffffffffffffffffffffffffffffff166126da611547565b73ffffffffffffffffffffffffffffffffffffffff1614612730576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161272790614754565b60405180910390fd5b565b6002600b5403612777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161276e906147c0565b60405180910390fd5b6002600b81905550565b6001600b81905550565b6127a683838360405180602001604052806000815250611a5b565b505050565b600080829050806127ba612383565b116128405760025481101561283f5760006006600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082160361283d575b60008103612833576006600083600190039350838152602001908152602001600020549050612809565b8092505050612872565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6129456132c0565b6129616006600084815260200190815260200160002054612ff2565b9050919050565b6000600254905090565b60006002549050600082036129b3576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129c06000848385612f8b565b600160406001901b178202600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612a3783612a286000866000612f91565b612a31856130a8565b17612fb9565b6006600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114612ad857808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612a9d565b5060008203612b13576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806002819055505050612b296000848385612fe4565b505050565b8060096000612b3b612f18565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612be8612f18565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612c2d91906133c3565b60405180910390a35050565b612c44848484610c23565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612ca657612c6f848484846130b8565b612ca5576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b612cb46132c0565b612cc5612cc0836127ab565b612ff2565b9050919050565b6060600f8054612cdb906140de565b80601f0160208091040260200160405190810160405280929190818152602001828054612d07906140de565b8015612d545780601f10612d2957610100808354040283529160200191612d54565b820191906000526020600020905b815481529060010190602001808311612d3757829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b600115612d9957600184039350600a81066030018453600a8104905080612d77575b50828103602084039350808452505050919050565b600081604051602001612dc191906135b7565b60405160208183030381529060405280519060200120604051602001612de79190614801565b604051602081830303815290604052805190602001209050919050565b6000612e11828486613208565b90509392505050565b6000600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b60008060006008600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8612fa886868461321f565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600033905090565b612ffa6132c0565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b60006001821460e11b9050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026130de612f18565b8786866040518563ffffffff1660e01b81526004016131009493929190614871565b6020604051808303816000875af192505050801561313c57506040513d601f19601f8201168201806040525081019061313991906148d2565b60015b6131b5573d806000811461316c576040519150601f19603f3d011682016040523d82523d6000602084013e613171565b606091505b5060008151036131ad576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6000826132158584613228565b1490509392505050565b60009392505050565b60008082905060005b84518110156132735761325e8286838151811061325157613250614316565b5b602002602001015161327e565b9150808061326b906148ff565b915050613231565b508091505092915050565b60008183106132965761329182846132a9565b6132a1565b6132a083836132a9565b5b905092915050565b600082600052816020526040600020905092915050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61335881613323565b811461336357600080fd5b50565b6000813590506133758161334f565b92915050565b60006020828403121561339157613390613319565b5b600061339f84828501613366565b91505092915050565b60008115159050919050565b6133bd816133a8565b82525050565b60006020820190506133d860008301846133b4565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613409826133de565b9050919050565b613419816133fe565b811461342457600080fd5b50565b60008135905061343681613410565b92915050565b60006020828403121561345257613451613319565b5b600061346084828501613427565b91505092915050565b6000819050919050565b61347c81613469565b82525050565b60006020820190506134976000830184613473565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156134d75780820151818401526020810190506134bc565b60008484015250505050565b6000601f19601f8301169050919050565b60006134ff8261349d565b61350981856134a8565b93506135198185602086016134b9565b613522816134e3565b840191505092915050565b6000602082019050818103600083015261354781846134f4565b905092915050565b61355881613469565b811461356357600080fd5b50565b6000813590506135758161354f565b92915050565b60006020828403121561359157613590613319565b5b600061359f84828501613566565b91505092915050565b6135b1816133fe565b82525050565b60006020820190506135cc60008301846135a8565b92915050565b600080604083850312156135e9576135e8613319565b5b60006135f785828601613427565b925050602061360885828601613566565b9150509250929050565b60008060006060848603121561362b5761362a613319565b5b600061363986828701613427565b935050602061364a86828701613427565b925050604061365b86828701613566565b9150509250925092565b6000806040838503121561367c5761367b613319565b5b600061368a85828601613566565b925050602061369b85828601613566565b9150509250929050565b60006040820190506136ba60008301856135a8565b6136c76020830184613473565b9392505050565b6000819050919050565b60006136f36136ee6136e9846133de565b6136ce565b6133de565b9050919050565b6000613705826136d8565b9050919050565b6000613717826136fa565b9050919050565b6137278161370c565b82525050565b6000602082019050613742600083018461371e565b92915050565b6000613753826133fe565b9050919050565b61376381613748565b811461376e57600080fd5b50565b6000813590506137808161375a565b92915050565b60006020828403121561379c5761379b613319565b5b60006137aa84828501613771565b91505092915050565b6137bc816133a8565b81146137c757600080fd5b50565b6000813590506137d9816137b3565b92915050565b6000602082840312156137f5576137f4613319565b5b6000613803848285016137ca565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126138315761383061380c565b5b8235905067ffffffffffffffff81111561384e5761384d613811565b5b60208301915083602082028301111561386a57613869613816565b5b9250929050565b6000806020838503121561388857613887613319565b5b600083013567ffffffffffffffff8111156138a6576138a561331e565b5b6138b28582860161381b565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6138f3816133fe565b82525050565b600067ffffffffffffffff82169050919050565b613916816138f9565b82525050565b613925816133a8565b82525050565b600062ffffff82169050919050565b6139438161392b565b82525050565b60808201600082015161395f60008501826138ea565b506020820151613972602085018261390d565b506040820151613985604085018261391c565b506060820151613998606085018261393a565b50505050565b60006139aa8383613949565b60808301905092915050565b6000602082019050919050565b60006139ce826138be565b6139d881856138c9565b93506139e3836138da565b8060005b83811015613a145781516139fb888261399e565b9750613a06836139b6565b9250506001810190506139e7565b5085935050505092915050565b60006020820190508181036000830152613a3b81846139c3565b905092915050565b6000819050919050565b613a5681613a43565b8114613a6157600080fd5b50565b600081359050613a7381613a4d565b92915050565b600060208284031215613a8f57613a8e613319565b5b6000613a9d84828501613a64565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613adb81613469565b82525050565b6000613aed8383613ad2565b60208301905092915050565b6000602082019050919050565b6000613b1182613aa6565b613b1b8185613ab1565b9350613b2683613ac2565b8060005b83811015613b57578151613b3e8882613ae1565b9750613b4983613af9565b925050600181019050613b2a565b5085935050505092915050565b60006020820190508181036000830152613b7e8184613b06565b905092915050565b600080600060608486031215613b9f57613b9e613319565b5b6000613bad86828701613427565b9350506020613bbe86828701613566565b9250506040613bcf86828701613566565b9150509250925092565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613c16826134e3565b810181811067ffffffffffffffff82111715613c3557613c34613bde565b5b80604052505050565b6000613c4861330f565b9050613c548282613c0d565b919050565b600067ffffffffffffffff821115613c7457613c73613bde565b5b613c7d826134e3565b9050602081019050919050565b82818337600083830152505050565b6000613cac613ca784613c59565b613c3e565b905082815260208101848484011115613cc857613cc7613bd9565b5b613cd3848285613c8a565b509392505050565b600082601f830112613cf057613cef61380c565b5b8135613d00848260208601613c99565b91505092915050565b600060208284031215613d1f57613d1e613319565b5b600082013567ffffffffffffffff811115613d3d57613d3c61331e565b5b613d4984828501613cdb565b91505092915050565b60008060408385031215613d6957613d68613319565b5b6000613d7785828601613427565b9250506020613d88858286016137ca565b9150509250929050565b613d9b81613a43565b82525050565b6000602082019050613db66000830184613d92565b92915050565b600067ffffffffffffffff821115613dd757613dd6613bde565b5b613de0826134e3565b9050602081019050919050565b6000613e00613dfb84613dbc565b613c3e565b905082815260208101848484011115613e1c57613e1b613bd9565b5b613e27848285613c8a565b509392505050565b600082601f830112613e4457613e4361380c565b5b8135613e54848260208601613ded565b91505092915050565b60008060008060808587031215613e7757613e76613319565b5b6000613e8587828801613427565b9450506020613e9687828801613427565b9350506040613ea787828801613566565b925050606085013567ffffffffffffffff811115613ec857613ec761331e565b5b613ed487828801613e2f565b91505092959194509250565b608082016000820151613ef660008501826138ea565b506020820151613f09602085018261390d565b506040820151613f1c604085018261391c565b506060820151613f2f606085018261393a565b50505050565b6000608082019050613f4a6000830184613ee0565b92915050565b600067ffffffffffffffff821115613f6b57613f6a613bde565b5b602082029050602081019050919050565b6000613f8f613f8a84613f50565b613c3e565b90508083825260208201905060208402830185811115613fb257613fb1613816565b5b835b81811015613fdb5780613fc78882613a64565b845260208401935050602081019050613fb4565b5050509392505050565b600082601f830112613ffa57613ff961380c565b5b813561400a848260208601613f7c565b91505092915050565b6000806040838503121561402a57614029613319565b5b600061403885828601613566565b925050602083013567ffffffffffffffff8111156140595761405861331e565b5b61406585828601613fe5565b9150509250929050565b6000806040838503121561408657614085613319565b5b600061409485828601613427565b92505060206140a585828601613427565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806140f657607f821691505b602082108103614109576141086140af565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061414982613469565b915061415483613469565b925082820261416281613469565b915082820484148315176141795761417861410f565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006141ba82613469565b91506141c583613469565b9250826141d5576141d4614180565b5b828204905092915050565b600081905092915050565b50565b60006141fb6000836141e0565b9150614206826141eb565b600082019050919050565b600061421c826141ee565b9150819050919050565b7f4661696c656420746f2057697468647261772e00000000000000000000000000600082015250565b600061425c6013836134a8565b915061426782614226565b602082019050919050565b6000602082019050818103600083015261428b8161424f565b9050919050565b6000815190506142a18161354f565b92915050565b6000602082840312156142bd576142bc613319565b5b60006142cb84828501614292565b91505092915050565b6000815190506142e3816137b3565b92915050565b6000602082840312156142ff576142fe613319565b5b600061430d848285016142d4565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061435082613469565b915061435b83613469565b92508282019050808211156143735761437261410f565b5b92915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026143db7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261439e565b6143e5868361439e565b95508019841693508086168417925050509392505050565b600061441861441361440e84613469565b6136ce565b613469565b9050919050565b6000819050919050565b614432836143fd565b61444661443e8261441f565b8484546143ab565b825550505050565b600090565b61445b61444e565b614466818484614429565b505050565b5b8181101561448a5761447f600082614453565b60018101905061446c565b5050565b601f8211156144cf576144a081614379565b6144a98461438e565b810160208510156144b8578190505b6144cc6144c48561438e565b83018261446b565b50505b505050565b600082821c905092915050565b60006144f2600019846008026144d4565b1980831691505092915050565b600061450b83836144e1565b9150826002028217905092915050565b6145248261349d565b67ffffffffffffffff81111561453d5761453c613bde565b5b61454782546140de565b61455282828561448e565b600060209050601f8311600181146145855760008415614573578287015190505b61457d85826144ff565b8655506145e5565b601f19841661459386614379565b60005b828110156145bb57848901518255600182019150602085019450602081019050614596565b868310156145d857848901516145d4601f8916826144e1565b8355505b6001600288020188555050505b505050505050565b600081905092915050565b60006146038261349d565b61460d81856145ed565b935061461d8185602086016134b9565b80840191505092915050565b600061463582856145f8565b915061464182846145f8565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006146a96026836134a8565b91506146b48261464d565b604082019050919050565b600060208201905081810360008301526146d88161469c565b9050919050565b60006040820190506146f460008301856135a8565b61470160208301846135a8565b9392505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061473e6020836134a8565b915061474982614708565b602082019050919050565b6000602082019050818103600083015261476d81614731565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006147aa601f836134a8565b91506147b582614774565b602082019050919050565b600060208201905081810360008301526147d98161479d565b9050919050565b6000819050919050565b6147fb6147f682613a43565b6147e0565b82525050565b600061480d82846147ea565b60208201915081905092915050565b600081519050919050565b600082825260208201905092915050565b60006148438261481c565b61484d8185614827565b935061485d8185602086016134b9565b614866816134e3565b840191505092915050565b600060808201905061488660008301876135a8565b61489360208301866135a8565b6148a06040830185613473565b81810360608301526148b28184614838565b905095945050505050565b6000815190506148cc8161334f565b92915050565b6000602082840312156148e8576148e7613319565b5b60006148f6848285016148bd565b91505092915050565b600061490a82613469565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361493c5761493b61410f565b5b60018201905091905056fea2646970667358221220af7e065803e72bc53afc7e2c2c1a3f58689227bd340a8ba7a02685a16761f24464736f6c63430008130033
Deployed Bytecode Sourcemap
1017:6484:10:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7238:261;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1933:45;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10039:98:11;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16360:214;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5772:240:10;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1426:59;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5894:317:11;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6517:218:10;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1491:57;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1671:428:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;2179:91:10;;;;;;;;;;;;;:::i;:::-;;2625:348;;;;;;;;;;;;;:::i;:::-;;1158:142:17;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6741:226:10;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1360:60;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2979:180;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2450:169;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1875:52;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1641:513:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;11391:150:11;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1848:21:10;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2276:168;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;7045:230:11;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1824:101:0;;;;;;;;;;;;;:::i;:::-;;3261:99:10;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1692:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5417:879:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1201:85:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10208:102:11;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2528:2454:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4457:632:10;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3165:90;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;5551:215;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1647:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6973:259;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1302:52;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1723:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1554:49;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1070:418:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1805:37:10;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1243:53;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10411:313:11;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2073:100:10;;;;;;;;;;;;;:::i;:::-;;3598:853;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3366:195;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;6144:367;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2074:198:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;7238:261:10;7365:4;7400:38;7426:11;7400:25;:38::i;:::-;:92;;;;7454:38;7480:11;7454:25;:38::i;:::-;7400:92;7381:111;;7238:261;;;:::o;1933:45::-;;;;;;;;;;;;;;;;;:::o;10039:98:11:-;10093:13;10125:5;10118:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10039:98;:::o;16360:214::-;16436:7;16460:16;16468:7;16460;:16::i;:::-;16455:64;;16485:34;;;;;;;;;;;;;;16455:64;16537:15;:24;16553:7;16537:24;;;;;;;;;;;:30;;;;;;;;;;;;16530:37;;16360:214;;;:::o;5772:240:10:-;5949:8;2902:30:17;2923:8;2902:20;:30::i;:::-;5973:32:10::1;5987:8;5997:7;5973:13;:32::i;:::-;5772:240:::0;;;:::o;1426:59::-;1484:1;1426:59;:::o;5894:317:11:-;5955:7;6179:15;:13;:15::i;:::-;6164:12;;6148:13;;:28;:46;6141:53;;5894:317;:::o;6517:218:10:-;6675:4;2646:10:17;2638:18;;:4;:18;;;2634:81;;2672:32;2693:10;2672:20;:32::i;:::-;2634:81;6691:37:10::1;6710:4;6716:2;6720:7;6691:18;:37::i;:::-;6517:218:::0;;;;:::o;1491:57::-;1536:12;1491:57;:::o;1671:428:5:-;1766:7;1775;1794:26;1823:17;:26;1841:7;1823:26;;;;;;;;;;;1794:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1892:1;1864:30;;:7;:16;;;:30;;;1860:90;;1920:19;1910:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1860:90;1960:21;2024:17;:15;:17::i;:::-;1984:57;;1997:7;:23;;;1985:35;;:9;:35;;;;:::i;:::-;1984:57;;;;:::i;:::-;1960:81;;2060:7;:16;;;2078:13;2052:40;;;;;;1671:428;;;;;:::o;2179:91:10:-;1094:13:0;:11;:13::i;:::-;2250::10::1;;;;;;;;;;;2249:14;2233:13;;:30;;;;;;;;;;;;;;;;;;2179:91::o:0;2625:348::-;1094:13:0;:11;:13::i;:::-;2261:21:3::1;:19;:21::i;:::-;2687:15:10::2;2705:21;2687:39;;2751:1;2740:7;:12:::0;2736:63:::2;;2775:13;;;;;;;;;;;;;;2736:63;2808:13;2832:10;2808:35;;2855:12;2873:5;:10;;2891:21;2873:44;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2854:63;;;2935:7;2927:39;;;;;;;;;;;;:::i;:::-;;;;;;;;;2677:296;;;2303:20:3::1;:18;:20::i;:::-;2625:348:10:o:0;1158:142:17:-;120:42:18;1158:142:17;:::o;6741:226:10:-;6903:4;2646:10:17;2638:18;;:4;:18;;;2634:81;;2672:32;2693:10;2672:20;:32::i;:::-;2634:81;6919:41:10::1;6942:4;6948:2;6952:7;6919:22;:41::i;:::-;6741:226:::0;;;;:::o;1360:60::-;1419:1;1360:60;:::o;2979:180::-;1094:13:0;:11;:13::i;:::-;2261:21:3::1;:19;:21::i;:::-;3059:15:10::2;3077:5;:15;;;3101:4;3077:30;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3059:48;;3117:5;:14;;;3132:10;3144:7;3117:35;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;3049:110;2303:20:3::1;:18;:20::i;:::-;2979:180:10::0;:::o;2450:169::-;1094:13:0;:11;:13::i;:::-;2589:23:10::1;2564:22;;:48;;;;;;;;;;;;;;;;;;2450:169:::0;:::o;1875:52::-;;;;;;;;;;;;;;;;;:::o;1641:513:13:-;1780:23;1843:22;1868:8;;:15;;1843:40;;1897:34;1955:14;1934:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;1897:73;;1989:9;1984:123;2005:14;2000:1;:19;1984:123;;2060:32;2080:8;;2089:1;2080:11;;;;;;;:::i;:::-;;;;;;;;2060:19;:32::i;:::-;2044:10;2055:1;2044:13;;;;;;;;:::i;:::-;;;;;;;:48;;;;2021:3;;;;;1984:123;;;;2127:10;2120:17;;;;1641:513;;;;:::o;11391:150:11:-;11463:7;11505:27;11524:7;11505:18;:27::i;:::-;11482:52;;11391:150;;;:::o;1848:21:10:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2276:168::-;1094:13:0;:11;:13::i;:::-;2415:22:10::1;2391:21;;:46;;;;;;;;;;;;;;;;;;2276:168:::0;:::o;7045:230:11:-;7117:7;7157:1;7140:19;;:5;:19;;;7136:60;;7168:28;;;;;;;;;;;;;;7136:60;1360:13;7213:18;:25;7232:5;7213:25;;;;;;;;;;;;;;;;:55;7206:62;;7045:230;;;:::o;1824:101:0:-;1094:13;:11;:13::i;:::-;1888:30:::1;1915:1;1888:18;:30::i;:::-;1824:101::o:0;3261:99:10:-;1094:13:0;:11;:13::i;:::-;3349:4:10::1;3327:19;:26;;;;3261:99:::0;:::o;1692:25::-;;;;;;;;;;;;;:::o;5417:879:13:-;5495:16;5547:19;5580:25;5619:22;5644:16;5654:5;5644:9;:16::i;:::-;5619:41;;5674:25;5716:14;5702:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5674:57;;5745:31;;:::i;:::-;5795:9;5807:15;:13;:15::i;:::-;5795:27;;5790:461;5839:14;5824:11;:29;5790:461;;5890:15;5903:1;5890:12;:15::i;:::-;5878:27;;5927:9;:16;;;5967:8;5923:71;6041:1;6015:28;;:9;:14;;;:28;;;6011:109;;6087:9;:14;;;6067:34;;6011:109;6162:5;6141:26;;:17;:26;;;6137:100;;6217:1;6191:8;6200:13;;;;;;6191:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;6137:100;5790:461;5855:3;;;;;5790:461;;;;6271:8;6264:15;;;;;;;5417:879;;;:::o;1201:85:0:-;1247:7;1273:6;;;;;;;;;;;1266:13;;1201:85;:::o;10208:102:11:-;10264:13;10296:7;10289:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10208:102;:::o;2528:2454:13:-;2667:16;2732:4;2723:5;:13;2719:45;;2745:19;;;;;;;;;;;;;;2719:45;2778:19;2811:17;2831:14;:12;:14::i;:::-;2811:34;;2929:15;:13;:15::i;:::-;2921:5;:23;2917:85;;;2972:15;:13;:15::i;:::-;2964:23;;2917:85;3076:9;3069:4;:16;3065:71;;;3112:9;3105:16;;3065:71;3149:25;3177:16;3187:5;3177:9;:16::i;:::-;3149:44;;3368:4;3360:5;:12;3356:271;;;3392:19;3421:5;3414:4;:12;3392:34;;3462:17;3448:11;:31;3444:109;;;3523:11;3503:31;;3444:109;3374:193;3356:271;;;3611:1;3591:21;;3356:271;3640:25;3682:17;3668:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3640:60;;3739:1;3718:17;:22;3714:76;;3767:8;3760:15;;;;;;;;3714:76;3931:31;3965:26;3985:5;3965:19;:26::i;:::-;3931:60;;4005:25;4247:9;:16;;;4242:90;;4303:9;:14;;;4283:34;;4242:90;4350:9;4362:5;4350:17;;4345:467;4374:4;4369:1;:9;;:45;;;;;4397:17;4382:11;:32;;4369:45;4345:467;;;4451:15;4464:1;4451:12;:15::i;:::-;4439:27;;4488:9;:16;;;4528:8;4484:71;4602:1;4576:28;;:9;:14;;;:28;;;4572:109;;4648:9;:14;;;4628:34;;4572:109;4723:5;4702:26;;:17;:26;;;4698:100;;4778:1;4752:8;4761:13;;;;;;4752:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;4698:100;4345:467;4416:3;;;;;4345:467;;;;4911:11;4901:8;4894:29;4957:8;4950:15;;;;;;;;2528:2454;;;;;;:::o;4457:632:10:-;2261:21:3;:19;:21::i;:::-;4529:16:10::1;;;;;;;;;;;4524:70;;4568:15;;;;;;;;;;;;;;4524:70;4633:5;4617:13;:11;:13::i;:::-;:21;;;;:::i;:::-;1838:4;4607:32;4603:79;;;4662:9;;;;;;;;;;;;;;4603:79;4721:5;1591:12;4708:18;;;;:::i;:::-;4695:9;:31;4691:92;;4749:23;;;;;;;;;;;;;;4691:92;1352:2;4796:5;:31;4792:96;;;4850:27;;;;;;;;;;;;;;4792:96;1294:2;4926:5;4901:10;:22;4912:10;4901:22;;;;;;;;;;;;;;;;:30;;;;:::i;:::-;:57;4897:110;;;4981:15;;;;;;;;;;;;;;4897:110;5043:5;5017:10;:22;5028:10;5017:22;;;;;;;;;;;;;;;;:31;;;;;;;:::i;:::-;;;;;;;;5058:24;5064:10;5076:5;5058;:24::i;:::-;2303:20:3::0;:18;:20::i;:::-;4457:632:10;:::o;3165:90::-;1094:13:0;:11;:13::i;:::-;3244:4:10::1;3234:7;:14;;;;;;:::i;:::-;;3165:90:::0;:::o;5551:215::-;5696:8;2902:30:17;2923:8;2902:20;:30::i;:::-;5716:43:10::1;5740:8;5750;5716:23;:43::i;:::-;5551:215:::0;;;:::o;1647:34::-;;;;:::o;6973:259::-;7162:4;2646:10:17;2638:18;;:4;:18;;;2634:81;;2672:32;2693:10;2672:20;:32::i;:::-;2634:81;7178:47:10::1;7201:4;7207:2;7211:7;7220:4;7178:22;:47::i;:::-;6973:259:::0;;;;;:::o;1302:52::-;1352:2;1302:52;:::o;1723:28::-;;;;;;;;;;;;;:::o;1554:49::-;1591:12;1554:49;:::o;1070:418:13:-;1154:21;;:::i;:::-;1187:31;;:::i;:::-;1242:15;:13;:15::i;:::-;1232:7;:25;:54;;;;1272:14;:12;:14::i;:::-;1261:7;:25;;1232:54;1228:101;;;1309:9;1302:16;;;;;1228:101;1350:21;1363:7;1350:12;:21::i;:::-;1338:33;;1385:9;:16;;;1381:63;;;1424:9;1417:16;;;;;1381:63;1460:21;1473:7;1460:12;:21::i;:::-;1453:28;;;1070:418;;;;:::o;1805:37:10:-;1838:4;1805:37;:::o;1243:53::-;1294:2;1243:53;:::o;10411:313:11:-;10484:13;10514:16;10522:7;10514;:16::i;:::-;10509:59;;10539:29;;;;;;;;;;;;;;10509:59;10579:21;10603:10;:8;:10::i;:::-;10579:34;;10655:1;10636:7;10630:21;:26;:87;;;;;;;;;;;;;;;;;10683:7;10692:18;10702:7;10692:9;:18::i;:::-;10666:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;10630:87;10623:94;;;10411:313;;;:::o;2073:100:10:-;1094:13:0;:11;:13::i;:::-;2150:16:10::1;;;;;;;;;;;2149:17;2130:16;;:36;;;;;;;;;;;;;;;;;;2073:100::o:0;3598:853::-;3688:13;;;;;;;;;;;3683:67;;3724:15;;;;;;;;;;;;;;3683:67;3797:5;1536:12;3776:26;;;;:::i;:::-;3763:9;:39;3759:100;;3825:23;;;;;;;;;;;;;;3759:100;3898:5;3882:13;:11;:13::i;:::-;:21;;;;:::i;:::-;1838:4;3872:32;3868:79;;;3927:9;;;;;;;;;;;;;;3868:79;1484:1;3960:5;:39;3956:111;;;4022:34;;;;;;;;;;;;;;3956:111;4081:54;4089:17;4095:10;4089:5;:17::i;:::-;4108:19;;4129:5;4081:7;:54::i;:::-;4076:116;;4158:23;;;;;;;;;;;;;;4076:116;1419:1;4250:5;4218:17;:29;4236:10;4218:29;;;;;;;;;;;;;;;;:37;;;;:::i;:::-;:84;4201:162;;;4334:18;;;;;;;;;;;;;;4201:162;4405:5;4372:17;:29;4390:10;4372:29;;;;;;;;;;;;;;;;:38;;;;;;;:::i;:::-;;;;;;;;4420:24;4426:10;4438:5;4420;:24::i;:::-;3598:853;;:::o;3366:195::-;1094:13:0;:11;:13::i;:::-;3475:5:10::1;3459:13;:11;:13::i;:::-;:21;;;;:::i;:::-;1838:4;3449:32;3445:79;;;3504:9;;;;;;;;;;;;;;3445:79;3534:20;3540:6;3548:5;3534;:20::i;:::-;3366:195:::0;;:::o;6144:367::-;6284:4;6321:22;;;;;;;;;;;:80;;;;;6393:8;6359:42;;6367:21;;;;;;;;;;;6359:42;;;6321:80;6304:144;;;6433:4;6426:11;;;;6304:144;6465:39;6488:5;6495:8;6465:22;:39::i;:::-;6458:46;;6144:367;;;;;:::o;2074:198:0:-;1094:13;:11;:13::i;:::-;2182:1:::1;2162:22;;:8;:22;;::::0;2154:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;2237:28;2256:8;2237:18;:28::i;:::-;2074:198:::0;:::o;9155:630:11:-;9240:4;9573:10;9558:25;;:11;:25;;;;:101;;;;9649:10;9634:25;;:11;:25;;;;9558:101;:177;;;;9725:10;9710:25;;:11;:25;;;;9558:177;9539:196;;9155:630;;;:::o;1408:213:5:-;1510:4;1548:26;1533:41;;;:11;:41;;;;:81;;;;1578:36;1602:11;1578:23;:36::i;:::-;1533:81;1526:88;;1408:213;;;:::o;17693:277:11:-;17758:4;17812:7;17793:15;:13;:15::i;:::-;:26;;:65;;;;;17845:13;;17835:7;:23;17793:65;:151;;;;;17943:1;2118:8;17895:17;:26;17913:7;17895:26;;;;;;;;;;;;:44;:49;17793:151;17774:170;;17693:277;;;:::o;3038:638:17:-;3275:1;120:42:18;3227:45:17;;;:49;3223:447;;;120:42:18;3523::17;;;3574:4;3581:8;3523:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3518:142;;3636:8;3617:28;;;;;;;;;;;:::i;:::-;;;;;;;;3518:142;3223:447;3038:638;:::o;15812:398:11:-;15900:13;15916:16;15924:7;15916;:16::i;:::-;15900:32;;15970:5;15947:28;;:19;:17;:19::i;:::-;:28;;;15943:172;;15994:44;16011:5;16018:19;:17;:19::i;:::-;15994:16;:44::i;:::-;15989:126;;16065:35;;;;;;;;;;;;;;15989:126;15943:172;16158:2;16125:15;:24;16141:7;16125:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;16195:7;16191:2;16175:28;;16184:5;16175:28;;;;;;;;;;;;15890:320;15812:398;;:::o;5426:90::-;5482:7;5426:90;:::o;19903:2764::-;20040:27;20070;20089:7;20070:18;:27::i;:::-;20040:57;;20153:4;20112:45;;20128:19;20112:45;;;20108:86;;20166:28;;;;;;;;;;;;;;20108:86;20206:27;20235:23;20262:35;20289:7;20262:26;:35::i;:::-;20205:92;;;;20394:68;20419:15;20436:4;20442:19;:17;:19::i;:::-;20394:24;:68::i;:::-;20389:179;;20481:43;20498:4;20504:19;:17;:19::i;:::-;20481:16;:43::i;:::-;20476:92;;20533:35;;;;;;;;;;;;;;20476:92;20389:179;20597:1;20583:16;;:2;:16;;;20579:52;;20608:23;;;;;;;;;;;;;;20579:52;20642:43;20664:4;20670:2;20674:7;20683:1;20642:21;:43::i;:::-;20774:15;20771:157;;;20912:1;20891:19;20884:30;20771:157;21300:18;:24;21319:4;21300:24;;;;;;;;;;;;;;;;21298:26;;;;;;;;;;;;21368:18;:22;21387:2;21368:22;;;;;;;;;;;;;;;;21366:24;;;;;;;;;;;21683:143;21719:2;21767:45;21782:4;21788:2;21792:19;21767:14;:45::i;:::-;2392:8;21739:73;21683:18;:143::i;:::-;21654:17;:26;21672:7;21654:26;;;;;;;;;;;:172;;;;21994:1;2392:8;21943:19;:47;:52;21939:617;;22015:19;22047:1;22037:7;:11;22015:33;;22202:1;22168:17;:30;22186:11;22168:30;;;;;;;;;;;;:35;22164:378;;22304:13;;22289:11;:28;22285:239;;22482:19;22449:17;:30;22467:11;22449:30;;;;;;;;;;;:52;;;;22285:239;22164:378;21997:559;21939:617;22600:7;22596:2;22581:27;;22590:4;22581:27;;;;;;;;;;;;22618:42;22639:4;22645:2;22649:7;22658:1;22618:20;:42::i;:::-;20030:2637;;;19903:2764;;;:::o;2374:95:5:-;2432:6;2457:5;2450:12;;2374:95;:::o;1359:130:0:-;1433:12;:10;:12::i;:::-;1422:23;;:7;:5;:7::i;:::-;:23;;;1414:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;1359:130::o;2336:287:3:-;1759:1;2468:7;;:19;2460:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;1759:1;2598:7;:18;;;;2336:287::o;2629:209::-;1716:1;2809:7;:22;;;;2629:209::o;22758:187:11:-;22899:39;22916:4;22922:2;22926:7;22899:39;;;;;;;;;;;;:16;:39::i;:::-;22758:187;;;:::o;12515:1249::-;12582:7;12601:12;12616:7;12601:22;;12681:4;12662:15;:13;:15::i;:::-;:23;12658:1042;;12714:13;;12707:4;:20;12703:997;;;12751:14;12768:17;:23;12786:4;12768:23;;;;;;;;;;;;12751:40;;12883:1;2118:8;12855:6;:24;:29;12851:831;;13510:111;13527:1;13517:6;:11;13510:111;;13569:17;:25;13587:6;;;;;;;13569:25;;;;;;;;;;;;13560:34;;13510:111;;;13653:6;13646:13;;;;;;12851:831;12729:971;12703:997;12658:1042;13726:31;;;;;;;;;;;;;;12515:1249;;;;:::o;2426:187:0:-;2499:16;2518:6;;;;;;;;;;;2499:25;;2543:8;2534:6;;:17;;;;;;;;;;;;;;;;;;2597:8;2566:40;;2587:8;2566:40;;;;;;;;;;;;2489:124;2426:187;:::o;11979:159:11:-;12047:21;;:::i;:::-;12087:44;12106:17;:24;12124:5;12106:24;;;;;;;;;;;;12087:18;:44::i;:::-;12080:51;;11979:159;;;:::o;5590:101::-;5645:7;5671:13;;5664:20;;5590:101;:::o;27091:2902::-;27163:20;27186:13;;27163:36;;27225:1;27213:8;:13;27209:44;;27235:18;;;;;;;;;;;;;;27209:44;27264:61;27294:1;27298:2;27302:12;27316:8;27264:21;:61::i;:::-;27797:1;1495:2;27767:1;:26;;27766:32;27754:8;:45;27728:18;:22;27747:2;27728:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;28069:136;28105:2;28158:33;28181:1;28185:2;28189:1;28158:14;:33::i;:::-;28125:30;28146:8;28125:20;:30::i;:::-;:66;28069:18;:136::i;:::-;28035:17;:31;28053:12;28035:31;;;;;;;;;;;:170;;;;28220:16;28250:11;28279:8;28264:12;:23;28250:37;;28792:16;28788:2;28784:25;28772:37;;29156:12;29117:8;29077:1;29016:25;28958:1;28898;28872:328;29520:1;29506:12;29502:20;29461:339;29560:3;29551:7;29548:16;29461:339;;29774:7;29764:8;29761:1;29734:25;29731:1;29728;29723:59;29612:1;29603:7;29599:15;29588:26;;29461:339;;;29465:75;29843:1;29831:8;:13;29827:45;;29853:19;;;;;;;;;;;;;;29827:45;29903:3;29887:13;:19;;;;27508:2409;;29926:60;29955:1;29959:2;29963:12;29977:8;29926:20;:60::i;:::-;27153:2840;27091:2902;;:::o;16901:231::-;17047:8;16995:18;:39;17014:19;:17;:19::i;:::-;16995:39;;;;;;;;;;;;;;;:49;17035:8;16995:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;17106:8;17070:55;;17085:19;:17;:19::i;:::-;17070:55;;;17116:8;17070:55;;;;;;:::i;:::-;;;;;;;;16901:231;;:::o;23526:396::-;23695:31;23708:4;23714:2;23718:7;23695:12;:31::i;:::-;23758:1;23740:2;:14;;;:19;23736:180;;23778:56;23809:4;23815:2;23819:7;23828:5;23778:30;:56::i;:::-;23773:143;;23861:40;;;;;;;;;;;;;;23773:143;23736:180;23526:396;;;;:::o;11724:164::-;11794:21;;:::i;:::-;11834:47;11853:27;11872:7;11853:18;:27::i;:::-;11834:18;:47::i;:::-;11827:54;;11724:164;;;:::o;5439:106:10:-;5499:13;5531:7;5524:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5439:106;:::o;39637:1708:11:-;39702:17;40130:4;40123;40117:11;40113:22;40220:1;40214:4;40207:15;40293:4;40290:1;40286:12;40279:19;;40373:1;40368:3;40361:14;40474:3;40708:5;40690:419;40716:1;40690:419;;;40755:1;40750:3;40746:11;40739:18;;40923:2;40917:4;40913:13;40909:2;40905:22;40900:3;40892:36;41015:2;41009:4;41005:13;40997:21;;41080:4;40690:419;41070:25;40690:419;40694:21;41146:3;41141;41137:13;41259:4;41254:3;41250:14;41243:21;;41322:6;41317:3;41310:19;39740:1599;;;39637:1708;;;:::o;5095:143:10:-;5150:7;5220;5209:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;5199:30;;;;;;5186:44;;;;;;;;:::i;:::-;;;;;;;;;;;;;5176:55;;;;;;5169:62;;5095:143;;;:::o;5244:189::-;5366:4;5389:37;5408:5;5415:4;5421;5389:18;:37::i;:::-;5382:44;;5244:189;;;;;:::o;17282:162:11:-;17379:4;17402:18;:25;17421:5;17402:25;;;;;;;;;;;;;;;:35;17428:8;17402:35;;;;;;;;;;;;;;;;;;;;;;;;;17395:42;;17282:162;;;;:::o;829:155:8:-;914:4;952:25;937:40;;;:11;:40;;;;930:47;;829:155;;;:::o;39437:103:11:-;39497:7;39523:10;39516:17;;39437:103;:::o;18828:474::-;18927:27;18956:23;18995:38;19036:15;:24;19052:7;19036:24;;;;;;;;;;;18995:65;;19210:18;19187:41;;19266:19;19260:26;19241:45;;19173:123;18828:474;;;:::o;18074:646::-;18219:11;18381:16;18374:5;18370:28;18361:37;;18539:16;18528:9;18524:32;18511:45;;18687:15;18676:9;18673:30;18665:5;18654:9;18651:20;18648:56;18638:66;;18074:646;;;;;:::o;24566:154::-;;;;;:::o;38764:304::-;38895:7;38914:16;2513:3;38940:19;:41;;38914:68;;2513:3;39007:31;39018:4;39024:2;39028:9;39007:10;:31::i;:::-;38999:40;;:62;;38992:69;;;38764:304;;;;;:::o;14297:443::-;14377:14;14542:16;14535:5;14531:28;14522:37;;14717:5;14703:11;14678:23;14674:41;14671:52;14664:5;14661:63;14651:73;;14297:443;;;;:::o;25367:153::-;;;;;:::o;640:96:6:-;693:7;719:10;712:17;;640:96;:::o;13858:361:11:-;13924:31;;:::i;:::-;14000:6;13967:9;:14;;:41;;;;;;;;;;;2004:3;14052:6;:33;;14018:9;:24;;:68;;;;;;;;;;;14143:1;2118:8;14115:6;:24;:29;;14096:9;:16;;:48;;;;;;;;;;;2513:3;14183:6;:28;;14154:9;:19;;:58;;;;;;;;;;;13858:361;;;:::o;14837:318::-;14907:14;15136:1;15126:8;15123:15;15097:24;15093:46;15083:56;;14837:318;;;:::o;25948:697::-;26106:4;26151:2;26126:45;;;26172:19;:17;:19::i;:::-;26193:4;26199:7;26208:5;26126:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;26122:517;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26421:1;26404:6;:13;:18;26400:229;;26449:40;;;;;;;;;;;;;;26400:229;26589:6;26583:13;26574:6;26570:2;26566:15;26559:38;26122:517;26292:54;;;26282:64;;;:6;:64;;;;26275:71;;;25948:697;;;;;;:::o;1156:154:7:-;1247:4;1299;1270:25;1283:5;1290:4;1270:12;:25::i;:::-;:33;1263:40;;1156:154;;;;;:::o;38475:143:11:-;38608:6;38475:143;;;;;:::o;1934:290:7:-;2017:7;2036:20;2059:4;2036:27;;2078:9;2073:116;2097:5;:12;2093:1;:16;2073:116;;;2145:33;2155:12;2169:5;2175:1;2169:8;;;;;;;;:::i;:::-;;;;;;;;2145:9;:33::i;:::-;2130:48;;2111:3;;;;;:::i;:::-;;;;2073:116;;;;2205:12;2198:19;;;1934:290;;;;:::o;9205:147::-;9268:7;9298:1;9294;:5;:51;;9325:20;9340:1;9343;9325:14;:20::i;:::-;9294:51;;;9302:20;9317:1;9320;9302:14;:20::i;:::-;9294:51;9287:58;;9205:147;;;;:::o;9358:261::-;9426:13;9530:1;9524:4;9517:15;9558:1;9552:4;9545:15;9598:4;9592;9582:21;9573:30;;9358:261;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:19:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:126::-;1555:7;1595:42;1588:5;1584:54;1573:65;;1518:126;;;:::o;1650:96::-;1687:7;1716:24;1734:5;1716:24;:::i;:::-;1705:35;;1650:96;;;:::o;1752:122::-;1825:24;1843:5;1825:24;:::i;:::-;1818:5;1815:35;1805:63;;1864:1;1861;1854:12;1805:63;1752:122;:::o;1880:139::-;1926:5;1964:6;1951:20;1942:29;;1980:33;2007:5;1980:33;:::i;:::-;1880:139;;;;:::o;2025:329::-;2084:6;2133:2;2121:9;2112:7;2108:23;2104:32;2101:119;;;2139:79;;:::i;:::-;2101:119;2259:1;2284:53;2329:7;2320:6;2309:9;2305:22;2284:53;:::i;:::-;2274:63;;2230:117;2025:329;;;;:::o;2360:77::-;2397:7;2426:5;2415:16;;2360:77;;;:::o;2443:118::-;2530:24;2548:5;2530:24;:::i;:::-;2525:3;2518:37;2443:118;;:::o;2567:222::-;2660:4;2698:2;2687:9;2683:18;2675:26;;2711:71;2779:1;2768:9;2764:17;2755:6;2711:71;:::i;:::-;2567:222;;;;:::o;2795:99::-;2847:6;2881:5;2875:12;2865:22;;2795:99;;;:::o;2900:169::-;2984:11;3018:6;3013:3;3006:19;3058:4;3053:3;3049:14;3034:29;;2900:169;;;;:::o;3075:246::-;3156:1;3166:113;3180:6;3177:1;3174:13;3166:113;;;3265:1;3260:3;3256:11;3250:18;3246:1;3241:3;3237:11;3230:39;3202:2;3199:1;3195:10;3190:15;;3166:113;;;3313:1;3304:6;3299:3;3295:16;3288:27;3137:184;3075:246;;;:::o;3327:102::-;3368:6;3419:2;3415:7;3410:2;3403:5;3399:14;3395:28;3385:38;;3327:102;;;:::o;3435:377::-;3523:3;3551:39;3584:5;3551:39;:::i;:::-;3606:71;3670:6;3665:3;3606:71;:::i;:::-;3599:78;;3686:65;3744:6;3739:3;3732:4;3725:5;3721:16;3686:65;:::i;:::-;3776:29;3798:6;3776:29;:::i;:::-;3771:3;3767:39;3760:46;;3527:285;3435:377;;;;:::o;3818:313::-;3931:4;3969:2;3958:9;3954:18;3946:26;;4018:9;4012:4;4008:20;4004:1;3993:9;3989:17;3982:47;4046:78;4119:4;4110:6;4046:78;:::i;:::-;4038:86;;3818:313;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:329::-;4469:6;4518:2;4506:9;4497:7;4493:23;4489:32;4486:119;;;4524:79;;:::i;:::-;4486:119;4644:1;4669:53;4714:7;4705:6;4694:9;4690:22;4669:53;:::i;:::-;4659:63;;4615:117;4410:329;;;;:::o;4745:118::-;4832:24;4850:5;4832:24;:::i;:::-;4827:3;4820:37;4745:118;;:::o;4869:222::-;4962:4;5000:2;4989:9;4985:18;4977:26;;5013:71;5081:1;5070:9;5066:17;5057:6;5013:71;:::i;:::-;4869:222;;;;:::o;5097:474::-;5165:6;5173;5222:2;5210:9;5201:7;5197:23;5193:32;5190:119;;;5228:79;;:::i;:::-;5190:119;5348:1;5373:53;5418:7;5409:6;5398:9;5394:22;5373:53;:::i;:::-;5363:63;;5319:117;5475:2;5501:53;5546:7;5537:6;5526:9;5522:22;5501:53;:::i;:::-;5491:63;;5446:118;5097:474;;;;;:::o;5577:619::-;5654:6;5662;5670;5719:2;5707:9;5698:7;5694:23;5690:32;5687:119;;;5725:79;;:::i;:::-;5687:119;5845:1;5870:53;5915:7;5906:6;5895:9;5891:22;5870:53;:::i;:::-;5860:63;;5816:117;5972:2;5998:53;6043:7;6034:6;6023:9;6019:22;5998:53;:::i;:::-;5988:63;;5943:118;6100:2;6126:53;6171:7;6162:6;6151:9;6147:22;6126:53;:::i;:::-;6116:63;;6071:118;5577:619;;;;;:::o;6202:474::-;6270:6;6278;6327:2;6315:9;6306:7;6302:23;6298:32;6295:119;;;6333:79;;:::i;:::-;6295:119;6453:1;6478:53;6523:7;6514:6;6503:9;6499:22;6478:53;:::i;:::-;6468:63;;6424:117;6580:2;6606:53;6651:7;6642:6;6631:9;6627:22;6606:53;:::i;:::-;6596:63;;6551:118;6202:474;;;;;:::o;6682:332::-;6803:4;6841:2;6830:9;6826:18;6818:26;;6854:71;6922:1;6911:9;6907:17;6898:6;6854:71;:::i;:::-;6935:72;7003:2;6992:9;6988:18;6979:6;6935:72;:::i;:::-;6682:332;;;;;:::o;7020:60::-;7048:3;7069:5;7062:12;;7020:60;;;:::o;7086:142::-;7136:9;7169:53;7187:34;7196:24;7214:5;7196:24;:::i;:::-;7187:34;:::i;:::-;7169:53;:::i;:::-;7156:66;;7086:142;;;:::o;7234:126::-;7284:9;7317:37;7348:5;7317:37;:::i;:::-;7304:50;;7234:126;;;:::o;7366:158::-;7448:9;7481:37;7512:5;7481:37;:::i;:::-;7468:50;;7366:158;;;:::o;7530:195::-;7649:69;7712:5;7649:69;:::i;:::-;7644:3;7637:82;7530:195;;:::o;7731:286::-;7856:4;7894:2;7883:9;7879:18;7871:26;;7907:103;8007:1;7996:9;7992:17;7983:6;7907:103;:::i;:::-;7731:286;;;;:::o;8023:110::-;8074:7;8103:24;8121:5;8103:24;:::i;:::-;8092:35;;8023:110;;;:::o;8139:150::-;8226:38;8258:5;8226:38;:::i;:::-;8219:5;8216:49;8206:77;;8279:1;8276;8269:12;8206:77;8139:150;:::o;8295:167::-;8355:5;8393:6;8380:20;8371:29;;8409:47;8450:5;8409:47;:::i;:::-;8295:167;;;;:::o;8468:357::-;8541:6;8590:2;8578:9;8569:7;8565:23;8561:32;8558:119;;;8596:79;;:::i;:::-;8558:119;8716:1;8741:67;8800:7;8791:6;8780:9;8776:22;8741:67;:::i;:::-;8731:77;;8687:131;8468:357;;;;:::o;8831:116::-;8901:21;8916:5;8901:21;:::i;:::-;8894:5;8891:32;8881:60;;8937:1;8934;8927:12;8881:60;8831:116;:::o;8953:133::-;8996:5;9034:6;9021:20;9012:29;;9050:30;9074:5;9050:30;:::i;:::-;8953:133;;;;:::o;9092:323::-;9148:6;9197:2;9185:9;9176:7;9172:23;9168:32;9165:119;;;9203:79;;:::i;:::-;9165:119;9323:1;9348:50;9390:7;9381:6;9370:9;9366:22;9348:50;:::i;:::-;9338:60;;9294:114;9092:323;;;;:::o;9421:117::-;9530:1;9527;9520:12;9544:117;9653:1;9650;9643:12;9667:117;9776:1;9773;9766:12;9807:568;9880:8;9890:6;9940:3;9933:4;9925:6;9921:17;9917:27;9907:122;;9948:79;;:::i;:::-;9907:122;10061:6;10048:20;10038:30;;10091:18;10083:6;10080:30;10077:117;;;10113:79;;:::i;:::-;10077:117;10227:4;10219:6;10215:17;10203:29;;10281:3;10273:4;10265:6;10261:17;10251:8;10247:32;10244:41;10241:128;;;10288:79;;:::i;:::-;10241:128;9807:568;;;;;:::o;10381:559::-;10467:6;10475;10524:2;10512:9;10503:7;10499:23;10495:32;10492:119;;;10530:79;;:::i;:::-;10492:119;10678:1;10667:9;10663:17;10650:31;10708:18;10700:6;10697:30;10694:117;;;10730:79;;:::i;:::-;10694:117;10843:80;10915:7;10906:6;10895:9;10891:22;10843:80;:::i;:::-;10825:98;;;;10621:312;10381:559;;;;;:::o;10946:146::-;11045:6;11079:5;11073:12;11063:22;;10946:146;;;:::o;11098:216::-;11229:11;11263:6;11258:3;11251:19;11303:4;11298:3;11294:14;11279:29;;11098:216;;;;:::o;11320:164::-;11419:4;11442:3;11434:11;;11472:4;11467:3;11463:14;11455:22;;11320:164;;;:::o;11490:108::-;11567:24;11585:5;11567:24;:::i;:::-;11562:3;11555:37;11490:108;;:::o;11604:101::-;11640:7;11680:18;11673:5;11669:30;11658:41;;11604:101;;;:::o;11711:105::-;11786:23;11803:5;11786:23;:::i;:::-;11781:3;11774:36;11711:105;;:::o;11822:99::-;11893:21;11908:5;11893:21;:::i;:::-;11888:3;11881:34;11822:99;;:::o;11927:91::-;11963:7;12003:8;11996:5;11992:20;11981:31;;11927:91;;;:::o;12024:105::-;12099:23;12116:5;12099:23;:::i;:::-;12094:3;12087:36;12024:105;;:::o;12207:866::-;12358:4;12353:3;12349:14;12445:4;12438:5;12434:16;12428:23;12464:63;12521:4;12516:3;12512:14;12498:12;12464:63;:::i;:::-;12373:164;12629:4;12622:5;12618:16;12612:23;12648:61;12703:4;12698:3;12694:14;12680:12;12648:61;:::i;:::-;12547:172;12803:4;12796:5;12792:16;12786:23;12822:57;12873:4;12868:3;12864:14;12850:12;12822:57;:::i;:::-;12729:160;12976:4;12969:5;12965:16;12959:23;12995:61;13050:4;13045:3;13041:14;13027:12;12995:61;:::i;:::-;12899:167;12327:746;12207:866;;:::o;13079:307::-;13212:10;13233:110;13339:3;13331:6;13233:110;:::i;:::-;13375:4;13370:3;13366:14;13352:28;;13079:307;;;;:::o;13392:145::-;13494:4;13526;13521:3;13517:14;13509:22;;13392:145;;;:::o;13619:988::-;13802:3;13831:86;13911:5;13831:86;:::i;:::-;13933:118;14044:6;14039:3;13933:118;:::i;:::-;13926:125;;14075:88;14157:5;14075:88;:::i;:::-;14186:7;14217:1;14202:380;14227:6;14224:1;14221:13;14202:380;;;14303:6;14297:13;14330:127;14453:3;14438:13;14330:127;:::i;:::-;14323:134;;14480:92;14565:6;14480:92;:::i;:::-;14470:102;;14262:320;14249:1;14246;14242:9;14237:14;;14202:380;;;14206:14;14598:3;14591:10;;13807:800;;;13619:988;;;;:::o;14613:501::-;14820:4;14858:2;14847:9;14843:18;14835:26;;14907:9;14901:4;14897:20;14893:1;14882:9;14878:17;14871:47;14935:172;15102:4;15093:6;14935:172;:::i;:::-;14927:180;;14613:501;;;;:::o;15120:77::-;15157:7;15186:5;15175:16;;15120:77;;;:::o;15203:122::-;15276:24;15294:5;15276:24;:::i;:::-;15269:5;15266:35;15256:63;;15315:1;15312;15305:12;15256:63;15203:122;:::o;15331:139::-;15377:5;15415:6;15402:20;15393:29;;15431:33;15458:5;15431:33;:::i;:::-;15331:139;;;;:::o;15476:329::-;15535:6;15584:2;15572:9;15563:7;15559:23;15555:32;15552:119;;;15590:79;;:::i;:::-;15552:119;15710:1;15735:53;15780:7;15771:6;15760:9;15756:22;15735:53;:::i;:::-;15725:63;;15681:117;15476:329;;;;:::o;15811:114::-;15878:6;15912:5;15906:12;15896:22;;15811:114;;;:::o;15931:184::-;16030:11;16064:6;16059:3;16052:19;16104:4;16099:3;16095:14;16080:29;;15931:184;;;;:::o;16121:132::-;16188:4;16211:3;16203:11;;16241:4;16236:3;16232:14;16224:22;;16121:132;;;:::o;16259:108::-;16336:24;16354:5;16336:24;:::i;:::-;16331:3;16324:37;16259:108;;:::o;16373:179::-;16442:10;16463:46;16505:3;16497:6;16463:46;:::i;:::-;16541:4;16536:3;16532:14;16518:28;;16373:179;;;;:::o;16558:113::-;16628:4;16660;16655:3;16651:14;16643:22;;16558:113;;;:::o;16707:732::-;16826:3;16855:54;16903:5;16855:54;:::i;:::-;16925:86;17004:6;16999:3;16925:86;:::i;:::-;16918:93;;17035:56;17085:5;17035:56;:::i;:::-;17114:7;17145:1;17130:284;17155:6;17152:1;17149:13;17130:284;;;17231:6;17225:13;17258:63;17317:3;17302:13;17258:63;:::i;:::-;17251:70;;17344:60;17397:6;17344:60;:::i;:::-;17334:70;;17190:224;17177:1;17174;17170:9;17165:14;;17130:284;;;17134:14;17430:3;17423:10;;16831:608;;;16707:732;;;;:::o;17445:373::-;17588:4;17626:2;17615:9;17611:18;17603:26;;17675:9;17669:4;17665:20;17661:1;17650:9;17646:17;17639:47;17703:108;17806:4;17797:6;17703:108;:::i;:::-;17695:116;;17445:373;;;;:::o;17824:619::-;17901:6;17909;17917;17966:2;17954:9;17945:7;17941:23;17937:32;17934:119;;;17972:79;;:::i;:::-;17934:119;18092:1;18117:53;18162:7;18153:6;18142:9;18138:22;18117:53;:::i;:::-;18107:63;;18063:117;18219:2;18245:53;18290:7;18281:6;18270:9;18266:22;18245:53;:::i;:::-;18235:63;;18190:118;18347:2;18373:53;18418:7;18409:6;18398:9;18394:22;18373:53;:::i;:::-;18363:63;;18318:118;17824:619;;;;;:::o;18449:117::-;18558:1;18555;18548:12;18572:180;18620:77;18617:1;18610:88;18717:4;18714:1;18707:15;18741:4;18738:1;18731:15;18758:281;18841:27;18863:4;18841:27;:::i;:::-;18833:6;18829:40;18971:6;18959:10;18956:22;18935:18;18923:10;18920:34;18917:62;18914:88;;;18982:18;;:::i;:::-;18914:88;19022:10;19018:2;19011:22;18801:238;18758:281;;:::o;19045:129::-;19079:6;19106:20;;:::i;:::-;19096:30;;19135:33;19163:4;19155:6;19135:33;:::i;:::-;19045:129;;;:::o;19180:308::-;19242:4;19332:18;19324:6;19321:30;19318:56;;;19354:18;;:::i;:::-;19318:56;19392:29;19414:6;19392:29;:::i;:::-;19384:37;;19476:4;19470;19466:15;19458:23;;19180:308;;;:::o;19494:146::-;19591:6;19586:3;19581;19568:30;19632:1;19623:6;19618:3;19614:16;19607:27;19494:146;;;:::o;19646:425::-;19724:5;19749:66;19765:49;19807:6;19765:49;:::i;:::-;19749:66;:::i;:::-;19740:75;;19838:6;19831:5;19824:21;19876:4;19869:5;19865:16;19914:3;19905:6;19900:3;19896:16;19893:25;19890:112;;;19921:79;;:::i;:::-;19890:112;20011:54;20058:6;20053:3;20048;20011:54;:::i;:::-;19730:341;19646:425;;;;;:::o;20091:340::-;20147:5;20196:3;20189:4;20181:6;20177:17;20173:27;20163:122;;20204:79;;:::i;:::-;20163:122;20321:6;20308:20;20346:79;20421:3;20413:6;20406:4;20398:6;20394:17;20346:79;:::i;:::-;20337:88;;20153:278;20091:340;;;;:::o;20437:509::-;20506:6;20555:2;20543:9;20534:7;20530:23;20526:32;20523:119;;;20561:79;;:::i;:::-;20523:119;20709:1;20698:9;20694:17;20681:31;20739:18;20731:6;20728:30;20725:117;;;20761:79;;:::i;:::-;20725:117;20866:63;20921:7;20912:6;20901:9;20897:22;20866:63;:::i;:::-;20856:73;;20652:287;20437:509;;;;:::o;20952:468::-;21017:6;21025;21074:2;21062:9;21053:7;21049:23;21045:32;21042:119;;;21080:79;;:::i;:::-;21042:119;21200:1;21225:53;21270:7;21261:6;21250:9;21246:22;21225:53;:::i;:::-;21215:63;;21171:117;21327:2;21353:50;21395:7;21386:6;21375:9;21371:22;21353:50;:::i;:::-;21343:60;;21298:115;20952:468;;;;;:::o;21426:118::-;21513:24;21531:5;21513:24;:::i;:::-;21508:3;21501:37;21426:118;;:::o;21550:222::-;21643:4;21681:2;21670:9;21666:18;21658:26;;21694:71;21762:1;21751:9;21747:17;21738:6;21694:71;:::i;:::-;21550:222;;;;:::o;21778:307::-;21839:4;21929:18;21921:6;21918:30;21915:56;;;21951:18;;:::i;:::-;21915:56;21989:29;22011:6;21989:29;:::i;:::-;21981:37;;22073:4;22067;22063:15;22055:23;;21778:307;;;:::o;22091:423::-;22168:5;22193:65;22209:48;22250:6;22209:48;:::i;:::-;22193:65;:::i;:::-;22184:74;;22281:6;22274:5;22267:21;22319:4;22312:5;22308:16;22357:3;22348:6;22343:3;22339:16;22336:25;22333:112;;;22364:79;;:::i;:::-;22333:112;22454:54;22501:6;22496:3;22491;22454:54;:::i;:::-;22174:340;22091:423;;;;;:::o;22533:338::-;22588:5;22637:3;22630:4;22622:6;22618:17;22614:27;22604:122;;22645:79;;:::i;:::-;22604:122;22762:6;22749:20;22787:78;22861:3;22853:6;22846:4;22838:6;22834:17;22787:78;:::i;:::-;22778:87;;22594:277;22533:338;;;;:::o;22877:943::-;22972:6;22980;22988;22996;23045:3;23033:9;23024:7;23020:23;23016:33;23013:120;;;23052:79;;:::i;:::-;23013:120;23172:1;23197:53;23242:7;23233:6;23222:9;23218:22;23197:53;:::i;:::-;23187:63;;23143:117;23299:2;23325:53;23370:7;23361:6;23350:9;23346:22;23325:53;:::i;:::-;23315:63;;23270:118;23427:2;23453:53;23498:7;23489:6;23478:9;23474:22;23453:53;:::i;:::-;23443:63;;23398:118;23583:2;23572:9;23568:18;23555:32;23614:18;23606:6;23603:30;23600:117;;;23636:79;;:::i;:::-;23600:117;23741:62;23795:7;23786:6;23775:9;23771:22;23741:62;:::i;:::-;23731:72;;23526:287;22877:943;;;;;;;:::o;23898:876::-;24059:4;24054:3;24050:14;24146:4;24139:5;24135:16;24129:23;24165:63;24222:4;24217:3;24213:14;24199:12;24165:63;:::i;:::-;24074:164;24330:4;24323:5;24319:16;24313:23;24349:61;24404:4;24399:3;24395:14;24381:12;24349:61;:::i;:::-;24248:172;24504:4;24497:5;24493:16;24487:23;24523:57;24574:4;24569:3;24565:14;24551:12;24523:57;:::i;:::-;24430:160;24677:4;24670:5;24666:16;24660:23;24696:61;24751:4;24746:3;24742:14;24728:12;24696:61;:::i;:::-;24600:167;24028:746;23898:876;;:::o;24780:351::-;24937:4;24975:3;24964:9;24960:19;24952:27;;24989:135;25121:1;25110:9;25106:17;25097:6;24989:135;:::i;:::-;24780:351;;;;:::o;25137:311::-;25214:4;25304:18;25296:6;25293:30;25290:56;;;25326:18;;:::i;:::-;25290:56;25376:4;25368:6;25364:17;25356:25;;25436:4;25430;25426:15;25418:23;;25137:311;;;:::o;25471:710::-;25567:5;25592:81;25608:64;25665:6;25608:64;:::i;:::-;25592:81;:::i;:::-;25583:90;;25693:5;25722:6;25715:5;25708:21;25756:4;25749:5;25745:16;25738:23;;25809:4;25801:6;25797:17;25789:6;25785:30;25838:3;25830:6;25827:15;25824:122;;;25857:79;;:::i;:::-;25824:122;25972:6;25955:220;25989:6;25984:3;25981:15;25955:220;;;26064:3;26093:37;26126:3;26114:10;26093:37;:::i;:::-;26088:3;26081:50;26160:4;26155:3;26151:14;26144:21;;26031:144;26015:4;26010:3;26006:14;25999:21;;25955:220;;;25959:21;25573:608;;25471:710;;;;;:::o;26204:370::-;26275:5;26324:3;26317:4;26309:6;26305:17;26301:27;26291:122;;26332:79;;:::i;:::-;26291:122;26449:6;26436:20;26474:94;26564:3;26556:6;26549:4;26541:6;26537:17;26474:94;:::i;:::-;26465:103;;26281:293;26204:370;;;;:::o;26580:684::-;26673:6;26681;26730:2;26718:9;26709:7;26705:23;26701:32;26698:119;;;26736:79;;:::i;:::-;26698:119;26856:1;26881:53;26926:7;26917:6;26906:9;26902:22;26881:53;:::i;:::-;26871:63;;26827:117;27011:2;27000:9;26996:18;26983:32;27042:18;27034:6;27031:30;27028:117;;;27064:79;;:::i;:::-;27028:117;27169:78;27239:7;27230:6;27219:9;27215:22;27169:78;:::i;:::-;27159:88;;26954:303;26580:684;;;;;:::o;27270:474::-;27338:6;27346;27395:2;27383:9;27374:7;27370:23;27366:32;27363:119;;;27401:79;;:::i;:::-;27363:119;27521:1;27546:53;27591:7;27582:6;27571:9;27567:22;27546:53;:::i;:::-;27536:63;;27492:117;27648:2;27674:53;27719:7;27710:6;27699:9;27695:22;27674:53;:::i;:::-;27664:63;;27619:118;27270:474;;;;;:::o;27750:180::-;27798:77;27795:1;27788:88;27895:4;27892:1;27885:15;27919:4;27916:1;27909:15;27936:320;27980:6;28017:1;28011:4;28007:12;27997:22;;28064:1;28058:4;28054:12;28085:18;28075:81;;28141:4;28133:6;28129:17;28119:27;;28075:81;28203:2;28195:6;28192:14;28172:18;28169:38;28166:84;;28222:18;;:::i;:::-;28166:84;27987:269;27936:320;;;:::o;28262:180::-;28310:77;28307:1;28300:88;28407:4;28404:1;28397:15;28431:4;28428:1;28421:15;28448:410;28488:7;28511:20;28529:1;28511:20;:::i;:::-;28506:25;;28545:20;28563:1;28545:20;:::i;:::-;28540:25;;28600:1;28597;28593:9;28622:30;28640:11;28622:30;:::i;:::-;28611:41;;28801:1;28792:7;28788:15;28785:1;28782:22;28762:1;28755:9;28735:83;28712:139;;28831:18;;:::i;:::-;28712:139;28496:362;28448:410;;;;:::o;28864:180::-;28912:77;28909:1;28902:88;29009:4;29006:1;28999:15;29033:4;29030:1;29023:15;29050:185;29090:1;29107:20;29125:1;29107:20;:::i;:::-;29102:25;;29141:20;29159:1;29141:20;:::i;:::-;29136:25;;29180:1;29170:35;;29185:18;;:::i;:::-;29170:35;29227:1;29224;29220:9;29215:14;;29050:185;;;;:::o;29241:147::-;29342:11;29379:3;29364:18;;29241:147;;;;:::o;29394:114::-;;:::o;29514:398::-;29673:3;29694:83;29775:1;29770:3;29694:83;:::i;:::-;29687:90;;29786:93;29875:3;29786:93;:::i;:::-;29904:1;29899:3;29895:11;29888:18;;29514:398;;;:::o;29918:379::-;30102:3;30124:147;30267:3;30124:147;:::i;:::-;30117:154;;30288:3;30281:10;;29918:379;;;:::o;30303:169::-;30443:21;30439:1;30431:6;30427:14;30420:45;30303:169;:::o;30478:366::-;30620:3;30641:67;30705:2;30700:3;30641:67;:::i;:::-;30634:74;;30717:93;30806:3;30717:93;:::i;:::-;30835:2;30830:3;30826:12;30819:19;;30478:366;;;:::o;30850:419::-;31016:4;31054:2;31043:9;31039:18;31031:26;;31103:9;31097:4;31093:20;31089:1;31078:9;31074:17;31067:47;31131:131;31257:4;31131:131;:::i;:::-;31123:139;;30850:419;;;:::o;31275:143::-;31332:5;31363:6;31357:13;31348:22;;31379:33;31406:5;31379:33;:::i;:::-;31275:143;;;;:::o;31424:351::-;31494:6;31543:2;31531:9;31522:7;31518:23;31514:32;31511:119;;;31549:79;;:::i;:::-;31511:119;31669:1;31694:64;31750:7;31741:6;31730:9;31726:22;31694:64;:::i;:::-;31684:74;;31640:128;31424:351;;;;:::o;31781:137::-;31835:5;31866:6;31860:13;31851:22;;31882:30;31906:5;31882:30;:::i;:::-;31781:137;;;;:::o;31924:345::-;31991:6;32040:2;32028:9;32019:7;32015:23;32011:32;32008:119;;;32046:79;;:::i;:::-;32008:119;32166:1;32191:61;32244:7;32235:6;32224:9;32220:22;32191:61;:::i;:::-;32181:71;;32137:125;31924:345;;;;:::o;32275:180::-;32323:77;32320:1;32313:88;32420:4;32417:1;32410:15;32444:4;32441:1;32434:15;32461:191;32501:3;32520:20;32538:1;32520:20;:::i;:::-;32515:25;;32554:20;32572:1;32554:20;:::i;:::-;32549:25;;32597:1;32594;32590:9;32583:16;;32618:3;32615:1;32612:10;32609:36;;;32625:18;;:::i;:::-;32609:36;32461:191;;;;:::o;32658:141::-;32707:4;32730:3;32722:11;;32753:3;32750:1;32743:14;32787:4;32784:1;32774:18;32766:26;;32658:141;;;:::o;32805:93::-;32842:6;32889:2;32884;32877:5;32873:14;32869:23;32859:33;;32805:93;;;:::o;32904:107::-;32948:8;32998:5;32992:4;32988:16;32967:37;;32904:107;;;;:::o;33017:393::-;33086:6;33136:1;33124:10;33120:18;33159:97;33189:66;33178:9;33159:97;:::i;:::-;33277:39;33307:8;33296:9;33277:39;:::i;:::-;33265:51;;33349:4;33345:9;33338:5;33334:21;33325:30;;33398:4;33388:8;33384:19;33377:5;33374:30;33364:40;;33093:317;;33017:393;;;;;:::o;33416:142::-;33466:9;33499:53;33517:34;33526:24;33544:5;33526:24;:::i;:::-;33517:34;:::i;:::-;33499:53;:::i;:::-;33486:66;;33416:142;;;:::o;33564:75::-;33607:3;33628:5;33621:12;;33564:75;;;:::o;33645:269::-;33755:39;33786:7;33755:39;:::i;:::-;33816:91;33865:41;33889:16;33865:41;:::i;:::-;33857:6;33850:4;33844:11;33816:91;:::i;:::-;33810:4;33803:105;33721:193;33645:269;;;:::o;33920:73::-;33965:3;33920:73;:::o;33999:189::-;34076:32;;:::i;:::-;34117:65;34175:6;34167;34161:4;34117:65;:::i;:::-;34052:136;33999:189;;:::o;34194:186::-;34254:120;34271:3;34264:5;34261:14;34254:120;;;34325:39;34362:1;34355:5;34325:39;:::i;:::-;34298:1;34291:5;34287:13;34278:22;;34254:120;;;34194:186;;:::o;34386:543::-;34487:2;34482:3;34479:11;34476:446;;;34521:38;34553:5;34521:38;:::i;:::-;34605:29;34623:10;34605:29;:::i;:::-;34595:8;34591:44;34788:2;34776:10;34773:18;34770:49;;;34809:8;34794:23;;34770:49;34832:80;34888:22;34906:3;34888:22;:::i;:::-;34878:8;34874:37;34861:11;34832:80;:::i;:::-;34491:431;;34476:446;34386:543;;;:::o;34935:117::-;34989:8;35039:5;35033:4;35029:16;35008:37;;34935:117;;;;:::o;35058:169::-;35102:6;35135:51;35183:1;35179:6;35171:5;35168:1;35164:13;35135:51;:::i;:::-;35131:56;35216:4;35210;35206:15;35196:25;;35109:118;35058:169;;;;:::o;35232:295::-;35308:4;35454:29;35479:3;35473:4;35454:29;:::i;:::-;35446:37;;35516:3;35513:1;35509:11;35503:4;35500:21;35492:29;;35232:295;;;;:::o;35532:1395::-;35649:37;35682:3;35649:37;:::i;:::-;35751:18;35743:6;35740:30;35737:56;;;35773:18;;:::i;:::-;35737:56;35817:38;35849:4;35843:11;35817:38;:::i;:::-;35902:67;35962:6;35954;35948:4;35902:67;:::i;:::-;35996:1;36020:4;36007:17;;36052:2;36044:6;36041:14;36069:1;36064:618;;;;36726:1;36743:6;36740:77;;;36792:9;36787:3;36783:19;36777:26;36768:35;;36740:77;36843:67;36903:6;36896:5;36843:67;:::i;:::-;36837:4;36830:81;36699:222;36034:887;;36064:618;36116:4;36112:9;36104:6;36100:22;36150:37;36182:4;36150:37;:::i;:::-;36209:1;36223:208;36237:7;36234:1;36231:14;36223:208;;;36316:9;36311:3;36307:19;36301:26;36293:6;36286:42;36367:1;36359:6;36355:14;36345:24;;36414:2;36403:9;36399:18;36386:31;;36260:4;36257:1;36253:12;36248:17;;36223:208;;;36459:6;36450:7;36447:19;36444:179;;;36517:9;36512:3;36508:19;36502:26;36560:48;36602:4;36594:6;36590:17;36579:9;36560:48;:::i;:::-;36552:6;36545:64;36467:156;36444:179;36669:1;36665;36657:6;36653:14;36649:22;36643:4;36636:36;36071:611;;;36034:887;;35624:1303;;;35532:1395;;:::o;36933:148::-;37035:11;37072:3;37057:18;;36933:148;;;;:::o;37087:390::-;37193:3;37221:39;37254:5;37221:39;:::i;:::-;37276:89;37358:6;37353:3;37276:89;:::i;:::-;37269:96;;37374:65;37432:6;37427:3;37420:4;37413:5;37409:16;37374:65;:::i;:::-;37464:6;37459:3;37455:16;37448:23;;37197:280;37087:390;;;;:::o;37483:435::-;37663:3;37685:95;37776:3;37767:6;37685:95;:::i;:::-;37678:102;;37797:95;37888:3;37879:6;37797:95;:::i;:::-;37790:102;;37909:3;37902:10;;37483:435;;;;;:::o;37924:225::-;38064:34;38060:1;38052:6;38048:14;38041:58;38133:8;38128:2;38120:6;38116:15;38109:33;37924:225;:::o;38155:366::-;38297:3;38318:67;38382:2;38377:3;38318:67;:::i;:::-;38311:74;;38394:93;38483:3;38394:93;:::i;:::-;38512:2;38507:3;38503:12;38496:19;;38155:366;;;:::o;38527:419::-;38693:4;38731:2;38720:9;38716:18;38708:26;;38780:9;38774:4;38770:20;38766:1;38755:9;38751:17;38744:47;38808:131;38934:4;38808:131;:::i;:::-;38800:139;;38527:419;;;:::o;38952:332::-;39073:4;39111:2;39100:9;39096:18;39088:26;;39124:71;39192:1;39181:9;39177:17;39168:6;39124:71;:::i;:::-;39205:72;39273:2;39262:9;39258:18;39249:6;39205:72;:::i;:::-;38952:332;;;;;:::o;39290:182::-;39430:34;39426:1;39418:6;39414:14;39407:58;39290:182;:::o;39478:366::-;39620:3;39641:67;39705:2;39700:3;39641:67;:::i;:::-;39634:74;;39717:93;39806:3;39717:93;:::i;:::-;39835:2;39830:3;39826:12;39819:19;;39478:366;;;:::o;39850:419::-;40016:4;40054:2;40043:9;40039:18;40031:26;;40103:9;40097:4;40093:20;40089:1;40078:9;40074:17;40067:47;40131:131;40257:4;40131:131;:::i;:::-;40123:139;;39850:419;;;:::o;40275:181::-;40415:33;40411:1;40403:6;40399:14;40392:57;40275:181;:::o;40462:366::-;40604:3;40625:67;40689:2;40684:3;40625:67;:::i;:::-;40618:74;;40701:93;40790:3;40701:93;:::i;:::-;40819:2;40814:3;40810:12;40803:19;;40462:366;;;:::o;40834:419::-;41000:4;41038:2;41027:9;41023:18;41015:26;;41087:9;41081:4;41077:20;41073:1;41062:9;41058:17;41051:47;41115:131;41241:4;41115:131;:::i;:::-;41107:139;;40834:419;;;:::o;41259:79::-;41298:7;41327:5;41316:16;;41259:79;;;:::o;41344:157::-;41449:45;41469:24;41487:5;41469:24;:::i;:::-;41449:45;:::i;:::-;41444:3;41437:58;41344:157;;:::o;41507:256::-;41619:3;41634:75;41705:3;41696:6;41634:75;:::i;:::-;41734:2;41729:3;41725:12;41718:19;;41754:3;41747:10;;41507:256;;;;:::o;41769:98::-;41820:6;41854:5;41848:12;41838:22;;41769:98;;;:::o;41873:168::-;41956:11;41990:6;41985:3;41978:19;42030:4;42025:3;42021:14;42006:29;;41873:168;;;;:::o;42047:373::-;42133:3;42161:38;42193:5;42161:38;:::i;:::-;42215:70;42278:6;42273:3;42215:70;:::i;:::-;42208:77;;42294:65;42352:6;42347:3;42340:4;42333:5;42329:16;42294:65;:::i;:::-;42384:29;42406:6;42384:29;:::i;:::-;42379:3;42375:39;42368:46;;42137:283;42047:373;;;;:::o;42426:640::-;42621:4;42659:3;42648:9;42644:19;42636:27;;42673:71;42741:1;42730:9;42726:17;42717:6;42673:71;:::i;:::-;42754:72;42822:2;42811:9;42807:18;42798:6;42754:72;:::i;:::-;42836;42904:2;42893:9;42889:18;42880:6;42836:72;:::i;:::-;42955:9;42949:4;42945:20;42940:2;42929:9;42925:18;42918:48;42983:76;43054:4;43045:6;42983:76;:::i;:::-;42975:84;;42426:640;;;;;;;:::o;43072:141::-;43128:5;43159:6;43153:13;43144:22;;43175:32;43201:5;43175:32;:::i;:::-;43072:141;;;;:::o;43219:349::-;43288:6;43337:2;43325:9;43316:7;43312:23;43308:32;43305:119;;;43343:79;;:::i;:::-;43305:119;43463:1;43488:63;43543:7;43534:6;43523:9;43519:22;43488:63;:::i;:::-;43478:73;;43434:127;43219:349;;;;:::o;43574:233::-;43613:3;43636:24;43654:5;43636:24;:::i;:::-;43627:33;;43682:66;43675:5;43672:77;43669:103;;43752:18;;:::i;:::-;43669:103;43799:1;43792:5;43788:13;43781:20;;43574:233;;;:::o
Swarm Source
ipfs://af7e065803e72bc53afc7e2c2c1a3f58689227bd340a8ba7a02685a16761f244
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.