ERC-721
Overview
Max Total Supply
999 MarsMask
Holders
289
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 MarsMaskLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Mars4Masks
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-01-24 */ // Sources flattened with hardhat v2.12.6 https://hardhat.org // File @openzeppelin/contracts/utils/[email protected] // 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; } } // File @openzeppelin/contracts/access/[email protected] // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File @openzeppelin/contracts/utils/cryptography/[email protected] // OpenZeppelin Contracts (last updated v4.8.0) (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 rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * 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 rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } } // File erc721a/contracts/[email protected] // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); } // File erc721a/contracts/[email protected] // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr) if (curr < _currentIndex) { uint256 packed = _packedOwnerships[curr]; // If not burned. if (packed & _BITMASK_BURNED == 0) { // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `curr` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) public payable virtual override { address owner = ownerOf(tokenId); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned. } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 toMasked; uint256 end = startTokenId + quantity; // Use assembly to loop and emit the `Transfer` event for gas savings. // The duplicated `log4` removes an extra check and reduces stack juggling. // The assembly, together with the surrounding Solidity code, have been // delicately arranged to nudge the compiler into producing optimized opcodes. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. startTokenId // `tokenId`. ) // The `iszero(eq(,))` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. // The compiler will optimize the `iszero` away for performance. for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } if (toMasked == 0) revert MintToZeroAddress(); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } } // File erc721a/contracts/extensions/[email protected] // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721AQueryable. */ interface IERC721AQueryable is IERC721A { /** * Invalid query range (`start` >= `stop`). */ error InvalidQueryRange(); /** * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting. * * If the `tokenId` is out of bounds: * * - `addr = address(0)` * - `startTimestamp = 0` * - `burned = false` * - `extraData = 0` * * If the `tokenId` is burned: * * - `addr = <Address of owner before token was burned>` * - `startTimestamp = <Timestamp when token was burned>` * - `burned = true` * - `extraData = <Extra data when token was burned>` * * Otherwise: * * - `addr = <Address of owner>` * - `startTimestamp = <Timestamp of start of ownership>` * - `burned = false` * - `extraData = <Extra data at start of ownership>` */ function explicitOwnershipOf(uint256 tokenId) external view returns (TokenOwnership memory); /** * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order. * See {ERC721AQueryable-explicitOwnershipOf} */ function explicitOwnershipsOf(uint256[] memory tokenIds) external view returns (TokenOwnership[] memory); /** * @dev Returns an array of token IDs owned by `owner`, * in the range [`start`, `stop`) * (i.e. `start <= tokenId < stop`). * * This function allows for tokens to be queried if the collection * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}. * * Requirements: * * - `start < stop` */ function tokensOfOwnerIn( address owner, uint256 start, uint256 stop ) external view returns (uint256[] memory); /** * @dev Returns an array of token IDs owned by `owner`. * * This function scans the ownership mapping and is O(`totalSupply`) in complexity. * It is meant to be called off-chain. * * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into * multiple smaller scans if the collection is large enough to cause * an out-of-gas error (10K collections should be fine). */ function tokensOfOwner(address owner) external view returns (uint256[] memory); } // File erc721a/contracts/extensions/[email protected] // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @title ERC721AQueryable. * * @dev ERC721A subclass with convenience query functions. */ abstract contract ERC721AQueryable is ERC721A, IERC721AQueryable { /** * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting. * * If the `tokenId` is out of bounds: * * - `addr = address(0)` * - `startTimestamp = 0` * - `burned = false` * - `extraData = 0` * * If the `tokenId` is burned: * * - `addr = <Address of owner before token was burned>` * - `startTimestamp = <Timestamp when token was burned>` * - `burned = true` * - `extraData = <Extra data when token was burned>` * * Otherwise: * * - `addr = <Address of owner>` * - `startTimestamp = <Timestamp of start of ownership>` * - `burned = false` * - `extraData = <Extra data at start of ownership>` */ function explicitOwnershipOf(uint256 tokenId) public view virtual override returns (TokenOwnership memory) { TokenOwnership memory ownership; if (tokenId < _startTokenId() || tokenId >= _nextTokenId()) { return ownership; } ownership = _ownershipAt(tokenId); if (ownership.burned) { return ownership; } return _ownershipOf(tokenId); } /** * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order. * See {ERC721AQueryable-explicitOwnershipOf} */ function explicitOwnershipsOf(uint256[] calldata tokenIds) external view virtual override returns (TokenOwnership[] memory) { unchecked { uint256 tokenIdsLength = tokenIds.length; TokenOwnership[] memory ownerships = new TokenOwnership[](tokenIdsLength); for (uint256 i; i != tokenIdsLength; ++i) { ownerships[i] = explicitOwnershipOf(tokenIds[i]); } return ownerships; } } /** * @dev Returns an array of token IDs owned by `owner`, * in the range [`start`, `stop`) * (i.e. `start <= tokenId < stop`). * * This function allows for tokens to be queried if the collection * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}. * * Requirements: * * - `start < stop` */ function tokensOfOwnerIn( address owner, uint256 start, uint256 stop ) external view virtual override returns (uint256[] memory) { unchecked { if (start >= stop) revert InvalidQueryRange(); uint256 tokenIdsIdx; uint256 stopLimit = _nextTokenId(); // Set `start = max(start, _startTokenId())`. if (start < _startTokenId()) { start = _startTokenId(); } // Set `stop = min(stop, stopLimit)`. if (stop > stopLimit) { stop = stopLimit; } uint256 tokenIdsMaxLength = balanceOf(owner); // Set `tokenIdsMaxLength = min(balanceOf(owner), stop - start)`, // to cater for cases where `balanceOf(owner)` is too big. if (start < stop) { uint256 rangeLength = stop - start; if (rangeLength < tokenIdsMaxLength) { tokenIdsMaxLength = rangeLength; } } else { tokenIdsMaxLength = 0; } uint256[] memory tokenIds = new uint256[](tokenIdsMaxLength); if (tokenIdsMaxLength == 0) { return tokenIds; } // We need to call `explicitOwnershipOf(start)`, // because the slot at `start` may not be initialized. TokenOwnership memory ownership = explicitOwnershipOf(start); address currOwnershipAddr; // If the starting slot exists (i.e. not burned), initialize `currOwnershipAddr`. // `ownership.address` will not be zero, as `start` is clamped to the valid token ID range. if (!ownership.burned) { currOwnershipAddr = ownership.addr; } for (uint256 i = start; i != stop && tokenIdsIdx != tokenIdsMaxLength; ++i) { ownership = _ownershipAt(i); if (ownership.burned) { continue; } if (ownership.addr != address(0)) { currOwnershipAddr = ownership.addr; } if (currOwnershipAddr == owner) { tokenIds[tokenIdsIdx++] = i; } } // Downsize the array to fit. assembly { mstore(tokenIds, tokenIdsIdx) } return tokenIds; } } /** * @dev Returns an array of token IDs owned by `owner`. * * This function scans the ownership mapping and is O(`totalSupply`) in complexity. * It is meant to be called off-chain. * * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into * multiple smaller scans if the collection is large enough to cause * an out-of-gas error (10K collections should be fine). */ function tokensOfOwner(address owner) external view virtual override returns (uint256[] memory) { unchecked { uint256 tokenIdsIdx; address currOwnershipAddr; uint256 tokenIdsLength = balanceOf(owner); uint256[] memory tokenIds = new uint256[](tokenIdsLength); TokenOwnership memory ownership; for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) { ownership = _ownershipAt(i); if (ownership.burned) { continue; } if (ownership.addr != address(0)) { currOwnershipAddr = ownership.addr; } if (currOwnershipAddr == owner) { tokenIds[tokenIdsIdx++] = i; } } return tokenIds; } } } // File contracts/Mars4Masks.sol pragma solidity ^0.8.17; contract Mars4Masks is ERC721AQueryable, Ownable { enum Stage { Closed, Whitelist, Public } uint256 public constant MAX_SUPPLY = 999; uint256 public price = 0; Stage public stage = Stage.Closed; string public baseTokenURI = 'https://mars4-masks.fra1.cdn.digitaloceanspaces.com/metadata/'; string public contractURI = 'https://mars4-masks.fra1.cdn.digitaloceanspaces.com/metadata.json'; bytes32 private merkleRoot; constructor() ERC721A("Mars4 Masks", "MarsMask") {} function setStage(Stage newStage, uint256 newPrice) external onlyOwner { stage = newStage; price = newPrice; } function getStage() public view returns (string memory) { if (stage == Stage.Closed) { return "Closed"; } else if (stage == Stage.Whitelist) { return "Whitelist"; } else { return "Public"; } } function buy(uint256 amount) external payable { require(stage == Stage.Public, "Public sale is closed"); require(totalSupply() + amount <= MAX_SUPPLY, "Insufficient token supply"); require(msg.value >= amount * price, "Amount invalid"); _mint(msg.sender, amount); } function buy(uint256 amount, bytes32[] memory proof) external payable { require(stage == Stage.Whitelist, "Whitelist sale is closed"); require(totalSupply() + amount <= MAX_SUPPLY, "Insufficient token supply"); require(merkleRoot != "", "Whitelist is empty"); require( MerkleProof.verify( proof, merkleRoot, keccak256(abi.encodePacked(msg.sender)) ), "Invalid proof" ); require(msg.value >= amount * price, "Amount invalid"); _mint(msg.sender, amount); } function mint(uint256 amount, address to) external onlyOwner { require(totalSupply() + amount <= MAX_SUPPLY, "Insufficient token supply"); _safeMint(to, amount); } function withdraw() external onlyOwner { (bool success, ) = owner().call{ value: address(this).balance }(""); require(success, "Failed to withdraw"); } function _startTokenId() internal pure override returns (uint256) { return 1; } function _baseURI() internal view override returns (string memory) { return baseTokenURI; } function setMerkleRoot(bytes32 newMerkleRoot) external onlyOwner { merkleRoot = newMerkleRoot; } function setContractURI(string memory newUri) external onlyOwner { contractURI = newUri; } function setTokenURI(string memory newUri) external onlyOwner { baseTokenURI = newUri; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"contractURI","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":[],"name":"getStage","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","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":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newUri","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"newMerkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum Mars4Masks.Stage","name":"newStage","type":"uint8"},{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"setStage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newUri","type":"string"}],"name":"setTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stage","outputs":[{"internalType":"enum Mars4Masks.Stage","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"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":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405260006009556000600a60006101000a81548160ff0219169083600281111562000032576200003162000240565b5b02179055506040518060600160405280603d815260200162004637603d9139600b9081620000619190620004e9565b50604051806080016040528060418152602001620045f660419139600c90816200008c9190620004e9565b503480156200009a57600080fd5b506040518060400160405280600b81526020017f4d61727334204d61736b730000000000000000000000000000000000000000008152506040518060400160405280600881526020017f4d6172734d61736b0000000000000000000000000000000000000000000000008152508160029081620001189190620004e9565b5080600390816200012a9190620004e9565b506200013b6200016960201b60201c565b600081905550505062000163620001576200017260201b60201c565b6200017a60201b60201c565b620005d0565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620002f157607f821691505b602082108103620003075762000306620002a9565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620003717fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000332565b6200037d868362000332565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620003ca620003c4620003be8462000395565b6200039f565b62000395565b9050919050565b6000819050919050565b620003e683620003a9565b620003fe620003f582620003d1565b8484546200033f565b825550505050565b600090565b6200041562000406565b62000422818484620003db565b505050565b5b818110156200044a576200043e6000826200040b565b60018101905062000428565b5050565b601f821115620004995762000463816200030d565b6200046e8462000322565b810160208510156200047e578190505b620004966200048d8562000322565b83018262000427565b50505b505050565b600082821c905092915050565b6000620004be600019846008026200049e565b1980831691505092915050565b6000620004d98383620004ab565b9150826002028217905092915050565b620004f4826200026f565b67ffffffffffffffff81111562000510576200050f6200027a565b5b6200051c8254620002d8565b620005298282856200044e565b600060209050601f8311600181146200056157600084156200054c578287015190505b620005588582620004cb565b865550620005c8565b601f19841662000571866200030d565b60005b828110156200059b5784890151825560018201915060208501945060208101905062000574565b86831015620005bb5784890151620005b7601f891682620004ab565b8355505b6001600288020188555050505b505050505050565b61401680620005e06000396000f3fe6080604052600436106102045760003560e01c8063938e3d7b11610118578063c87b56dd116100a0578063e0df5b6f1161006f578063e0df5b6f14610729578063e8a3d48514610752578063e985e9c51461077d578063f2fde38b146107ba578063fcaa7664146107e357610204565b8063c87b56dd1461067c578063ce773649146106b9578063d547cfb7146106e2578063d96a094a1461070d57610204565b8063a035b1fe116100e7578063a035b1fe146105a4578063a22cb465146105cf578063b88d4fde146105f8578063c040e6b814610614578063c23dc68f1461063f57610204565b8063938e3d7b146104ea57806394bf804d1461051357806395d89b411461053c57806399a2557a1461056757610204565b806342842e0e1161019b57806370a082311161016a57806370a0823114610405578063715018a6146104425780637cb64759146104595780638462151c146104825780638da5cb5b146104bf57610204565b806342842e0e146103535780635a19b4db1461036f5780635bbb21771461038b5780636352211e146103c857610204565b806318160ddd116101d757806318160ddd146102ca57806323b872dd146102f557806332cb6b0c146103115780633ccfd60b1461033c57610204565b806301ffc9a71461020957806306fdde0314610246578063081812fc14610271578063095ea7b3146102ae575b600080fd5b34801561021557600080fd5b50610230600480360381019061022b9190612942565b61080e565b60405161023d919061298a565b60405180910390f35b34801561025257600080fd5b5061025b6108a0565b6040516102689190612a35565b60405180910390f35b34801561027d57600080fd5b5061029860048036038101906102939190612a8d565b610932565b6040516102a59190612afb565b60405180910390f35b6102c860048036038101906102c39190612b42565b6109b1565b005b3480156102d657600080fd5b506102df610af5565b6040516102ec9190612b91565b60405180910390f35b61030f600480360381019061030a9190612bac565b610b0c565b005b34801561031d57600080fd5b50610326610e2e565b6040516103339190612b91565b60405180910390f35b34801561034857600080fd5b50610351610e34565b005b61036d60048036038101906103689190612bac565b610ef2565b005b61038960048036038101906103849190612d7d565b610f12565b005b34801561039757600080fd5b506103b260048036038101906103ad9190612e34565b6110f4565b6040516103bf9190612fe4565b60405180910390f35b3480156103d457600080fd5b506103ef60048036038101906103ea9190612a8d565b6111b7565b6040516103fc9190612afb565b60405180910390f35b34801561041157600080fd5b5061042c60048036038101906104279190613006565b6111c9565b6040516104399190612b91565b60405180910390f35b34801561044e57600080fd5b50610457611281565b005b34801561046557600080fd5b50610480600480360381019061047b9190613033565b611295565b005b34801561048e57600080fd5b506104a960048036038101906104a49190613006565b6112a7565b6040516104b6919061311e565b60405180910390f35b3480156104cb57600080fd5b506104d46113ea565b6040516104e19190612afb565b60405180910390f35b3480156104f657600080fd5b50610511600480360381019061050c91906131f5565b611414565b005b34801561051f57600080fd5b5061053a6004803603810190610535919061323e565b61142f565b005b34801561054857600080fd5b5061055161149c565b60405161055e9190612a35565b60405180910390f35b34801561057357600080fd5b5061058e6004803603810190610589919061327e565b61152e565b60405161059b919061311e565b60405180910390f35b3480156105b057600080fd5b506105b961173a565b6040516105c69190612b91565b60405180910390f35b3480156105db57600080fd5b506105f660048036038101906105f191906132fd565b611740565b005b610612600480360381019061060d91906133de565b61184b565b005b34801561062057600080fd5b506106296118be565b60405161063691906134d8565b60405180910390f35b34801561064b57600080fd5b5061066660048036038101906106619190612a8d565b6118d1565b6040516106739190613548565b60405180910390f35b34801561068857600080fd5b506106a3600480360381019061069e9190612a8d565b61193b565b6040516106b09190612a35565b60405180910390f35b3480156106c557600080fd5b506106e060048036038101906106db9190613588565b6119d9565b005b3480156106ee57600080fd5b506106f7611a16565b6040516107049190612a35565b60405180910390f35b61072760048036038101906107229190612a8d565b611aa4565b005b34801561073557600080fd5b50610750600480360381019061074b91906131f5565b611bcd565b005b34801561075e57600080fd5b50610767611be8565b6040516107749190612a35565b60405180910390f35b34801561078957600080fd5b506107a4600480360381019061079f91906135c8565b611c76565b6040516107b1919061298a565b60405180910390f35b3480156107c657600080fd5b506107e160048036038101906107dc9190613006565b611d0a565b005b3480156107ef57600080fd5b506107f8611d8d565b6040516108059190612a35565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061086957506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108995750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6060600280546108af90613637565b80601f01602080910402602001604051908101604052809291908181526020018280546108db90613637565b80156109285780601f106108fd57610100808354040283529160200191610928565b820191906000526020600020905b81548152906001019060200180831161090b57829003601f168201915b5050505050905090565b600061093d82611ebb565b610973576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006109bc826111b7565b90508073ffffffffffffffffffffffffffffffffffffffff166109dd611f1a565b73ffffffffffffffffffffffffffffffffffffffff1614610a4057610a0981610a04611f1a565b611c76565b610a3f576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610aff611f22565b6001546000540303905090565b6000610b1782611f2b565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b7e576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610b8a84611ff7565b91509150610ba08187610b9b611f1a565b61201e565b610bec57610bb586610bb0611f1a565b611c76565b610beb576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610c52576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c5f8686866001612062565b8015610c6a57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610d3885610d14888887612068565b7c020000000000000000000000000000000000000000000000000000000017612090565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610dbe5760006001850190506000600460008381526020019081526020016000205403610dbc576000548114610dbb578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610e2686868660016120bb565b505050505050565b6103e781565b610e3c6120c1565b6000610e466113ea565b73ffffffffffffffffffffffffffffffffffffffff1647604051610e6990613699565b60006040518083038185875af1925050503d8060008114610ea6576040519150601f19603f3d011682016040523d82523d6000602084013e610eab565b606091505b5050905080610eef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee6906136fa565b60405180910390fd5b50565b610f0d8383836040518060200160405280600081525061184b565b505050565b60016002811115610f2657610f25613461565b5b600a60009054906101000a900460ff166002811115610f4857610f47613461565b5b14610f88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7f90613766565b60405180910390fd5b6103e782610f94610af5565b610f9e91906137b5565b1115610fdf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd690613835565b60405180910390fd5b6000600d5403611024576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101b906138a1565b60405180910390fd5b61105781600d543360405160200161103c9190613909565b6040516020818303038152906040528051906020012061213f565b611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108d90613970565b60405180910390fd5b600954826110a49190613990565b3410156110e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110dd90613a1e565b60405180910390fd5b6110f03383612156565b5050565b6060600083839050905060008167ffffffffffffffff81111561111a57611119612c04565b5b60405190808252806020026020018201604052801561115357816020015b611140612887565b8152602001906001900390816111385790505b50905060005b8281146111ab5761118286868381811061117657611175613a3e565b5b905060200201356118d1565b82828151811061119557611194613a3e565b5b6020026020010181905250806001019050611159565b50809250505092915050565b60006111c282611f2b565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611230576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6112896120c1565b6112936000612311565b565b61129d6120c1565b80600d8190555050565b606060008060006112b7856111c9565b905060008167ffffffffffffffff8111156112d5576112d4612c04565b5b6040519080825280602002602001820160405280156113035781602001602082028036833780820191505090505b50905061130e612887565b6000611318611f22565b90505b8386146113dc5761132b816123d7565b915081604001516113d157600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff161461137657816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036113d057808387806001019850815181106113c3576113c2613a3e565b5b6020026020010181815250505b5b80600101905061131b565b508195505050505050919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61141c6120c1565b80600c908161142b9190613c19565b5050565b6114376120c1565b6103e782611443610af5565b61144d91906137b5565b111561148e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161148590613835565b60405180910390fd5b6114988183612402565b5050565b6060600380546114ab90613637565b80601f01602080910402602001604051908101604052809291908181526020018280546114d790613637565b80156115245780601f106114f957610100808354040283529160200191611524565b820191906000526020600020905b81548152906001019060200180831161150757829003601f168201915b5050505050905090565b6060818310611569576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080611574612420565b905061157e611f22565b8510156115905761158d611f22565b94505b8084111561159c578093505b60006115a7876111c9565b9050848610156115ca5760008686039050818110156115c4578091505b506115cf565b600090505b60008167ffffffffffffffff8111156115eb576115ea612c04565b5b6040519080825280602002602001820160405280156116195781602001602082028036833780820191505090505b509050600082036116305780945050505050611733565b600061163b886118d1565b90506000816040015161165057816000015190505b60008990505b8881141580156116665750848714155b1561172557611674816123d7565b9250826040015161171a57600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16146116bf57826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611719578084888060010199508151811061170c5761170b613a3e565b5b6020026020010181815250505b5b806001019050611656565b508583528296505050505050505b9392505050565b60095481565b806007600061174d611f1a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166117fa611f1a565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161183f919061298a565b60405180910390a35050565b611856848484610b0c565b60008373ffffffffffffffffffffffffffffffffffffffff163b146118b85761188184848484612429565b6118b7576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b600a60009054906101000a900460ff1681565b6118d9612887565b6118e1612887565b6118e9611f22565b8310806118fd57506118f9612420565b8310155b1561190b5780915050611936565b611914836123d7565b90508060400151156119295780915050611936565b61193283612579565b9150505b919050565b606061194682611ebb565b61197c576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611986612599565b905060008151036119a657604051806020016040528060008152506119d1565b806119b08461262b565b6040516020016119c1929190613d27565b6040516020818303038152906040525b915050919050565b6119e16120c1565b81600a60006101000a81548160ff02191690836002811115611a0657611a05613461565b5b0217905550806009819055505050565b600b8054611a2390613637565b80601f0160208091040260200160405190810160405280929190818152602001828054611a4f90613637565b8015611a9c5780601f10611a7157610100808354040283529160200191611a9c565b820191906000526020600020905b815481529060010190602001808311611a7f57829003601f168201915b505050505081565b600280811115611ab757611ab6613461565b5b600a60009054906101000a900460ff166002811115611ad957611ad8613461565b5b14611b19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1090613d97565b60405180910390fd5b6103e781611b25610af5565b611b2f91906137b5565b1115611b70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b6790613835565b60405180910390fd5b60095481611b7e9190613990565b341015611bc0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bb790613a1e565b60405180910390fd5b611bca3382612156565b50565b611bd56120c1565b80600b9081611be49190613c19565b5050565b600c8054611bf590613637565b80601f0160208091040260200160405190810160405280929190818152602001828054611c2190613637565b8015611c6e5780601f10611c4357610100808354040283529160200191611c6e565b820191906000526020600020905b815481529060010190602001808311611c5157829003601f168201915b505050505081565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611d126120c1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7890613e29565b60405180910390fd5b611d8a81612311565b50565b606060006002811115611da357611da2613461565b5b600a60009054906101000a900460ff166002811115611dc557611dc4613461565b5b03611e07576040518060400160405280600681526020017f436c6f73656400000000000000000000000000000000000000000000000000008152509050611eb8565b60016002811115611e1b57611e1a613461565b5b600a60009054906101000a900460ff166002811115611e3d57611e3c613461565b5b03611e7f576040518060400160405280600981526020017f57686974656c69737400000000000000000000000000000000000000000000008152509050611eb8565b6040518060400160405280600681526020017f5075626c6963000000000000000000000000000000000000000000000000000081525090505b90565b600081611ec6611f22565b11158015611ed5575060005482105b8015611f13575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b60008082905080611f3a611f22565b11611fc057600054811015611fbf5760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611fbd575b60008103611fb3576004600083600190039350838152602001908152602001600020549050611f89565b8092505050611ff2565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e861207f86868461267b565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6120c9612684565b73ffffffffffffffffffffffffffffffffffffffff166120e76113ea565b73ffffffffffffffffffffffffffffffffffffffff161461213d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213490613e95565b60405180910390fd5b565b60008261214c858461268c565b1490509392505050565b60008054905060008203612196576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6121a36000848385612062565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061221a8361220b6000866000612068565b612214856126e2565b17612090565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146122bb57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612280565b50600082036122f6576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061230c60008483856120bb565b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6123df612887565b6123fb60046000848152602001908152602001600020546126f2565b9050919050565b61241c8282604051806020016040528060008152506127a8565b5050565b60008054905090565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261244f611f1a565b8786866040518563ffffffff1660e01b81526004016124719493929190613f0a565b6020604051808303816000875af19250505080156124ad57506040513d601f19601f820116820180604052508101906124aa9190613f6b565b60015b612526573d80600081146124dd576040519150601f19603f3d011682016040523d82523d6000602084013e6124e2565b606091505b50600081510361251e576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b612581612887565b61259261258d83611f2b565b6126f2565b9050919050565b6060600b80546125a890613637565b80601f01602080910402602001604051908101604052809291908181526020018280546125d490613637565b80156126215780601f106125f657610100808354040283529160200191612621565b820191906000526020600020905b81548152906001019060200180831161260457829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b60011561266657600184039350600a81066030018453600a8104905080612644575b50828103602084039350808452505050919050565b60009392505050565b600033905090565b60008082905060005b84518110156126d7576126c2828683815181106126b5576126b4613a3e565b5b6020026020010151612845565b915080806126cf90613f98565b915050612695565b508091505092915050565b60006001821460e11b9050919050565b6126fa612887565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b6127b28383612156565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461284057600080549050600083820390505b6127f26000868380600101945086612429565b612828576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181106127df57816000541461283d57600080fd5b50505b505050565b600081831061285d576128588284612870565b612868565b6128678383612870565b5b905092915050565b600082600052816020526040600020905092915050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61291f816128ea565b811461292a57600080fd5b50565b60008135905061293c81612916565b92915050565b600060208284031215612958576129576128e0565b5b60006129668482850161292d565b91505092915050565b60008115159050919050565b6129848161296f565b82525050565b600060208201905061299f600083018461297b565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156129df5780820151818401526020810190506129c4565b60008484015250505050565b6000601f19601f8301169050919050565b6000612a07826129a5565b612a1181856129b0565b9350612a218185602086016129c1565b612a2a816129eb565b840191505092915050565b60006020820190508181036000830152612a4f81846129fc565b905092915050565b6000819050919050565b612a6a81612a57565b8114612a7557600080fd5b50565b600081359050612a8781612a61565b92915050565b600060208284031215612aa357612aa26128e0565b5b6000612ab184828501612a78565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612ae582612aba565b9050919050565b612af581612ada565b82525050565b6000602082019050612b106000830184612aec565b92915050565b612b1f81612ada565b8114612b2a57600080fd5b50565b600081359050612b3c81612b16565b92915050565b60008060408385031215612b5957612b586128e0565b5b6000612b6785828601612b2d565b9250506020612b7885828601612a78565b9150509250929050565b612b8b81612a57565b82525050565b6000602082019050612ba66000830184612b82565b92915050565b600080600060608486031215612bc557612bc46128e0565b5b6000612bd386828701612b2d565b9350506020612be486828701612b2d565b9250506040612bf586828701612a78565b9150509250925092565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612c3c826129eb565b810181811067ffffffffffffffff82111715612c5b57612c5a612c04565b5b80604052505050565b6000612c6e6128d6565b9050612c7a8282612c33565b919050565b600067ffffffffffffffff821115612c9a57612c99612c04565b5b602082029050602081019050919050565b600080fd5b6000819050919050565b612cc381612cb0565b8114612cce57600080fd5b50565b600081359050612ce081612cba565b92915050565b6000612cf9612cf484612c7f565b612c64565b90508083825260208201905060208402830185811115612d1c57612d1b612cab565b5b835b81811015612d455780612d318882612cd1565b845260208401935050602081019050612d1e565b5050509392505050565b600082601f830112612d6457612d63612bff565b5b8135612d74848260208601612ce6565b91505092915050565b60008060408385031215612d9457612d936128e0565b5b6000612da285828601612a78565b925050602083013567ffffffffffffffff811115612dc357612dc26128e5565b5b612dcf85828601612d4f565b9150509250929050565b600080fd5b60008083601f840112612df457612df3612bff565b5b8235905067ffffffffffffffff811115612e1157612e10612dd9565b5b602083019150836020820283011115612e2d57612e2c612cab565b5b9250929050565b60008060208385031215612e4b57612e4a6128e0565b5b600083013567ffffffffffffffff811115612e6957612e686128e5565b5b612e7585828601612dde565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612eb681612ada565b82525050565b600067ffffffffffffffff82169050919050565b612ed981612ebc565b82525050565b612ee88161296f565b82525050565b600062ffffff82169050919050565b612f0681612eee565b82525050565b608082016000820151612f226000850182612ead565b506020820151612f356020850182612ed0565b506040820151612f486040850182612edf565b506060820151612f5b6060850182612efd565b50505050565b6000612f6d8383612f0c565b60808301905092915050565b6000602082019050919050565b6000612f9182612e81565b612f9b8185612e8c565b9350612fa683612e9d565b8060005b83811015612fd7578151612fbe8882612f61565b9750612fc983612f79565b925050600181019050612faa565b5085935050505092915050565b60006020820190508181036000830152612ffe8184612f86565b905092915050565b60006020828403121561301c5761301b6128e0565b5b600061302a84828501612b2d565b91505092915050565b600060208284031215613049576130486128e0565b5b600061305784828501612cd1565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61309581612a57565b82525050565b60006130a7838361308c565b60208301905092915050565b6000602082019050919050565b60006130cb82613060565b6130d5818561306b565b93506130e08361307c565b8060005b838110156131115781516130f8888261309b565b9750613103836130b3565b9250506001810190506130e4565b5085935050505092915050565b6000602082019050818103600083015261313881846130c0565b905092915050565b600080fd5b600067ffffffffffffffff8211156131605761315f612c04565b5b613169826129eb565b9050602081019050919050565b82818337600083830152505050565b600061319861319384613145565b612c64565b9050828152602081018484840111156131b4576131b3613140565b5b6131bf848285613176565b509392505050565b600082601f8301126131dc576131db612bff565b5b81356131ec848260208601613185565b91505092915050565b60006020828403121561320b5761320a6128e0565b5b600082013567ffffffffffffffff811115613229576132286128e5565b5b613235848285016131c7565b91505092915050565b60008060408385031215613255576132546128e0565b5b600061326385828601612a78565b925050602061327485828601612b2d565b9150509250929050565b600080600060608486031215613297576132966128e0565b5b60006132a586828701612b2d565b93505060206132b686828701612a78565b92505060406132c786828701612a78565b9150509250925092565b6132da8161296f565b81146132e557600080fd5b50565b6000813590506132f7816132d1565b92915050565b60008060408385031215613314576133136128e0565b5b600061332285828601612b2d565b9250506020613333858286016132e8565b9150509250929050565b600067ffffffffffffffff82111561335857613357612c04565b5b613361826129eb565b9050602081019050919050565b600061338161337c8461333d565b612c64565b90508281526020810184848401111561339d5761339c613140565b5b6133a8848285613176565b509392505050565b600082601f8301126133c5576133c4612bff565b5b81356133d584826020860161336e565b91505092915050565b600080600080608085870312156133f8576133f76128e0565b5b600061340687828801612b2d565b945050602061341787828801612b2d565b935050604061342887828801612a78565b925050606085013567ffffffffffffffff811115613449576134486128e5565b5b613455878288016133b0565b91505092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600381106134a1576134a0613461565b5b50565b60008190506134b282613490565b919050565b60006134c2826134a4565b9050919050565b6134d2816134b7565b82525050565b60006020820190506134ed60008301846134c9565b92915050565b6080820160008201516135096000850182612ead565b50602082015161351c6020850182612ed0565b50604082015161352f6040850182612edf565b5060608201516135426060850182612efd565b50505050565b600060808201905061355d60008301846134f3565b92915050565b6003811061357057600080fd5b50565b60008135905061358281613563565b92915050565b6000806040838503121561359f5761359e6128e0565b5b60006135ad85828601613573565b92505060206135be85828601612a78565b9150509250929050565b600080604083850312156135df576135de6128e0565b5b60006135ed85828601612b2d565b92505060206135fe85828601612b2d565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061364f57607f821691505b60208210810361366257613661613608565b5b50919050565b600081905092915050565b50565b6000613683600083613668565b915061368e82613673565b600082019050919050565b60006136a482613676565b9150819050919050565b7f4661696c656420746f2077697468647261770000000000000000000000000000600082015250565b60006136e46012836129b0565b91506136ef826136ae565b602082019050919050565b60006020820190508181036000830152613713816136d7565b9050919050565b7f57686974656c6973742073616c6520697320636c6f7365640000000000000000600082015250565b60006137506018836129b0565b915061375b8261371a565b602082019050919050565b6000602082019050818103600083015261377f81613743565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006137c082612a57565b91506137cb83612a57565b92508282019050808211156137e3576137e2613786565b5b92915050565b7f496e73756666696369656e7420746f6b656e20737570706c7900000000000000600082015250565b600061381f6019836129b0565b915061382a826137e9565b602082019050919050565b6000602082019050818103600083015261384e81613812565b9050919050565b7f57686974656c69737420697320656d7074790000000000000000000000000000600082015250565b600061388b6012836129b0565b915061389682613855565b602082019050919050565b600060208201905081810360008301526138ba8161387e565b9050919050565b60008160601b9050919050565b60006138d9826138c1565b9050919050565b60006138eb826138ce565b9050919050565b6139036138fe82612ada565b6138e0565b82525050565b600061391582846138f2565b60148201915081905092915050565b7f496e76616c69642070726f6f6600000000000000000000000000000000000000600082015250565b600061395a600d836129b0565b915061396582613924565b602082019050919050565b600060208201905081810360008301526139898161394d565b9050919050565b600061399b82612a57565b91506139a683612a57565b92508282026139b481612a57565b915082820484148315176139cb576139ca613786565b5b5092915050565b7f416d6f756e7420696e76616c6964000000000000000000000000000000000000600082015250565b6000613a08600e836129b0565b9150613a13826139d2565b602082019050919050565b60006020820190508181036000830152613a37816139fb565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613acf7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613a92565b613ad98683613a92565b95508019841693508086168417925050509392505050565b6000819050919050565b6000613b16613b11613b0c84612a57565b613af1565b612a57565b9050919050565b6000819050919050565b613b3083613afb565b613b44613b3c82613b1d565b848454613a9f565b825550505050565b600090565b613b59613b4c565b613b64818484613b27565b505050565b5b81811015613b8857613b7d600082613b51565b600181019050613b6a565b5050565b601f821115613bcd57613b9e81613a6d565b613ba784613a82565b81016020851015613bb6578190505b613bca613bc285613a82565b830182613b69565b50505b505050565b600082821c905092915050565b6000613bf060001984600802613bd2565b1980831691505092915050565b6000613c098383613bdf565b9150826002028217905092915050565b613c22826129a5565b67ffffffffffffffff811115613c3b57613c3a612c04565b5b613c458254613637565b613c50828285613b8c565b600060209050601f831160018114613c835760008415613c71578287015190505b613c7b8582613bfd565b865550613ce3565b601f198416613c9186613a6d565b60005b82811015613cb957848901518255600182019150602085019450602081019050613c94565b86831015613cd65784890151613cd2601f891682613bdf565b8355505b6001600288020188555050505b505050505050565b600081905092915050565b6000613d01826129a5565b613d0b8185613ceb565b9350613d1b8185602086016129c1565b80840191505092915050565b6000613d338285613cf6565b9150613d3f8284613cf6565b91508190509392505050565b7f5075626c69632073616c6520697320636c6f7365640000000000000000000000600082015250565b6000613d816015836129b0565b9150613d8c82613d4b565b602082019050919050565b60006020820190508181036000830152613db081613d74565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613e136026836129b0565b9150613e1e82613db7565b604082019050919050565b60006020820190508181036000830152613e4281613e06565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613e7f6020836129b0565b9150613e8a82613e49565b602082019050919050565b60006020820190508181036000830152613eae81613e72565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000613edc82613eb5565b613ee68185613ec0565b9350613ef68185602086016129c1565b613eff816129eb565b840191505092915050565b6000608082019050613f1f6000830187612aec565b613f2c6020830186612aec565b613f396040830185612b82565b8181036060830152613f4b8184613ed1565b905095945050505050565b600081519050613f6581612916565b92915050565b600060208284031215613f8157613f806128e0565b5b6000613f8f84828501613f56565b91505092915050565b6000613fa382612a57565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fd557613fd4613786565b5b60018201905091905056fea26469706673582212202294d02076e334a90fad374186850942d9a0e9068ffc987361a50df53a19357364736f6c6343000811003368747470733a2f2f6d617273342d6d61736b732e667261312e63646e2e6469676974616c6f6365616e7370616365732e636f6d2f6d657461646174612e6a736f6e68747470733a2f2f6d617273342d6d61736b732e667261312e63646e2e6469676974616c6f6365616e7370616365732e636f6d2f6d657461646174612f
Deployed Bytecode
0x6080604052600436106102045760003560e01c8063938e3d7b11610118578063c87b56dd116100a0578063e0df5b6f1161006f578063e0df5b6f14610729578063e8a3d48514610752578063e985e9c51461077d578063f2fde38b146107ba578063fcaa7664146107e357610204565b8063c87b56dd1461067c578063ce773649146106b9578063d547cfb7146106e2578063d96a094a1461070d57610204565b8063a035b1fe116100e7578063a035b1fe146105a4578063a22cb465146105cf578063b88d4fde146105f8578063c040e6b814610614578063c23dc68f1461063f57610204565b8063938e3d7b146104ea57806394bf804d1461051357806395d89b411461053c57806399a2557a1461056757610204565b806342842e0e1161019b57806370a082311161016a57806370a0823114610405578063715018a6146104425780637cb64759146104595780638462151c146104825780638da5cb5b146104bf57610204565b806342842e0e146103535780635a19b4db1461036f5780635bbb21771461038b5780636352211e146103c857610204565b806318160ddd116101d757806318160ddd146102ca57806323b872dd146102f557806332cb6b0c146103115780633ccfd60b1461033c57610204565b806301ffc9a71461020957806306fdde0314610246578063081812fc14610271578063095ea7b3146102ae575b600080fd5b34801561021557600080fd5b50610230600480360381019061022b9190612942565b61080e565b60405161023d919061298a565b60405180910390f35b34801561025257600080fd5b5061025b6108a0565b6040516102689190612a35565b60405180910390f35b34801561027d57600080fd5b5061029860048036038101906102939190612a8d565b610932565b6040516102a59190612afb565b60405180910390f35b6102c860048036038101906102c39190612b42565b6109b1565b005b3480156102d657600080fd5b506102df610af5565b6040516102ec9190612b91565b60405180910390f35b61030f600480360381019061030a9190612bac565b610b0c565b005b34801561031d57600080fd5b50610326610e2e565b6040516103339190612b91565b60405180910390f35b34801561034857600080fd5b50610351610e34565b005b61036d60048036038101906103689190612bac565b610ef2565b005b61038960048036038101906103849190612d7d565b610f12565b005b34801561039757600080fd5b506103b260048036038101906103ad9190612e34565b6110f4565b6040516103bf9190612fe4565b60405180910390f35b3480156103d457600080fd5b506103ef60048036038101906103ea9190612a8d565b6111b7565b6040516103fc9190612afb565b60405180910390f35b34801561041157600080fd5b5061042c60048036038101906104279190613006565b6111c9565b6040516104399190612b91565b60405180910390f35b34801561044e57600080fd5b50610457611281565b005b34801561046557600080fd5b50610480600480360381019061047b9190613033565b611295565b005b34801561048e57600080fd5b506104a960048036038101906104a49190613006565b6112a7565b6040516104b6919061311e565b60405180910390f35b3480156104cb57600080fd5b506104d46113ea565b6040516104e19190612afb565b60405180910390f35b3480156104f657600080fd5b50610511600480360381019061050c91906131f5565b611414565b005b34801561051f57600080fd5b5061053a6004803603810190610535919061323e565b61142f565b005b34801561054857600080fd5b5061055161149c565b60405161055e9190612a35565b60405180910390f35b34801561057357600080fd5b5061058e6004803603810190610589919061327e565b61152e565b60405161059b919061311e565b60405180910390f35b3480156105b057600080fd5b506105b961173a565b6040516105c69190612b91565b60405180910390f35b3480156105db57600080fd5b506105f660048036038101906105f191906132fd565b611740565b005b610612600480360381019061060d91906133de565b61184b565b005b34801561062057600080fd5b506106296118be565b60405161063691906134d8565b60405180910390f35b34801561064b57600080fd5b5061066660048036038101906106619190612a8d565b6118d1565b6040516106739190613548565b60405180910390f35b34801561068857600080fd5b506106a3600480360381019061069e9190612a8d565b61193b565b6040516106b09190612a35565b60405180910390f35b3480156106c557600080fd5b506106e060048036038101906106db9190613588565b6119d9565b005b3480156106ee57600080fd5b506106f7611a16565b6040516107049190612a35565b60405180910390f35b61072760048036038101906107229190612a8d565b611aa4565b005b34801561073557600080fd5b50610750600480360381019061074b91906131f5565b611bcd565b005b34801561075e57600080fd5b50610767611be8565b6040516107749190612a35565b60405180910390f35b34801561078957600080fd5b506107a4600480360381019061079f91906135c8565b611c76565b6040516107b1919061298a565b60405180910390f35b3480156107c657600080fd5b506107e160048036038101906107dc9190613006565b611d0a565b005b3480156107ef57600080fd5b506107f8611d8d565b6040516108059190612a35565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061086957506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108995750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6060600280546108af90613637565b80601f01602080910402602001604051908101604052809291908181526020018280546108db90613637565b80156109285780601f106108fd57610100808354040283529160200191610928565b820191906000526020600020905b81548152906001019060200180831161090b57829003601f168201915b5050505050905090565b600061093d82611ebb565b610973576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006109bc826111b7565b90508073ffffffffffffffffffffffffffffffffffffffff166109dd611f1a565b73ffffffffffffffffffffffffffffffffffffffff1614610a4057610a0981610a04611f1a565b611c76565b610a3f576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610aff611f22565b6001546000540303905090565b6000610b1782611f2b565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b7e576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610b8a84611ff7565b91509150610ba08187610b9b611f1a565b61201e565b610bec57610bb586610bb0611f1a565b611c76565b610beb576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610c52576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c5f8686866001612062565b8015610c6a57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610d3885610d14888887612068565b7c020000000000000000000000000000000000000000000000000000000017612090565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610dbe5760006001850190506000600460008381526020019081526020016000205403610dbc576000548114610dbb578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610e2686868660016120bb565b505050505050565b6103e781565b610e3c6120c1565b6000610e466113ea565b73ffffffffffffffffffffffffffffffffffffffff1647604051610e6990613699565b60006040518083038185875af1925050503d8060008114610ea6576040519150601f19603f3d011682016040523d82523d6000602084013e610eab565b606091505b5050905080610eef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee6906136fa565b60405180910390fd5b50565b610f0d8383836040518060200160405280600081525061184b565b505050565b60016002811115610f2657610f25613461565b5b600a60009054906101000a900460ff166002811115610f4857610f47613461565b5b14610f88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7f90613766565b60405180910390fd5b6103e782610f94610af5565b610f9e91906137b5565b1115610fdf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd690613835565b60405180910390fd5b6000600d5403611024576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101b906138a1565b60405180910390fd5b61105781600d543360405160200161103c9190613909565b6040516020818303038152906040528051906020012061213f565b611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108d90613970565b60405180910390fd5b600954826110a49190613990565b3410156110e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110dd90613a1e565b60405180910390fd5b6110f03383612156565b5050565b6060600083839050905060008167ffffffffffffffff81111561111a57611119612c04565b5b60405190808252806020026020018201604052801561115357816020015b611140612887565b8152602001906001900390816111385790505b50905060005b8281146111ab5761118286868381811061117657611175613a3e565b5b905060200201356118d1565b82828151811061119557611194613a3e565b5b6020026020010181905250806001019050611159565b50809250505092915050565b60006111c282611f2b565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611230576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6112896120c1565b6112936000612311565b565b61129d6120c1565b80600d8190555050565b606060008060006112b7856111c9565b905060008167ffffffffffffffff8111156112d5576112d4612c04565b5b6040519080825280602002602001820160405280156113035781602001602082028036833780820191505090505b50905061130e612887565b6000611318611f22565b90505b8386146113dc5761132b816123d7565b915081604001516113d157600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff161461137657816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036113d057808387806001019850815181106113c3576113c2613a3e565b5b6020026020010181815250505b5b80600101905061131b565b508195505050505050919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61141c6120c1565b80600c908161142b9190613c19565b5050565b6114376120c1565b6103e782611443610af5565b61144d91906137b5565b111561148e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161148590613835565b60405180910390fd5b6114988183612402565b5050565b6060600380546114ab90613637565b80601f01602080910402602001604051908101604052809291908181526020018280546114d790613637565b80156115245780601f106114f957610100808354040283529160200191611524565b820191906000526020600020905b81548152906001019060200180831161150757829003601f168201915b5050505050905090565b6060818310611569576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080611574612420565b905061157e611f22565b8510156115905761158d611f22565b94505b8084111561159c578093505b60006115a7876111c9565b9050848610156115ca5760008686039050818110156115c4578091505b506115cf565b600090505b60008167ffffffffffffffff8111156115eb576115ea612c04565b5b6040519080825280602002602001820160405280156116195781602001602082028036833780820191505090505b509050600082036116305780945050505050611733565b600061163b886118d1565b90506000816040015161165057816000015190505b60008990505b8881141580156116665750848714155b1561172557611674816123d7565b9250826040015161171a57600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16146116bf57826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611719578084888060010199508151811061170c5761170b613a3e565b5b6020026020010181815250505b5b806001019050611656565b508583528296505050505050505b9392505050565b60095481565b806007600061174d611f1a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166117fa611f1a565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161183f919061298a565b60405180910390a35050565b611856848484610b0c565b60008373ffffffffffffffffffffffffffffffffffffffff163b146118b85761188184848484612429565b6118b7576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b600a60009054906101000a900460ff1681565b6118d9612887565b6118e1612887565b6118e9611f22565b8310806118fd57506118f9612420565b8310155b1561190b5780915050611936565b611914836123d7565b90508060400151156119295780915050611936565b61193283612579565b9150505b919050565b606061194682611ebb565b61197c576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611986612599565b905060008151036119a657604051806020016040528060008152506119d1565b806119b08461262b565b6040516020016119c1929190613d27565b6040516020818303038152906040525b915050919050565b6119e16120c1565b81600a60006101000a81548160ff02191690836002811115611a0657611a05613461565b5b0217905550806009819055505050565b600b8054611a2390613637565b80601f0160208091040260200160405190810160405280929190818152602001828054611a4f90613637565b8015611a9c5780601f10611a7157610100808354040283529160200191611a9c565b820191906000526020600020905b815481529060010190602001808311611a7f57829003601f168201915b505050505081565b600280811115611ab757611ab6613461565b5b600a60009054906101000a900460ff166002811115611ad957611ad8613461565b5b14611b19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1090613d97565b60405180910390fd5b6103e781611b25610af5565b611b2f91906137b5565b1115611b70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b6790613835565b60405180910390fd5b60095481611b7e9190613990565b341015611bc0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bb790613a1e565b60405180910390fd5b611bca3382612156565b50565b611bd56120c1565b80600b9081611be49190613c19565b5050565b600c8054611bf590613637565b80601f0160208091040260200160405190810160405280929190818152602001828054611c2190613637565b8015611c6e5780601f10611c4357610100808354040283529160200191611c6e565b820191906000526020600020905b815481529060010190602001808311611c5157829003601f168201915b505050505081565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611d126120c1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7890613e29565b60405180910390fd5b611d8a81612311565b50565b606060006002811115611da357611da2613461565b5b600a60009054906101000a900460ff166002811115611dc557611dc4613461565b5b03611e07576040518060400160405280600681526020017f436c6f73656400000000000000000000000000000000000000000000000000008152509050611eb8565b60016002811115611e1b57611e1a613461565b5b600a60009054906101000a900460ff166002811115611e3d57611e3c613461565b5b03611e7f576040518060400160405280600981526020017f57686974656c69737400000000000000000000000000000000000000000000008152509050611eb8565b6040518060400160405280600681526020017f5075626c6963000000000000000000000000000000000000000000000000000081525090505b90565b600081611ec6611f22565b11158015611ed5575060005482105b8015611f13575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b60008082905080611f3a611f22565b11611fc057600054811015611fbf5760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611fbd575b60008103611fb3576004600083600190039350838152602001908152602001600020549050611f89565b8092505050611ff2565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e861207f86868461267b565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6120c9612684565b73ffffffffffffffffffffffffffffffffffffffff166120e76113ea565b73ffffffffffffffffffffffffffffffffffffffff161461213d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213490613e95565b60405180910390fd5b565b60008261214c858461268c565b1490509392505050565b60008054905060008203612196576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6121a36000848385612062565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061221a8361220b6000866000612068565b612214856126e2565b17612090565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146122bb57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612280565b50600082036122f6576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061230c60008483856120bb565b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6123df612887565b6123fb60046000848152602001908152602001600020546126f2565b9050919050565b61241c8282604051806020016040528060008152506127a8565b5050565b60008054905090565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261244f611f1a565b8786866040518563ffffffff1660e01b81526004016124719493929190613f0a565b6020604051808303816000875af19250505080156124ad57506040513d601f19601f820116820180604052508101906124aa9190613f6b565b60015b612526573d80600081146124dd576040519150601f19603f3d011682016040523d82523d6000602084013e6124e2565b606091505b50600081510361251e576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b612581612887565b61259261258d83611f2b565b6126f2565b9050919050565b6060600b80546125a890613637565b80601f01602080910402602001604051908101604052809291908181526020018280546125d490613637565b80156126215780601f106125f657610100808354040283529160200191612621565b820191906000526020600020905b81548152906001019060200180831161260457829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b60011561266657600184039350600a81066030018453600a8104905080612644575b50828103602084039350808452505050919050565b60009392505050565b600033905090565b60008082905060005b84518110156126d7576126c2828683815181106126b5576126b4613a3e565b5b6020026020010151612845565b915080806126cf90613f98565b915050612695565b508091505092915050565b60006001821460e11b9050919050565b6126fa612887565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b6127b28383612156565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461284057600080549050600083820390505b6127f26000868380600101945086612429565b612828576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181106127df57816000541461283d57600080fd5b50505b505050565b600081831061285d576128588284612870565b612868565b6128678383612870565b5b905092915050565b600082600052816020526040600020905092915050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61291f816128ea565b811461292a57600080fd5b50565b60008135905061293c81612916565b92915050565b600060208284031215612958576129576128e0565b5b60006129668482850161292d565b91505092915050565b60008115159050919050565b6129848161296f565b82525050565b600060208201905061299f600083018461297b565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156129df5780820151818401526020810190506129c4565b60008484015250505050565b6000601f19601f8301169050919050565b6000612a07826129a5565b612a1181856129b0565b9350612a218185602086016129c1565b612a2a816129eb565b840191505092915050565b60006020820190508181036000830152612a4f81846129fc565b905092915050565b6000819050919050565b612a6a81612a57565b8114612a7557600080fd5b50565b600081359050612a8781612a61565b92915050565b600060208284031215612aa357612aa26128e0565b5b6000612ab184828501612a78565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612ae582612aba565b9050919050565b612af581612ada565b82525050565b6000602082019050612b106000830184612aec565b92915050565b612b1f81612ada565b8114612b2a57600080fd5b50565b600081359050612b3c81612b16565b92915050565b60008060408385031215612b5957612b586128e0565b5b6000612b6785828601612b2d565b9250506020612b7885828601612a78565b9150509250929050565b612b8b81612a57565b82525050565b6000602082019050612ba66000830184612b82565b92915050565b600080600060608486031215612bc557612bc46128e0565b5b6000612bd386828701612b2d565b9350506020612be486828701612b2d565b9250506040612bf586828701612a78565b9150509250925092565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612c3c826129eb565b810181811067ffffffffffffffff82111715612c5b57612c5a612c04565b5b80604052505050565b6000612c6e6128d6565b9050612c7a8282612c33565b919050565b600067ffffffffffffffff821115612c9a57612c99612c04565b5b602082029050602081019050919050565b600080fd5b6000819050919050565b612cc381612cb0565b8114612cce57600080fd5b50565b600081359050612ce081612cba565b92915050565b6000612cf9612cf484612c7f565b612c64565b90508083825260208201905060208402830185811115612d1c57612d1b612cab565b5b835b81811015612d455780612d318882612cd1565b845260208401935050602081019050612d1e565b5050509392505050565b600082601f830112612d6457612d63612bff565b5b8135612d74848260208601612ce6565b91505092915050565b60008060408385031215612d9457612d936128e0565b5b6000612da285828601612a78565b925050602083013567ffffffffffffffff811115612dc357612dc26128e5565b5b612dcf85828601612d4f565b9150509250929050565b600080fd5b60008083601f840112612df457612df3612bff565b5b8235905067ffffffffffffffff811115612e1157612e10612dd9565b5b602083019150836020820283011115612e2d57612e2c612cab565b5b9250929050565b60008060208385031215612e4b57612e4a6128e0565b5b600083013567ffffffffffffffff811115612e6957612e686128e5565b5b612e7585828601612dde565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612eb681612ada565b82525050565b600067ffffffffffffffff82169050919050565b612ed981612ebc565b82525050565b612ee88161296f565b82525050565b600062ffffff82169050919050565b612f0681612eee565b82525050565b608082016000820151612f226000850182612ead565b506020820151612f356020850182612ed0565b506040820151612f486040850182612edf565b506060820151612f5b6060850182612efd565b50505050565b6000612f6d8383612f0c565b60808301905092915050565b6000602082019050919050565b6000612f9182612e81565b612f9b8185612e8c565b9350612fa683612e9d565b8060005b83811015612fd7578151612fbe8882612f61565b9750612fc983612f79565b925050600181019050612faa565b5085935050505092915050565b60006020820190508181036000830152612ffe8184612f86565b905092915050565b60006020828403121561301c5761301b6128e0565b5b600061302a84828501612b2d565b91505092915050565b600060208284031215613049576130486128e0565b5b600061305784828501612cd1565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61309581612a57565b82525050565b60006130a7838361308c565b60208301905092915050565b6000602082019050919050565b60006130cb82613060565b6130d5818561306b565b93506130e08361307c565b8060005b838110156131115781516130f8888261309b565b9750613103836130b3565b9250506001810190506130e4565b5085935050505092915050565b6000602082019050818103600083015261313881846130c0565b905092915050565b600080fd5b600067ffffffffffffffff8211156131605761315f612c04565b5b613169826129eb565b9050602081019050919050565b82818337600083830152505050565b600061319861319384613145565b612c64565b9050828152602081018484840111156131b4576131b3613140565b5b6131bf848285613176565b509392505050565b600082601f8301126131dc576131db612bff565b5b81356131ec848260208601613185565b91505092915050565b60006020828403121561320b5761320a6128e0565b5b600082013567ffffffffffffffff811115613229576132286128e5565b5b613235848285016131c7565b91505092915050565b60008060408385031215613255576132546128e0565b5b600061326385828601612a78565b925050602061327485828601612b2d565b9150509250929050565b600080600060608486031215613297576132966128e0565b5b60006132a586828701612b2d565b93505060206132b686828701612a78565b92505060406132c786828701612a78565b9150509250925092565b6132da8161296f565b81146132e557600080fd5b50565b6000813590506132f7816132d1565b92915050565b60008060408385031215613314576133136128e0565b5b600061332285828601612b2d565b9250506020613333858286016132e8565b9150509250929050565b600067ffffffffffffffff82111561335857613357612c04565b5b613361826129eb565b9050602081019050919050565b600061338161337c8461333d565b612c64565b90508281526020810184848401111561339d5761339c613140565b5b6133a8848285613176565b509392505050565b600082601f8301126133c5576133c4612bff565b5b81356133d584826020860161336e565b91505092915050565b600080600080608085870312156133f8576133f76128e0565b5b600061340687828801612b2d565b945050602061341787828801612b2d565b935050604061342887828801612a78565b925050606085013567ffffffffffffffff811115613449576134486128e5565b5b613455878288016133b0565b91505092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600381106134a1576134a0613461565b5b50565b60008190506134b282613490565b919050565b60006134c2826134a4565b9050919050565b6134d2816134b7565b82525050565b60006020820190506134ed60008301846134c9565b92915050565b6080820160008201516135096000850182612ead565b50602082015161351c6020850182612ed0565b50604082015161352f6040850182612edf565b5060608201516135426060850182612efd565b50505050565b600060808201905061355d60008301846134f3565b92915050565b6003811061357057600080fd5b50565b60008135905061358281613563565b92915050565b6000806040838503121561359f5761359e6128e0565b5b60006135ad85828601613573565b92505060206135be85828601612a78565b9150509250929050565b600080604083850312156135df576135de6128e0565b5b60006135ed85828601612b2d565b92505060206135fe85828601612b2d565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061364f57607f821691505b60208210810361366257613661613608565b5b50919050565b600081905092915050565b50565b6000613683600083613668565b915061368e82613673565b600082019050919050565b60006136a482613676565b9150819050919050565b7f4661696c656420746f2077697468647261770000000000000000000000000000600082015250565b60006136e46012836129b0565b91506136ef826136ae565b602082019050919050565b60006020820190508181036000830152613713816136d7565b9050919050565b7f57686974656c6973742073616c6520697320636c6f7365640000000000000000600082015250565b60006137506018836129b0565b915061375b8261371a565b602082019050919050565b6000602082019050818103600083015261377f81613743565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006137c082612a57565b91506137cb83612a57565b92508282019050808211156137e3576137e2613786565b5b92915050565b7f496e73756666696369656e7420746f6b656e20737570706c7900000000000000600082015250565b600061381f6019836129b0565b915061382a826137e9565b602082019050919050565b6000602082019050818103600083015261384e81613812565b9050919050565b7f57686974656c69737420697320656d7074790000000000000000000000000000600082015250565b600061388b6012836129b0565b915061389682613855565b602082019050919050565b600060208201905081810360008301526138ba8161387e565b9050919050565b60008160601b9050919050565b60006138d9826138c1565b9050919050565b60006138eb826138ce565b9050919050565b6139036138fe82612ada565b6138e0565b82525050565b600061391582846138f2565b60148201915081905092915050565b7f496e76616c69642070726f6f6600000000000000000000000000000000000000600082015250565b600061395a600d836129b0565b915061396582613924565b602082019050919050565b600060208201905081810360008301526139898161394d565b9050919050565b600061399b82612a57565b91506139a683612a57565b92508282026139b481612a57565b915082820484148315176139cb576139ca613786565b5b5092915050565b7f416d6f756e7420696e76616c6964000000000000000000000000000000000000600082015250565b6000613a08600e836129b0565b9150613a13826139d2565b602082019050919050565b60006020820190508181036000830152613a37816139fb565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613acf7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613a92565b613ad98683613a92565b95508019841693508086168417925050509392505050565b6000819050919050565b6000613b16613b11613b0c84612a57565b613af1565b612a57565b9050919050565b6000819050919050565b613b3083613afb565b613b44613b3c82613b1d565b848454613a9f565b825550505050565b600090565b613b59613b4c565b613b64818484613b27565b505050565b5b81811015613b8857613b7d600082613b51565b600181019050613b6a565b5050565b601f821115613bcd57613b9e81613a6d565b613ba784613a82565b81016020851015613bb6578190505b613bca613bc285613a82565b830182613b69565b50505b505050565b600082821c905092915050565b6000613bf060001984600802613bd2565b1980831691505092915050565b6000613c098383613bdf565b9150826002028217905092915050565b613c22826129a5565b67ffffffffffffffff811115613c3b57613c3a612c04565b5b613c458254613637565b613c50828285613b8c565b600060209050601f831160018114613c835760008415613c71578287015190505b613c7b8582613bfd565b865550613ce3565b601f198416613c9186613a6d565b60005b82811015613cb957848901518255600182019150602085019450602081019050613c94565b86831015613cd65784890151613cd2601f891682613bdf565b8355505b6001600288020188555050505b505050505050565b600081905092915050565b6000613d01826129a5565b613d0b8185613ceb565b9350613d1b8185602086016129c1565b80840191505092915050565b6000613d338285613cf6565b9150613d3f8284613cf6565b91508190509392505050565b7f5075626c69632073616c6520697320636c6f7365640000000000000000000000600082015250565b6000613d816015836129b0565b9150613d8c82613d4b565b602082019050919050565b60006020820190508181036000830152613db081613d74565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613e136026836129b0565b9150613e1e82613db7565b604082019050919050565b60006020820190508181036000830152613e4281613e06565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613e7f6020836129b0565b9150613e8a82613e49565b602082019050919050565b60006020820190508181036000830152613eae81613e72565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000613edc82613eb5565b613ee68185613ec0565b9350613ef68185602086016129c1565b613eff816129eb565b840191505092915050565b6000608082019050613f1f6000830187612aec565b613f2c6020830186612aec565b613f396040830185612b82565b8181036060830152613f4b8184613ed1565b905095945050505050565b600081519050613f6581612916565b92915050565b600060208284031215613f8157613f806128e0565b5b6000613f8f84828501613f56565b91505092915050565b6000613fa382612a57565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fd557613fd4613786565b5b60018201905091905056fea26469706673582212202294d02076e334a90fad374186850942d9a0e9068ffc987361a50df53a19357364736f6c63430008110033
Deployed Bytecode Sourcemap
73748:2839:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31670:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32572:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39063:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38496:408;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;28323:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42702:2825;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73890:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75856:174;;;;;;;;;;;;;:::i;:::-;;45623:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75038:612;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68897:528;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33965:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;29507:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2878:103;;;;;;;;;;;;;:::i;:::-;;76252:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72773:900;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2230:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76370:104;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75662:186;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;32748:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69813:2513;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73937:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39621:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;46414:407;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73968:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68310:428;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32958:318;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74303:133;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74008:92;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74724:306;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76482:102;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74107:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40012:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3136:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74444:272;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31670:639;31755:4;32094:10;32079:25;;:11;:25;;;;:102;;;;32171:10;32156:25;;:11;:25;;;;32079:102;:179;;;;32248:10;32233:25;;:11;:25;;;;32079:179;32059:199;;31670:639;;;:::o;32572:100::-;32626:13;32659:5;32652:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32572:100;:::o;39063:218::-;39139:7;39164:16;39172:7;39164;:16::i;:::-;39159:64;;39189:34;;;;;;;;;;;;;;39159:64;39243:15;:24;39259:7;39243:24;;;;;;;;;;;:30;;;;;;;;;;;;39236:37;;39063:218;;;:::o;38496:408::-;38585:13;38601:16;38609:7;38601;:16::i;:::-;38585:32;;38657:5;38634:28;;:19;:17;:19::i;:::-;:28;;;38630:175;;38682:44;38699:5;38706:19;:17;:19::i;:::-;38682:16;:44::i;:::-;38677:128;;38754:35;;;;;;;;;;;;;;38677:128;38630:175;38850:2;38817:15;:24;38833:7;38817:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;38888:7;38884:2;38868:28;;38877:5;38868:28;;;;;;;;;;;;38574:330;38496:408;;:::o;28323:323::-;28384:7;28612:15;:13;:15::i;:::-;28597:12;;28581:13;;:28;:46;28574:53;;28323:323;:::o;42702:2825::-;42844:27;42874;42893:7;42874:18;:27::i;:::-;42844:57;;42959:4;42918:45;;42934:19;42918:45;;;42914:86;;42972:28;;;;;;;;;;;;;;42914:86;43014:27;43043:23;43070:35;43097:7;43070:26;:35::i;:::-;43013:92;;;;43205:68;43230:15;43247:4;43253:19;:17;:19::i;:::-;43205:24;:68::i;:::-;43200:180;;43293:43;43310:4;43316:19;:17;:19::i;:::-;43293:16;:43::i;:::-;43288:92;;43345:35;;;;;;;;;;;;;;43288:92;43200:180;43411:1;43397:16;;:2;:16;;;43393:52;;43422:23;;;;;;;;;;;;;;43393:52;43458:43;43480:4;43486:2;43490:7;43499:1;43458:21;:43::i;:::-;43594:15;43591:160;;;43734:1;43713:19;43706:30;43591:160;44131:18;:24;44150:4;44131:24;;;;;;;;;;;;;;;;44129:26;;;;;;;;;;;;44200:18;:22;44219:2;44200:22;;;;;;;;;;;;;;;;44198:24;;;;;;;;;;;44522:146;44559:2;44608:45;44623:4;44629:2;44633:19;44608:14;:45::i;:::-;24722:8;44580:73;44522:18;:146::i;:::-;44493:17;:26;44511:7;44493:26;;;;;;;;;;;:175;;;;44839:1;24722:8;44788:19;:47;:52;44784:627;;44861:19;44893:1;44883:7;:11;44861:33;;45050:1;45016:17;:30;45034:11;45016:30;;;;;;;;;;;;:35;45012:384;;45154:13;;45139:11;:28;45135:242;;45334:19;45301:17;:30;45319:11;45301:30;;;;;;;;;;;:52;;;;45135:242;45012:384;44842:569;44784:627;45458:7;45454:2;45439:27;;45448:4;45439:27;;;;;;;;;;;;45477:42;45498:4;45504:2;45508:7;45517:1;45477:20;:42::i;:::-;42833:2694;;;42702:2825;;;:::o;73890:40::-;73927:3;73890:40;:::o;75856:174::-;2116:13;:11;:13::i;:::-;75907:12:::1;75925:7;:5;:7::i;:::-;:12;;75946:21;75925:48;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75906:67;;;75992:7;75984:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;75895:135;75856:174::o:0;45623:193::-;45769:39;45786:4;45792:2;45796:7;45769:39;;;;;;;;;;;;:16;:39::i;:::-;45623:193;;;:::o;75038:612::-;75136:15;75127:24;;;;;;;;:::i;:::-;;:5;;;;;;;;;;;:24;;;;;;;;:::i;:::-;;;75119:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;73927:3;75215:6;75199:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:36;;75191:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;75284:16;:10;;:16;75276:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;75356:144;75393:5;75417:10;;75473;75456:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;75446:39;;;;;;75356:18;:144::i;:::-;75334:207;;;;;;;;;;;;:::i;:::-;;;;;;;;;75582:5;;75573:6;:14;;;;:::i;:::-;75560:9;:27;;75552:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;75617:25;75623:10;75635:6;75617:5;:25::i;:::-;75038:612;;:::o;68897:528::-;69041:23;69107:22;69132:8;;:15;;69107:40;;69162:34;69220:14;69199:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;69162:73;;69255:9;69250:125;69271:14;69266:1;:19;69250:125;;69327:32;69347:8;;69356:1;69347:11;;;;;;;:::i;:::-;;;;;;;;69327:19;:32::i;:::-;69311:10;69322:1;69311:13;;;;;;;;:::i;:::-;;;;;;;:48;;;;69287:3;;;;;69250:125;;;;69396:10;69389:17;;;;68897:528;;;;:::o;33965:152::-;34037:7;34080:27;34099:7;34080:18;:27::i;:::-;34057:52;;33965:152;;;:::o;29507:233::-;29579:7;29620:1;29603:19;;:5;:19;;;29599:60;;29631:28;;;;;;;;;;;;;;29599:60;23666:13;29677:18;:25;29696:5;29677:25;;;;;;;;;;;;;;;;:55;29670:62;;29507:233;;;:::o;2878:103::-;2116:13;:11;:13::i;:::-;2943:30:::1;2970:1;2943:18;:30::i;:::-;2878:103::o:0;76252:110::-;2116:13;:11;:13::i;:::-;76341::::1;76328:10;:26;;;;76252:110:::0;:::o;72773:900::-;72851:16;72905:19;72939:25;72979:22;73004:16;73014:5;73004:9;:16::i;:::-;72979:41;;73035:25;73077:14;73063:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73035:57;;73107:31;;:::i;:::-;73158:9;73170:15;:13;:15::i;:::-;73158:27;;73153:472;73202:14;73187:11;:29;73153:472;;73254:15;73267:1;73254:12;:15::i;:::-;73242:27;;73292:9;:16;;;73333:8;73288:73;73409:1;73383:28;;:9;:14;;;:28;;;73379:111;;73456:9;:14;;;73436:34;;73379:111;73533:5;73512:26;;:17;:26;;;73508:102;;73589:1;73563:8;73572:13;;;;;;73563:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;73508:102;73153:472;73218:3;;;;;73153:472;;;;73646:8;73639:15;;;;;;;72773:900;;;:::o;2230:87::-;2276:7;2303:6;;;;;;;;;;;2296:13;;2230:87;:::o;76370:104::-;2116:13;:11;:13::i;:::-;76460:6:::1;76446:11;:20;;;;;;:::i;:::-;;76370:104:::0;:::o;75662:186::-;2116:13;:11;:13::i;:::-;73927:3:::1;75758:6;75742:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:36;;75734:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;75819:21;75829:2;75833:6;75819:9;:21::i;:::-;75662:186:::0;;:::o;32748:104::-;32804:13;32837:7;32830:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32748:104;:::o;69813:2513::-;69956:16;70023:4;70014:5;:13;70010:45;;70036:19;;;;;;;;;;;;;;70010:45;70070:19;70104:17;70124:14;:12;:14::i;:::-;70104:34;;70224:15;:13;:15::i;:::-;70216:5;:23;70212:87;;;70268:15;:13;:15::i;:::-;70260:23;;70212:87;70375:9;70368:4;:16;70364:73;;;70412:9;70405:16;;70364:73;70451:25;70479:16;70489:5;70479:9;:16::i;:::-;70451:44;;70673:4;70665:5;:12;70661:278;;;70698:19;70727:5;70720:4;:12;70698:34;;70769:17;70755:11;:31;70751:111;;;70831:11;70811:31;;70751:111;70679:198;70661:278;;;70922:1;70902:21;;70661:278;70953:25;70995:17;70981:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70953:60;;71053:1;71032:17;:22;71028:78;;71082:8;71075:15;;;;;;;;71028:78;71250:31;71284:26;71304:5;71284:19;:26::i;:::-;71250:60;;71325:25;71570:9;:16;;;71565:92;;71627:9;:14;;;71607:34;;71565:92;71676:9;71688:5;71676:17;;71671:478;71700:4;71695:1;:9;;:45;;;;;71723:17;71708:11;:32;;71695:45;71671:478;;;71778:15;71791:1;71778:12;:15::i;:::-;71766:27;;71816:9;:16;;;71857:8;71812:73;71933:1;71907:28;;:9;:14;;;:28;;;71903:111;;71980:9;:14;;;71960:34;;71903:111;72057:5;72036:26;;:17;:26;;;72032:102;;72113:1;72087:8;72096:13;;;;;;72087:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;72032:102;71671:478;71742:3;;;;;71671:478;;;;72251:11;72241:8;72234:29;72299:8;72292:15;;;;;;;;69813:2513;;;;;;:::o;73937:24::-;;;;:::o;39621:234::-;39768:8;39716:18;:39;39735:19;:17;:19::i;:::-;39716:39;;;;;;;;;;;;;;;:49;39756:8;39716:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;39828:8;39792:55;;39807:19;:17;:19::i;:::-;39792:55;;;39838:8;39792:55;;;;;;:::i;:::-;;;;;;;;39621:234;;:::o;46414:407::-;46589:31;46602:4;46608:2;46612:7;46589:12;:31::i;:::-;46653:1;46635:2;:14;;;:19;46631:183;;46674:56;46705:4;46711:2;46715:7;46724:5;46674:30;:56::i;:::-;46669:145;;46758:40;;;;;;;;;;;;;;46669:145;46631:183;46414:407;;;;:::o;73968:33::-;;;;;;;;;;;;;:::o;68310:428::-;68394:21;;:::i;:::-;68428:31;;:::i;:::-;68484:15;:13;:15::i;:::-;68474:7;:25;:54;;;;68514:14;:12;:14::i;:::-;68503:7;:25;;68474:54;68470:103;;;68552:9;68545:16;;;;;68470:103;68595:21;68608:7;68595:12;:21::i;:::-;68583:33;;68631:9;:16;;;68627:65;;;68671:9;68664:16;;;;;68627:65;68709:21;68722:7;68709:12;:21::i;:::-;68702:28;;;68310:428;;;;:::o;32958:318::-;33031:13;33062:16;33070:7;33062;:16::i;:::-;33057:59;;33087:29;;;;;;;;;;;;;;33057:59;33129:21;33153:10;:8;:10::i;:::-;33129:34;;33206:1;33187:7;33181:21;:26;:87;;;;;;;;;;;;;;;;;33234:7;33243:18;33253:7;33243:9;:18::i;:::-;33217:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;33181:87;33174:94;;;32958:318;;;:::o;74303:133::-;2116:13;:11;:13::i;:::-;74393:8:::1;74385:5;;:16;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;74420:8;74412:5;:16;;;;74303:133:::0;;:::o;74008:92::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;74724:306::-;74798:12;74789:21;;;;;;;;:::i;:::-;;:5;;;;;;;;;;;:21;;;;;;;;:::i;:::-;;;74781:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;73927:3;74871:6;74855:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:36;;74847:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;74962:5;;74953:6;:14;;;;:::i;:::-;74940:9;:27;;74932:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;74997:25;75003:10;75015:6;74997:5;:25::i;:::-;74724:306;:::o;76482:102::-;2116:13;:11;:13::i;:::-;76570:6:::1;76555:12;:21;;;;;;:::i;:::-;;76482:102:::0;:::o;74107:95::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;40012:164::-;40109:4;40133:18;:25;40152:5;40133:25;;;;;;;;;;;;;;;:35;40159:8;40133:35;;;;;;;;;;;;;;;;;;;;;;;;;40126:42;;40012:164;;;;:::o;3136:201::-;2116:13;:11;:13::i;:::-;3245:1:::1;3225:22;;:8;:22;;::::0;3217:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;3301:28;3320:8;3301:18;:28::i;:::-;3136:201:::0;:::o;74444:272::-;74485:13;74524:12;74515:21;;;;;;;;:::i;:::-;;:5;;;;;;;;;;;:21;;;;;;;;:::i;:::-;;;74511:198;;74553:15;;;;;;;;;;;;;;;;;;;;;74511:198;74599:15;74590:24;;;;;;;;:::i;:::-;;:5;;;;;;;;;;;:24;;;;;;;;:::i;:::-;;;74586:123;;74631:18;;;;;;;;;;;;;;;;;;;;;74586:123;74682:15;;;;;;;;;;;;;;;;;;;74444:272;;:::o;40434:282::-;40499:4;40555:7;40536:15;:13;:15::i;:::-;:26;;:66;;;;;40589:13;;40579:7;:23;40536:66;:153;;;;;40688:1;24442:8;40640:17;:26;40658:7;40640:26;;;;;;;;;;;;:44;:49;40536:153;40516:173;;40434:282;;;:::o;62742:105::-;62802:7;62829:10;62822:17;;62742:105;:::o;76038:93::-;76095:7;76122:1;76115:8;;76038:93;:::o;35120:1275::-;35187:7;35207:12;35222:7;35207:22;;35290:4;35271:15;:13;:15::i;:::-;:23;35267:1061;;35324:13;;35317:4;:20;35313:1015;;;35362:14;35379:17;:23;35397:4;35379:23;;;;;;;;;;;;35362:40;;35496:1;24442:8;35468:6;:24;:29;35464:845;;36133:113;36150:1;36140:6;:11;36133:113;;36193:17;:25;36211:6;;;;;;;36193:25;;;;;;;;;;;;36184:34;;36133:113;;;36279:6;36272:13;;;;;;35464:845;35339:989;35313:1015;35267:1061;36356:31;;;;;;;;;;;;;;35120:1275;;;;:::o;41597:485::-;41699:27;41728:23;41769:38;41810:15;:24;41826:7;41810:24;;;;;;;;;;;41769:65;;41987:18;41964:41;;42044:19;42038:26;42019:45;;41949:126;41597:485;;;:::o;40825:659::-;40974:11;41139:16;41132:5;41128:28;41119:37;;41299:16;41288:9;41284:32;41271:45;;41449:15;41438:9;41435:30;41427:5;41416:9;41413:20;41410:56;41400:66;;40825:659;;;;;:::o;47483:159::-;;;;;:::o;62051:311::-;62186:7;62206:16;24846:3;62232:19;:41;;62206:68;;24846:3;62300:31;62311:4;62317:2;62321:9;62300:10;:31::i;:::-;62292:40;;:62;;62285:69;;;62051:311;;;;;:::o;36943:450::-;37023:14;37191:16;37184:5;37180:28;37171:37;;37368:5;37354:11;37329:23;37325:41;37322:52;37315:5;37312:63;37302:73;;36943:450;;;;:::o;48307:158::-;;;;;:::o;2395:132::-;2470:12;:10;:12::i;:::-;2459:23;;:7;:5;:7::i;:::-;:23;;;2451:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;2395:132::o;4921:190::-;5046:4;5099;5070:25;5083:5;5090:4;5070:12;:25::i;:::-;:33;5063:40;;4921:190;;;;;:::o;50083:2966::-;50156:20;50179:13;;50156:36;;50219:1;50207:8;:13;50203:44;;50229:18;;;;;;;;;;;;;;50203:44;50260:61;50290:1;50294:2;50298:12;50312:8;50260:21;:61::i;:::-;50804:1;23804:2;50774:1;:26;;50773:32;50761:8;:45;50735:18;:22;50754:2;50735:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;51083:139;51120:2;51174:33;51197:1;51201:2;51205:1;51174:14;:33::i;:::-;51141:30;51162:8;51141:20;:30::i;:::-;:66;51083:18;:139::i;:::-;51049:17;:31;51067:12;51049:31;;;;;;;;;;;:173;;;;51239:16;51270:11;51299:8;51284:12;:23;51270:37;;51820:16;51816:2;51812:25;51800:37;;52192:12;52152:8;52111:1;52049:25;51990:1;51929;51902:335;52563:1;52549:12;52545:20;52503:346;52604:3;52595:7;52592:16;52503:346;;52822:7;52812:8;52809:1;52782:25;52779:1;52776;52771:59;52657:1;52648:7;52644:15;52633:26;;52503:346;;;52507:77;52894:1;52882:8;:13;52878:45;;52904:19;;;;;;;;;;;;;;52878:45;52956:3;52940:13;:19;;;;50509:2462;;52981:60;53010:1;53014:2;53018:12;53032:8;52981:20;:60::i;:::-;50145:2904;50083:2966;;:::o;3497:191::-;3571:16;3590:6;;;;;;;;;;;3571:25;;3616:8;3607:6;;:17;;;;;;;;;;;;;;;;;;3671:8;3640:40;;3661:8;3640:40;;;;;;;;;;;;3560:128;3497:191;:::o;34568:161::-;34636:21;;:::i;:::-;34677:44;34696:17;:24;34714:5;34696:24;;;;;;;;;;;;34677:18;:44::i;:::-;34670:51;;34568:161;;;:::o;56574:112::-;56651:27;56661:2;56665:8;56651:27;;;;;;;;;;;;:9;:27::i;:::-;56574:112;;:::o;28010:103::-;28065:7;28092:13;;28085:20;;28010:103;:::o;48905:716::-;49068:4;49114:2;49089:45;;;49135:19;:17;:19::i;:::-;49156:4;49162:7;49171:5;49089:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;49085:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49389:1;49372:6;:13;:18;49368:235;;49418:40;;;;;;;;;;;;;;49368:235;49561:6;49555:13;49546:6;49542:2;49538:15;49531:38;49085:529;49258:54;;;49248:64;;;:6;:64;;;;49241:71;;;48905:716;;;;;;:::o;34306:166::-;34376:21;;:::i;:::-;34417:47;34436:27;34455:7;34436:18;:27::i;:::-;34417:18;:47::i;:::-;34410:54;;34306:166;;;:::o;76139:105::-;76191:13;76224:12;76217:19;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76139:105;:::o;62949:1745::-;63014:17;63448:4;63441;63435:11;63431:22;63540:1;63534:4;63527:15;63615:4;63612:1;63608:12;63601:19;;63697:1;63692:3;63685:14;63801:3;64040:5;64022:428;64048:1;64022:428;;;64088:1;64083:3;64079:11;64072:18;;64259:2;64253:4;64249:13;64245:2;64241:22;64236:3;64228:36;64353:2;64347:4;64343:13;64335:21;;64420:4;64022:428;64410:25;64022:428;64026:21;64489:3;64484;64480:13;64604:4;64599:3;64595:14;64588:21;;64669:6;64664:3;64657:19;63053:1634;;;62949:1745;;;:::o;61752:147::-;61889:6;61752:147;;;;;:::o;779:98::-;832:7;859:10;852:17;;779:98;:::o;5788:296::-;5871:7;5891:20;5914:4;5891:27;;5934:9;5929:118;5953:5;:12;5949:1;:16;5929:118;;;6002:33;6012:12;6026:5;6032:1;6026:8;;;;;;;;:::i;:::-;;;;;;;;6002:9;:33::i;:::-;5987:48;;5967:3;;;;;:::i;:::-;;;;5929:118;;;;6064:12;6057:19;;;5788:296;;;;:::o;37495:324::-;37565:14;37798:1;37788:8;37785:15;37759:24;37755:46;37745:56;;37495:324;;;:::o;36494:366::-;36560:31;;:::i;:::-;36637:6;36604:9;:14;;:41;;;;;;;;;;;24325:3;36690:6;:33;;36656:9;:24;;:68;;;;;;;;;;;36782:1;24442:8;36754:6;:24;:29;;36735:9;:16;;:48;;;;;;;;;;;24846:3;36823:6;:28;;36794:9;:19;;:58;;;;;;;;;;;36494:366;;;:::o;55801:689::-;55932:19;55938:2;55942:8;55932:5;:19::i;:::-;56011:1;55993:2;:14;;;:19;55989:483;;56033:11;56047:13;;56033:27;;56079:13;56101:8;56095:3;:14;56079:30;;56128:233;56159:62;56198:1;56202:2;56206:7;;;;;;56215:5;56159:30;:62::i;:::-;56154:167;;56257:40;;;;;;;;;;;;;;56154:167;56356:3;56348:5;:11;56128:233;;56443:3;56426:13;;:20;56422:34;;56448:8;;;56422:34;56014:458;;55989:483;55801:689;;;:::o;12828:149::-;12891:7;12922:1;12918;:5;:51;;12949:20;12964:1;12967;12949:14;:20::i;:::-;12918:51;;;12926:20;12941:1;12944;12926:14;:20::i;:::-;12918:51;12911:58;;12828:149;;;;:::o;12985:268::-;13053:13;13160:1;13154:4;13147:15;13189:1;13183:4;13176:15;13230:4;13224;13214:21;13205:30;;12985:268;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::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:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:118::-;4977:24;4995:5;4977:24;:::i;:::-;4972:3;4965:37;4890:118;;:::o;5014:222::-;5107:4;5145:2;5134:9;5130:18;5122:26;;5158:71;5226:1;5215:9;5211:17;5202:6;5158:71;:::i;:::-;5014:222;;;;:::o;5242:619::-;5319:6;5327;5335;5384:2;5372:9;5363:7;5359:23;5355:32;5352:119;;;5390:79;;:::i;:::-;5352:119;5510:1;5535:53;5580:7;5571:6;5560:9;5556:22;5535:53;:::i;:::-;5525:63;;5481:117;5637:2;5663:53;5708:7;5699:6;5688:9;5684:22;5663:53;:::i;:::-;5653:63;;5608:118;5765:2;5791:53;5836:7;5827:6;5816:9;5812:22;5791:53;:::i;:::-;5781:63;;5736:118;5242:619;;;;;:::o;5867:117::-;5976:1;5973;5966:12;5990:180;6038:77;6035:1;6028:88;6135:4;6132:1;6125:15;6159:4;6156:1;6149:15;6176:281;6259:27;6281:4;6259:27;:::i;:::-;6251:6;6247:40;6389:6;6377:10;6374:22;6353:18;6341:10;6338:34;6335:62;6332:88;;;6400:18;;:::i;:::-;6332:88;6440:10;6436:2;6429:22;6219:238;6176:281;;:::o;6463:129::-;6497:6;6524:20;;:::i;:::-;6514:30;;6553:33;6581:4;6573:6;6553:33;:::i;:::-;6463:129;;;:::o;6598:311::-;6675:4;6765:18;6757:6;6754:30;6751:56;;;6787:18;;:::i;:::-;6751:56;6837:4;6829:6;6825:17;6817:25;;6897:4;6891;6887:15;6879:23;;6598:311;;;:::o;6915:117::-;7024:1;7021;7014:12;7038:77;7075:7;7104:5;7093:16;;7038:77;;;:::o;7121:122::-;7194:24;7212:5;7194:24;:::i;:::-;7187:5;7184:35;7174:63;;7233:1;7230;7223:12;7174:63;7121:122;:::o;7249:139::-;7295:5;7333:6;7320:20;7311:29;;7349:33;7376:5;7349:33;:::i;:::-;7249:139;;;;:::o;7411:710::-;7507:5;7532:81;7548:64;7605:6;7548:64;:::i;:::-;7532:81;:::i;:::-;7523:90;;7633:5;7662:6;7655:5;7648:21;7696:4;7689:5;7685:16;7678:23;;7749:4;7741:6;7737:17;7729:6;7725:30;7778:3;7770:6;7767:15;7764:122;;;7797:79;;:::i;:::-;7764:122;7912:6;7895:220;7929:6;7924:3;7921:15;7895:220;;;8004:3;8033:37;8066:3;8054:10;8033:37;:::i;:::-;8028:3;8021:50;8100:4;8095:3;8091:14;8084:21;;7971:144;7955:4;7950:3;7946:14;7939:21;;7895:220;;;7899:21;7513:608;;7411:710;;;;;:::o;8144:370::-;8215:5;8264:3;8257:4;8249:6;8245:17;8241:27;8231:122;;8272:79;;:::i;:::-;8231:122;8389:6;8376:20;8414:94;8504:3;8496:6;8489:4;8481:6;8477:17;8414:94;:::i;:::-;8405:103;;8221:293;8144:370;;;;:::o;8520:684::-;8613:6;8621;8670:2;8658:9;8649:7;8645:23;8641:32;8638:119;;;8676:79;;:::i;:::-;8638:119;8796:1;8821:53;8866:7;8857:6;8846:9;8842:22;8821:53;:::i;:::-;8811:63;;8767:117;8951:2;8940:9;8936:18;8923:32;8982:18;8974:6;8971:30;8968:117;;;9004:79;;:::i;:::-;8968:117;9109:78;9179:7;9170:6;9159:9;9155:22;9109:78;:::i;:::-;9099:88;;8894:303;8520:684;;;;;:::o;9210:117::-;9319:1;9316;9309:12;9350:568;9423:8;9433:6;9483:3;9476:4;9468:6;9464:17;9460:27;9450:122;;9491:79;;:::i;:::-;9450:122;9604:6;9591:20;9581:30;;9634:18;9626:6;9623:30;9620:117;;;9656:79;;:::i;:::-;9620:117;9770:4;9762:6;9758:17;9746:29;;9824:3;9816:4;9808:6;9804:17;9794:8;9790:32;9787:41;9784:128;;;9831:79;;:::i;:::-;9784:128;9350:568;;;;;:::o;9924:559::-;10010:6;10018;10067:2;10055:9;10046:7;10042:23;10038:32;10035:119;;;10073:79;;:::i;:::-;10035:119;10221:1;10210:9;10206:17;10193:31;10251:18;10243:6;10240:30;10237:117;;;10273:79;;:::i;:::-;10237:117;10386:80;10458:7;10449:6;10438:9;10434:22;10386:80;:::i;:::-;10368:98;;;;10164:312;9924:559;;;;;:::o;10489:145::-;10587:6;10621:5;10615:12;10605:22;;10489:145;;;:::o;10640:215::-;10770:11;10804:6;10799:3;10792:19;10844:4;10839:3;10835:14;10820:29;;10640:215;;;;:::o;10861:163::-;10959:4;10982:3;10974:11;;11012:4;11007:3;11003:14;10995:22;;10861:163;;;:::o;11030:108::-;11107:24;11125:5;11107:24;:::i;:::-;11102:3;11095:37;11030:108;;:::o;11144:101::-;11180:7;11220:18;11213:5;11209:30;11198:41;;11144:101;;;:::o;11251:105::-;11326:23;11343:5;11326:23;:::i;:::-;11321:3;11314:36;11251:105;;:::o;11362:99::-;11433:21;11448:5;11433:21;:::i;:::-;11428:3;11421:34;11362:99;;:::o;11467:91::-;11503:7;11543:8;11536:5;11532:20;11521:31;;11467:91;;;:::o;11564:105::-;11639:23;11656:5;11639:23;:::i;:::-;11634:3;11627:36;11564:105;;:::o;11747:864::-;11896:4;11891:3;11887:14;11983:4;11976:5;11972:16;11966:23;12002:63;12059:4;12054:3;12050:14;12036:12;12002:63;:::i;:::-;11911:164;12167:4;12160:5;12156:16;12150:23;12186:61;12241:4;12236:3;12232:14;12218:12;12186:61;:::i;:::-;12085:172;12341:4;12334:5;12330:16;12324:23;12360:57;12411:4;12406:3;12402:14;12388:12;12360:57;:::i;:::-;12267:160;12514:4;12507:5;12503:16;12497:23;12533:61;12588:4;12583:3;12579:14;12565:12;12533:61;:::i;:::-;12437:167;11865:746;11747:864;;:::o;12617:303::-;12748:10;12769:108;12873:3;12865:6;12769:108;:::i;:::-;12909:4;12904:3;12900:14;12886:28;;12617:303;;;;:::o;12926:144::-;13027:4;13059;13054:3;13050:14;13042:22;;12926:144;;;:::o;13152:980::-;13333:3;13362:85;13441:5;13362:85;:::i;:::-;13463:117;13573:6;13568:3;13463:117;:::i;:::-;13456:124;;13604:87;13685:5;13604:87;:::i;:::-;13714:7;13745:1;13730:377;13755:6;13752:1;13749:13;13730:377;;;13831:6;13825:13;13858:125;13979:3;13964:13;13858:125;:::i;:::-;13851:132;;14006:91;14090:6;14006:91;:::i;:::-;13996:101;;13790:317;13777:1;13774;13770:9;13765:14;;13730:377;;;13734:14;14123:3;14116:10;;13338:794;;;13152:980;;;;:::o;14138:497::-;14343:4;14381:2;14370:9;14366:18;14358:26;;14430:9;14424:4;14420:20;14416:1;14405:9;14401:17;14394:47;14458:170;14623:4;14614:6;14458:170;:::i;:::-;14450:178;;14138:497;;;;:::o;14641:329::-;14700:6;14749:2;14737:9;14728:7;14724:23;14720:32;14717:119;;;14755:79;;:::i;:::-;14717:119;14875:1;14900:53;14945:7;14936:6;14925:9;14921:22;14900:53;:::i;:::-;14890:63;;14846:117;14641:329;;;;:::o;14976:::-;15035:6;15084:2;15072:9;15063:7;15059:23;15055:32;15052:119;;;15090:79;;:::i;:::-;15052:119;15210:1;15235:53;15280:7;15271:6;15260:9;15256:22;15235:53;:::i;:::-;15225:63;;15181:117;14976:329;;;;:::o;15311:114::-;15378:6;15412:5;15406:12;15396:22;;15311:114;;;:::o;15431:184::-;15530:11;15564:6;15559:3;15552:19;15604:4;15599:3;15595:14;15580:29;;15431:184;;;;:::o;15621:132::-;15688:4;15711:3;15703:11;;15741:4;15736:3;15732:14;15724:22;;15621:132;;;:::o;15759:108::-;15836:24;15854:5;15836:24;:::i;:::-;15831:3;15824:37;15759:108;;:::o;15873:179::-;15942:10;15963:46;16005:3;15997:6;15963:46;:::i;:::-;16041:4;16036:3;16032:14;16018:28;;15873:179;;;;:::o;16058:113::-;16128:4;16160;16155:3;16151:14;16143:22;;16058:113;;;:::o;16207:732::-;16326:3;16355:54;16403:5;16355:54;:::i;:::-;16425:86;16504:6;16499:3;16425:86;:::i;:::-;16418:93;;16535:56;16585:5;16535:56;:::i;:::-;16614:7;16645:1;16630:284;16655:6;16652:1;16649:13;16630:284;;;16731:6;16725:13;16758:63;16817:3;16802:13;16758:63;:::i;:::-;16751:70;;16844:60;16897:6;16844:60;:::i;:::-;16834:70;;16690:224;16677:1;16674;16670:9;16665:14;;16630:284;;;16634:14;16930:3;16923:10;;16331:608;;;16207:732;;;;:::o;16945:373::-;17088:4;17126:2;17115:9;17111:18;17103:26;;17175:9;17169:4;17165:20;17161:1;17150:9;17146:17;17139:47;17203:108;17306:4;17297:6;17203:108;:::i;:::-;17195:116;;16945:373;;;;:::o;17324:117::-;17433:1;17430;17423:12;17447:308;17509:4;17599:18;17591:6;17588:30;17585:56;;;17621:18;;:::i;:::-;17585:56;17659:29;17681:6;17659:29;:::i;:::-;17651:37;;17743:4;17737;17733:15;17725:23;;17447:308;;;:::o;17761:146::-;17858:6;17853:3;17848;17835:30;17899:1;17890:6;17885:3;17881:16;17874:27;17761:146;;;:::o;17913:425::-;17991:5;18016:66;18032:49;18074:6;18032:49;:::i;:::-;18016:66;:::i;:::-;18007:75;;18105:6;18098:5;18091:21;18143:4;18136:5;18132:16;18181:3;18172:6;18167:3;18163:16;18160:25;18157:112;;;18188:79;;:::i;:::-;18157:112;18278:54;18325:6;18320:3;18315;18278:54;:::i;:::-;17997:341;17913:425;;;;;:::o;18358:340::-;18414:5;18463:3;18456:4;18448:6;18444:17;18440:27;18430:122;;18471:79;;:::i;:::-;18430:122;18588:6;18575:20;18613:79;18688:3;18680:6;18673:4;18665:6;18661:17;18613:79;:::i;:::-;18604:88;;18420:278;18358:340;;;;:::o;18704:509::-;18773:6;18822:2;18810:9;18801:7;18797:23;18793:32;18790:119;;;18828:79;;:::i;:::-;18790:119;18976:1;18965:9;18961:17;18948:31;19006:18;18998:6;18995:30;18992:117;;;19028:79;;:::i;:::-;18992:117;19133:63;19188:7;19179:6;19168:9;19164:22;19133:63;:::i;:::-;19123:73;;18919:287;18704:509;;;;:::o;19219:474::-;19287:6;19295;19344:2;19332:9;19323:7;19319:23;19315:32;19312:119;;;19350:79;;:::i;:::-;19312:119;19470:1;19495:53;19540:7;19531:6;19520:9;19516:22;19495:53;:::i;:::-;19485:63;;19441:117;19597:2;19623:53;19668:7;19659:6;19648:9;19644:22;19623:53;:::i;:::-;19613:63;;19568:118;19219:474;;;;;:::o;19699:619::-;19776:6;19784;19792;19841:2;19829:9;19820:7;19816:23;19812:32;19809:119;;;19847:79;;:::i;:::-;19809:119;19967:1;19992:53;20037:7;20028:6;20017:9;20013:22;19992:53;:::i;:::-;19982:63;;19938:117;20094:2;20120:53;20165:7;20156:6;20145:9;20141:22;20120:53;:::i;:::-;20110:63;;20065:118;20222:2;20248:53;20293:7;20284:6;20273:9;20269:22;20248:53;:::i;:::-;20238:63;;20193:118;19699:619;;;;;:::o;20324:116::-;20394:21;20409:5;20394:21;:::i;:::-;20387:5;20384:32;20374:60;;20430:1;20427;20420:12;20374:60;20324:116;:::o;20446:133::-;20489:5;20527:6;20514:20;20505:29;;20543:30;20567:5;20543:30;:::i;:::-;20446:133;;;;:::o;20585:468::-;20650:6;20658;20707:2;20695:9;20686:7;20682:23;20678:32;20675:119;;;20713:79;;:::i;:::-;20675:119;20833:1;20858:53;20903:7;20894:6;20883:9;20879:22;20858:53;:::i;:::-;20848:63;;20804:117;20960:2;20986:50;21028:7;21019:6;21008:9;21004:22;20986:50;:::i;:::-;20976:60;;20931:115;20585:468;;;;;:::o;21059:307::-;21120:4;21210:18;21202:6;21199:30;21196:56;;;21232:18;;:::i;:::-;21196:56;21270:29;21292:6;21270:29;:::i;:::-;21262:37;;21354:4;21348;21344:15;21336:23;;21059:307;;;:::o;21372:423::-;21449:5;21474:65;21490:48;21531:6;21490:48;:::i;:::-;21474:65;:::i;:::-;21465:74;;21562:6;21555:5;21548:21;21600:4;21593:5;21589:16;21638:3;21629:6;21624:3;21620:16;21617:25;21614:112;;;21645:79;;:::i;:::-;21614:112;21735:54;21782:6;21777:3;21772;21735:54;:::i;:::-;21455:340;21372:423;;;;;:::o;21814:338::-;21869:5;21918:3;21911:4;21903:6;21899:17;21895:27;21885:122;;21926:79;;:::i;:::-;21885:122;22043:6;22030:20;22068:78;22142:3;22134:6;22127:4;22119:6;22115:17;22068:78;:::i;:::-;22059:87;;21875:277;21814:338;;;;:::o;22158:943::-;22253:6;22261;22269;22277;22326:3;22314:9;22305:7;22301:23;22297:33;22294:120;;;22333:79;;:::i;:::-;22294:120;22453:1;22478:53;22523:7;22514:6;22503:9;22499:22;22478:53;:::i;:::-;22468:63;;22424:117;22580:2;22606:53;22651:7;22642:6;22631:9;22627:22;22606:53;:::i;:::-;22596:63;;22551:118;22708:2;22734:53;22779:7;22770:6;22759:9;22755:22;22734:53;:::i;:::-;22724:63;;22679:118;22864:2;22853:9;22849:18;22836:32;22895:18;22887:6;22884:30;22881:117;;;22917:79;;:::i;:::-;22881:117;23022:62;23076:7;23067:6;23056:9;23052:22;23022:62;:::i;:::-;23012:72;;22807:287;22158:943;;;;;;;:::o;23107:180::-;23155:77;23152:1;23145:88;23252:4;23249:1;23242:15;23276:4;23273:1;23266:15;23293:115;23376:1;23369:5;23366:12;23356:46;;23382:18;;:::i;:::-;23356:46;23293:115;:::o;23414:131::-;23461:7;23490:5;23479:16;;23496:43;23533:5;23496:43;:::i;:::-;23414:131;;;:::o;23551:::-;23609:9;23642:34;23670:5;23642:34;:::i;:::-;23629:47;;23551:131;;;:::o;23688:147::-;23783:45;23822:5;23783:45;:::i;:::-;23778:3;23771:58;23688:147;;:::o;23841:238::-;23942:4;23980:2;23969:9;23965:18;23957:26;;23993:79;24069:1;24058:9;24054:17;24045:6;23993:79;:::i;:::-;23841:238;;;;:::o;24157:874::-;24316:4;24311:3;24307:14;24403:4;24396:5;24392:16;24386:23;24422:63;24479:4;24474:3;24470:14;24456:12;24422:63;:::i;:::-;24331:164;24587:4;24580:5;24576:16;24570:23;24606:61;24661:4;24656:3;24652:14;24638:12;24606:61;:::i;:::-;24505:172;24761:4;24754:5;24750:16;24744:23;24780:57;24831:4;24826:3;24822:14;24808:12;24780:57;:::i;:::-;24687:160;24934:4;24927:5;24923:16;24917:23;24953:61;25008:4;25003:3;24999:14;24985:12;24953:61;:::i;:::-;24857:167;24285:746;24157:874;;:::o;25037:347::-;25192:4;25230:3;25219:9;25215:19;25207:27;;25244:133;25374:1;25363:9;25359:17;25350:6;25244:133;:::i;:::-;25037:347;;;;:::o;25390:109::-;25473:1;25466:5;25463:12;25453:40;;25489:1;25486;25479:12;25453:40;25390:109;:::o;25505:159::-;25561:5;25599:6;25586:20;25577:29;;25615:43;25652:5;25615:43;:::i;:::-;25505:159;;;;:::o;25670:494::-;25748:6;25756;25805:2;25793:9;25784:7;25780:23;25776:32;25773:119;;;25811:79;;:::i;:::-;25773:119;25931:1;25956:63;26011:7;26002:6;25991:9;25987:22;25956:63;:::i;:::-;25946:73;;25902:127;26068:2;26094:53;26139:7;26130:6;26119:9;26115:22;26094:53;:::i;:::-;26084:63;;26039:118;25670:494;;;;;:::o;26170:474::-;26238:6;26246;26295:2;26283:9;26274:7;26270:23;26266:32;26263:119;;;26301:79;;:::i;:::-;26263:119;26421:1;26446:53;26491:7;26482:6;26471:9;26467:22;26446:53;:::i;:::-;26436:63;;26392:117;26548:2;26574:53;26619:7;26610:6;26599:9;26595:22;26574:53;:::i;:::-;26564:63;;26519:118;26170:474;;;;;:::o;26650:180::-;26698:77;26695:1;26688:88;26795:4;26792:1;26785:15;26819:4;26816:1;26809:15;26836:320;26880:6;26917:1;26911:4;26907:12;26897:22;;26964:1;26958:4;26954:12;26985:18;26975:81;;27041:4;27033:6;27029:17;27019:27;;26975:81;27103:2;27095:6;27092:14;27072:18;27069:38;27066:84;;27122:18;;:::i;:::-;27066:84;26887:269;26836:320;;;:::o;27162:147::-;27263:11;27300:3;27285:18;;27162:147;;;;:::o;27315:114::-;;:::o;27435:398::-;27594:3;27615:83;27696:1;27691:3;27615:83;:::i;:::-;27608:90;;27707:93;27796:3;27707:93;:::i;:::-;27825:1;27820:3;27816:11;27809:18;;27435:398;;;:::o;27839:379::-;28023:3;28045:147;28188:3;28045:147;:::i;:::-;28038:154;;28209:3;28202:10;;27839:379;;;:::o;28224:168::-;28364:20;28360:1;28352:6;28348:14;28341:44;28224:168;:::o;28398:366::-;28540:3;28561:67;28625:2;28620:3;28561:67;:::i;:::-;28554:74;;28637:93;28726:3;28637:93;:::i;:::-;28755:2;28750:3;28746:12;28739:19;;28398:366;;;:::o;28770:419::-;28936:4;28974:2;28963:9;28959:18;28951:26;;29023:9;29017:4;29013:20;29009:1;28998:9;28994:17;28987:47;29051:131;29177:4;29051:131;:::i;:::-;29043:139;;28770:419;;;:::o;29195:174::-;29335:26;29331:1;29323:6;29319:14;29312:50;29195:174;:::o;29375:366::-;29517:3;29538:67;29602:2;29597:3;29538:67;:::i;:::-;29531:74;;29614:93;29703:3;29614:93;:::i;:::-;29732:2;29727:3;29723:12;29716:19;;29375:366;;;:::o;29747:419::-;29913:4;29951:2;29940:9;29936:18;29928:26;;30000:9;29994:4;29990:20;29986:1;29975:9;29971:17;29964:47;30028:131;30154:4;30028:131;:::i;:::-;30020:139;;29747:419;;;:::o;30172:180::-;30220:77;30217:1;30210:88;30317:4;30314:1;30307:15;30341:4;30338:1;30331:15;30358:191;30398:3;30417:20;30435:1;30417:20;:::i;:::-;30412:25;;30451:20;30469:1;30451:20;:::i;:::-;30446:25;;30494:1;30491;30487:9;30480:16;;30515:3;30512:1;30509:10;30506:36;;;30522:18;;:::i;:::-;30506:36;30358:191;;;;:::o;30555:175::-;30695:27;30691:1;30683:6;30679:14;30672:51;30555:175;:::o;30736:366::-;30878:3;30899:67;30963:2;30958:3;30899:67;:::i;:::-;30892:74;;30975:93;31064:3;30975:93;:::i;:::-;31093:2;31088:3;31084:12;31077:19;;30736:366;;;:::o;31108:419::-;31274:4;31312:2;31301:9;31297:18;31289:26;;31361:9;31355:4;31351:20;31347:1;31336:9;31332:17;31325:47;31389:131;31515:4;31389:131;:::i;:::-;31381:139;;31108:419;;;:::o;31533:168::-;31673:20;31669:1;31661:6;31657:14;31650:44;31533:168;:::o;31707:366::-;31849:3;31870:67;31934:2;31929:3;31870:67;:::i;:::-;31863:74;;31946:93;32035:3;31946:93;:::i;:::-;32064:2;32059:3;32055:12;32048:19;;31707:366;;;:::o;32079:419::-;32245:4;32283:2;32272:9;32268:18;32260:26;;32332:9;32326:4;32322:20;32318:1;32307:9;32303:17;32296:47;32360:131;32486:4;32360:131;:::i;:::-;32352:139;;32079:419;;;:::o;32504:94::-;32537:8;32585:5;32581:2;32577:14;32556:35;;32504:94;;;:::o;32604:::-;32643:7;32672:20;32686:5;32672:20;:::i;:::-;32661:31;;32604:94;;;:::o;32704:100::-;32743:7;32772:26;32792:5;32772:26;:::i;:::-;32761:37;;32704:100;;;:::o;32810:157::-;32915:45;32935:24;32953:5;32935:24;:::i;:::-;32915:45;:::i;:::-;32910:3;32903:58;32810:157;;:::o;32973:256::-;33085:3;33100:75;33171:3;33162:6;33100:75;:::i;:::-;33200:2;33195:3;33191:12;33184:19;;33220:3;33213:10;;32973:256;;;;:::o;33235:163::-;33375:15;33371:1;33363:6;33359:14;33352:39;33235:163;:::o;33404:366::-;33546:3;33567:67;33631:2;33626:3;33567:67;:::i;:::-;33560:74;;33643:93;33732:3;33643:93;:::i;:::-;33761:2;33756:3;33752:12;33745:19;;33404:366;;;:::o;33776:419::-;33942:4;33980:2;33969:9;33965:18;33957:26;;34029:9;34023:4;34019:20;34015:1;34004:9;34000:17;33993:47;34057:131;34183:4;34057:131;:::i;:::-;34049:139;;33776:419;;;:::o;34201:410::-;34241:7;34264:20;34282:1;34264:20;:::i;:::-;34259:25;;34298:20;34316:1;34298:20;:::i;:::-;34293:25;;34353:1;34350;34346:9;34375:30;34393:11;34375:30;:::i;:::-;34364:41;;34554:1;34545:7;34541:15;34538:1;34535:22;34515:1;34508:9;34488:83;34465:139;;34584:18;;:::i;:::-;34465:139;34249:362;34201:410;;;;:::o;34617:164::-;34757:16;34753:1;34745:6;34741:14;34734:40;34617:164;:::o;34787:366::-;34929:3;34950:67;35014:2;35009:3;34950:67;:::i;:::-;34943:74;;35026:93;35115:3;35026:93;:::i;:::-;35144:2;35139:3;35135:12;35128:19;;34787:366;;;:::o;35159:419::-;35325:4;35363:2;35352:9;35348:18;35340:26;;35412:9;35406:4;35402:20;35398:1;35387:9;35383:17;35376:47;35440:131;35566:4;35440:131;:::i;:::-;35432:139;;35159:419;;;:::o;35584:180::-;35632:77;35629:1;35622:88;35729:4;35726:1;35719:15;35753:4;35750:1;35743:15;35770:141;35819:4;35842:3;35834:11;;35865:3;35862:1;35855:14;35899:4;35896:1;35886:18;35878:26;;35770:141;;;:::o;35917:93::-;35954:6;36001:2;35996;35989:5;35985:14;35981:23;35971:33;;35917:93;;;:::o;36016:107::-;36060:8;36110:5;36104:4;36100:16;36079:37;;36016:107;;;;:::o;36129:393::-;36198:6;36248:1;36236:10;36232:18;36271:97;36301:66;36290:9;36271:97;:::i;:::-;36389:39;36419:8;36408:9;36389:39;:::i;:::-;36377:51;;36461:4;36457:9;36450:5;36446:21;36437:30;;36510:4;36500:8;36496:19;36489:5;36486:30;36476:40;;36205:317;;36129:393;;;;;:::o;36528:60::-;36556:3;36577:5;36570:12;;36528:60;;;:::o;36594:142::-;36644:9;36677:53;36695:34;36704:24;36722:5;36704:24;:::i;:::-;36695:34;:::i;:::-;36677:53;:::i;:::-;36664:66;;36594:142;;;:::o;36742:75::-;36785:3;36806:5;36799:12;;36742:75;;;:::o;36823:269::-;36933:39;36964:7;36933:39;:::i;:::-;36994:91;37043:41;37067:16;37043:41;:::i;:::-;37035:6;37028:4;37022:11;36994:91;:::i;:::-;36988:4;36981:105;36899:193;36823:269;;;:::o;37098:73::-;37143:3;37098:73;:::o;37177:189::-;37254:32;;:::i;:::-;37295:65;37353:6;37345;37339:4;37295:65;:::i;:::-;37230:136;37177:189;;:::o;37372:186::-;37432:120;37449:3;37442:5;37439:14;37432:120;;;37503:39;37540:1;37533:5;37503:39;:::i;:::-;37476:1;37469:5;37465:13;37456:22;;37432:120;;;37372:186;;:::o;37564:543::-;37665:2;37660:3;37657:11;37654:446;;;37699:38;37731:5;37699:38;:::i;:::-;37783:29;37801:10;37783:29;:::i;:::-;37773:8;37769:44;37966:2;37954:10;37951:18;37948:49;;;37987:8;37972:23;;37948:49;38010:80;38066:22;38084:3;38066:22;:::i;:::-;38056:8;38052:37;38039:11;38010:80;:::i;:::-;37669:431;;37654:446;37564:543;;;:::o;38113:117::-;38167:8;38217:5;38211:4;38207:16;38186:37;;38113:117;;;;:::o;38236:169::-;38280:6;38313:51;38361:1;38357:6;38349:5;38346:1;38342:13;38313:51;:::i;:::-;38309:56;38394:4;38388;38384:15;38374:25;;38287:118;38236:169;;;;:::o;38410:295::-;38486:4;38632:29;38657:3;38651:4;38632:29;:::i;:::-;38624:37;;38694:3;38691:1;38687:11;38681:4;38678:21;38670:29;;38410:295;;;;:::o;38710:1395::-;38827:37;38860:3;38827:37;:::i;:::-;38929:18;38921:6;38918:30;38915:56;;;38951:18;;:::i;:::-;38915:56;38995:38;39027:4;39021:11;38995:38;:::i;:::-;39080:67;39140:6;39132;39126:4;39080:67;:::i;:::-;39174:1;39198:4;39185:17;;39230:2;39222:6;39219:14;39247:1;39242:618;;;;39904:1;39921:6;39918:77;;;39970:9;39965:3;39961:19;39955:26;39946:35;;39918:77;40021:67;40081:6;40074:5;40021:67;:::i;:::-;40015:4;40008:81;39877:222;39212:887;;39242:618;39294:4;39290:9;39282:6;39278:22;39328:37;39360:4;39328:37;:::i;:::-;39387:1;39401:208;39415:7;39412:1;39409:14;39401:208;;;39494:9;39489:3;39485:19;39479:26;39471:6;39464:42;39545:1;39537:6;39533:14;39523:24;;39592:2;39581:9;39577:18;39564:31;;39438:4;39435:1;39431:12;39426:17;;39401:208;;;39637:6;39628:7;39625:19;39622:179;;;39695:9;39690:3;39686:19;39680:26;39738:48;39780:4;39772:6;39768:17;39757:9;39738:48;:::i;:::-;39730:6;39723:64;39645:156;39622:179;39847:1;39843;39835:6;39831:14;39827:22;39821:4;39814:36;39249:611;;;39212:887;;38802:1303;;;38710:1395;;:::o;40111:148::-;40213:11;40250:3;40235:18;;40111:148;;;;:::o;40265:390::-;40371:3;40399:39;40432:5;40399:39;:::i;:::-;40454:89;40536:6;40531:3;40454:89;:::i;:::-;40447:96;;40552:65;40610:6;40605:3;40598:4;40591:5;40587:16;40552:65;:::i;:::-;40642:6;40637:3;40633:16;40626:23;;40375:280;40265:390;;;;:::o;40661:435::-;40841:3;40863:95;40954:3;40945:6;40863:95;:::i;:::-;40856:102;;40975:95;41066:3;41057:6;40975:95;:::i;:::-;40968:102;;41087:3;41080:10;;40661:435;;;;;:::o;41102:171::-;41242:23;41238:1;41230:6;41226:14;41219:47;41102:171;:::o;41279:366::-;41421:3;41442:67;41506:2;41501:3;41442:67;:::i;:::-;41435:74;;41518:93;41607:3;41518:93;:::i;:::-;41636:2;41631:3;41627:12;41620:19;;41279:366;;;:::o;41651:419::-;41817:4;41855:2;41844:9;41840:18;41832:26;;41904:9;41898:4;41894:20;41890:1;41879:9;41875:17;41868:47;41932:131;42058:4;41932:131;:::i;:::-;41924:139;;41651:419;;;:::o;42076:225::-;42216:34;42212:1;42204:6;42200:14;42193:58;42285:8;42280:2;42272:6;42268:15;42261:33;42076:225;:::o;42307:366::-;42449:3;42470:67;42534:2;42529:3;42470:67;:::i;:::-;42463:74;;42546:93;42635:3;42546:93;:::i;:::-;42664:2;42659:3;42655:12;42648:19;;42307:366;;;:::o;42679:419::-;42845:4;42883:2;42872:9;42868:18;42860:26;;42932:9;42926:4;42922:20;42918:1;42907:9;42903:17;42896:47;42960:131;43086:4;42960:131;:::i;:::-;42952:139;;42679:419;;;:::o;43104:182::-;43244:34;43240:1;43232:6;43228:14;43221:58;43104:182;:::o;43292:366::-;43434:3;43455:67;43519:2;43514:3;43455:67;:::i;:::-;43448:74;;43531:93;43620:3;43531:93;:::i;:::-;43649:2;43644:3;43640:12;43633:19;;43292:366;;;:::o;43664:419::-;43830:4;43868:2;43857:9;43853:18;43845:26;;43917:9;43911:4;43907:20;43903:1;43892:9;43888:17;43881:47;43945:131;44071:4;43945:131;:::i;:::-;43937:139;;43664:419;;;:::o;44089:98::-;44140:6;44174:5;44168:12;44158:22;;44089:98;;;:::o;44193:168::-;44276:11;44310:6;44305:3;44298:19;44350:4;44345:3;44341:14;44326:29;;44193:168;;;;:::o;44367:373::-;44453:3;44481:38;44513:5;44481:38;:::i;:::-;44535:70;44598:6;44593:3;44535:70;:::i;:::-;44528:77;;44614:65;44672:6;44667:3;44660:4;44653:5;44649:16;44614:65;:::i;:::-;44704:29;44726:6;44704:29;:::i;:::-;44699:3;44695:39;44688:46;;44457:283;44367:373;;;;:::o;44746:640::-;44941:4;44979:3;44968:9;44964:19;44956:27;;44993:71;45061:1;45050:9;45046:17;45037:6;44993:71;:::i;:::-;45074:72;45142:2;45131:9;45127:18;45118:6;45074:72;:::i;:::-;45156;45224:2;45213:9;45209:18;45200:6;45156:72;:::i;:::-;45275:9;45269:4;45265:20;45260:2;45249:9;45245:18;45238:48;45303:76;45374:4;45365:6;45303:76;:::i;:::-;45295:84;;44746:640;;;;;;;:::o;45392:141::-;45448:5;45479:6;45473:13;45464:22;;45495:32;45521:5;45495:32;:::i;:::-;45392:141;;;;:::o;45539:349::-;45608:6;45657:2;45645:9;45636:7;45632:23;45628:32;45625:119;;;45663:79;;:::i;:::-;45625:119;45783:1;45808:63;45863:7;45854:6;45843:9;45839:22;45808:63;:::i;:::-;45798:73;;45754:127;45539:349;;;;:::o;45894:233::-;45933:3;45956:24;45974:5;45956:24;:::i;:::-;45947:33;;46002:66;45995:5;45992:77;45989:103;;46072:18;;:::i;:::-;45989:103;46119:1;46112:5;46108:13;46101:20;;45894:233;;;:::o
Swarm Source
ipfs://2294d02076e334a90fad374186850942d9a0e9068ffc987361a50df53a193573
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.