ERC-20
Overview
Max Total Supply
1,401 SKULL
Holders
0
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 0 Decimals)
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
SkullIsland
Compiler Version
v0.8.7+commit.e28d00a7
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-09-19 */ // File: @openzeppelin/contracts/utils/structs/EnumerableSet.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } // File: @openzeppelin/contracts/access/IAccessControl.sol // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; } // File: @openzeppelin/contracts/access/IAccessControlEnumerable.sol // OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControlEnumerable declared to support ERC165 detection. */ interface IAccessControlEnumerable is IAccessControl { /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) external view returns (address); /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) external view returns (uint256); } // File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The proofs can be generated using the JavaScript library * https://github.com/miguelmota/merkletreejs[merkletreejs]. * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled. * * See `test/utils/cryptography/MerkleProof.test.js` for some examples. * * 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. */ 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 proved to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * _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} * * _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 the sibling nodes in `proof`, * consuming from one or the other at each step according to the instructions given by * `proofFlags`. * * _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} * * _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: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/access/AccessControl.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol) pragma solidity ^0.8.0; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } } // File: @openzeppelin/contracts/access/AccessControlEnumerable.sol // OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol) pragma solidity ^0.8.0; /** * @dev Extension of {AccessControl} that allows enumerating the members of each role. */ abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl { using EnumerableSet for EnumerableSet.AddressSet; mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) { return _roleMembers[role].at(index); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) { return _roleMembers[role].length(); } /** * @dev Overload {_grantRole} to track enumerable memberships */ function _grantRole(bytes32 role, address account) internal virtual override { super._grantRole(role, account); _roleMembers[role].add(account); } /** * @dev Overload {_revokeRole} to track enumerable memberships */ function _revokeRole(bytes32 role, address account) internal virtual override { super._revokeRole(role, account); _roleMembers[role].remove(account); } } // File: @openzeppelin/contracts/access/Ownable.sol // 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: erc721a/contracts/IERC721A.sol // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); } // File: erc721a/contracts/ERC721A.sol // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr) if (curr < _currentIndex) { uint256 packed = _packedOwnerships[curr]; // If not burned. if (packed & _BITMASK_BURNED == 0) { // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `curr` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) public payable virtual override { address owner = ownerOf(tokenId); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned. } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 toMasked; uint256 end = startTokenId + quantity; // Use assembly to loop and emit the `Transfer` event for gas savings. // The duplicated `log4` removes an extra check and reduces stack juggling. // The assembly, together with the surrounding Solidity code, have been // delicately arranged to nudge the compiler into producing optimized opcodes. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. startTokenId // `tokenId`. ) // The `iszero(eq(,))` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. // The compiler will optimize the `iszero` away for performance. for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } if (toMasked == 0) revert MintToZeroAddress(); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } } // File: contracts/SkullIsland.sol pragma solidity ^0.8.4; // @author <https://welabs.io> // ░██╗░░░░░░░██╗███████╗██╗░░░░░░█████╗░██████╗░░██████╗░░░██╗░█████╗░ // ░██║░░██╗░░██║██╔════╝██║░░░░░██╔══██╗██╔══██╗██╔════╝░░░██║██╔══██╗ // ░╚██╗████╗██╔╝█████╗░░██║░░░░░███████║██████╦╝╚█████╗░░░░██║██║░░██║ // ░░████╔═████║░██╔══╝░░██║░░░░░██╔══██║██╔══██╗░╚═══██╗░░░██║██║░░██║ // ░░╚██╔╝░╚██╔╝░███████╗███████╗██║░░██║██████╦╝██████╔╝██╗██║╚█████╔╝ // ░░░╚═╝░░░╚═╝░░╚══════╝╚══════╝╚═╝░░╚═╝╚═════╝░╚═════╝░╚═╝╚═╝░╚════╝░ contract SkullIsland is ERC721A, Ownable, AccessControlEnumerable { uint256 public maxTotalSupply = 3165; uint256 public holderMintPrice = 1200 * 10 ** 18; uint256 public publicMintPrice = 0.007 ether; uint8 private maxTokenPrivate = 1; uint8 private maxTokenPublic = 5; enum SaleState{ CLOSED, PRIVATE, PUBLIC } SaleState public saleState = SaleState.CLOSED; bytes32 private merkleRoot; address public tokenContract; mapping(address => uint256) public maxMintPerAddress; mapping(address => uint256) public mintedPerAddress; mapping(address => uint256) privateMinted; mapping(address => uint256) publicMinted; string _baseTokenURI; constructor(address _tokenContract) ERC721A("SkullIsland", "SKULL") { tokenContract = _tokenContract; _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); } function holderMint(uint256 amount) external { require (saleState == SaleState.PRIVATE, "Sale state should be private"); require(totalSupply() + amount <= maxTotalSupply, "Max supply reached"); require(maxMintPerAddress[msg.sender] > 0, "You are not a holder"); require(amount + mintedPerAddress[msg.sender] <= maxMintPerAddress[msg.sender], "sender address cannot mint more than maxMintPerAddress lands"); IERC20(tokenContract).transferFrom(msg.sender, address(this), holderMintPrice * amount); mintedPerAddress[msg.sender] += amount; _safeMint(_msgSender(), amount); } function privateMint(uint256 amount, bytes32[] calldata proof) public payable { require (saleState == SaleState.PRIVATE, "Sale state should be private"); require(totalSupply() + amount <= maxTotalSupply, "Max supply reached"); require(MerkleProof.verify(proof, merkleRoot, keccak256(abi.encodePacked(msg.sender))), "You are not in the valid whitelist"); require(amount + publicMinted[msg.sender] <= maxTokenPrivate, "sender address cannot mint more than maxMintPerAddress lands"); require(amount * publicMintPrice <= msg.value, "Provided not enough Ether for purchase"); privateMinted[msg.sender] += amount; _safeMint(_msgSender(), amount); } function publicsale(uint256 amount) public payable { require (saleState == SaleState.PUBLIC, "Sale state should be public"); require(totalSupply() + amount <= maxTotalSupply, "Max supply reached"); require(amount + publicMinted[msg.sender] <= maxTokenPublic, "Your token amount reached out max"); require(amount * publicMintPrice <= msg.value, "Provided not enough Ether for purchase"); publicMinted[msg.sender] += amount; _safeMint(_msgSender(), amount); } function withdraw() public onlyOwner { require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Cannot withdraw"); uint256 balance = address(this).balance; if(balance > 0){ payable(owner()).transfer(address(this).balance); } balance = IERC20(tokenContract).balanceOf(address(this)); if(balance > 0){ IERC20(tokenContract).transfer(owner(), balance); } } function setSaleState(SaleState newState) public { require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Cannot alter sale state"); saleState = newState; } function setMerkleRoot(bytes32 _merkleRoot) public { require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Cannot set merkle root"); merkleRoot = _merkleRoot; } function setMaxMintPerAddress(address[] calldata _addresses, uint256[] calldata _mints) public onlyOwner{ for(uint256 i = 0; i < _addresses.length; i++) { maxMintPerAddress[_addresses[i]] = _mints[i]; } } function _baseURI() internal view virtual override returns (string memory) { return _baseTokenURI; } function setBaseURI(string memory baseURI) public onlyOwner { _baseTokenURI = baseURI; } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721A, AccessControlEnumerable) returns (bool) { return super.supportsInterface(interfaceId); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_tokenContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"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":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","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":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"holderMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"holderMintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"address","name":"","type":"address"}],"name":"maxMintPerAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintedPerAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"privateMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"publicMintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"publicsale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","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":[],"name":"saleState","outputs":[{"internalType":"enum SkullIsland.SaleState","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"},{"internalType":"uint256[]","name":"_mints","type":"uint256[]"}],"name":"setMaxMintPerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum SkullIsland.SaleState","name":"newState","type":"uint8"}],"name":"setSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052610c5d600b5568410d586a20a4c00000600c556618de76816d8000600d556001600e60006101000a81548160ff021916908360ff1602179055506005600e60016101000a81548160ff021916908360ff1602179055506000600e60026101000a81548160ff02191690836002811115620000835762000082620006c3565b5b02179055503480156200009557600080fd5b5060405162005362380380620053628339818101604052810190620000bb919062000627565b6040518060400160405280600b81526020017f536b756c6c49736c616e640000000000000000000000000000000000000000008152506040518060400160405280600581526020017f534b554c4c00000000000000000000000000000000000000000000000000000081525081600290805190602001906200013f92919062000560565b5080600390805190602001906200015892919062000560565b5062000169620001fd60201b60201c565b600081905550505062000191620001856200020260201b60201c565b6200020a60201b60201c565b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620001f66000801b620001ea6200020260201b60201c565b620002d060201b60201c565b5062000740565b600090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620002e28282620002e660201b60201c565b5050565b620002fd82826200032e60201b620022121760201c565b6200032981600a60008581526020019081526020016000206200042060201b620022f31790919060201c565b505050565b6200034082826200045860201b60201c565b6200041c5760016009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550620003c16200020260201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600062000450836000018373ffffffffffffffffffffffffffffffffffffffff1660001b620004c360201b60201c565b905092915050565b60006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000620004d783836200053d60201b60201c565b6200053257826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905062000537565b600090505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b8280546200056e906200068d565b90600052602060002090601f016020900481019282620005925760008555620005de565b82601f10620005ad57805160ff1916838001178555620005de565b82800160010185558215620005de579182015b82811115620005dd578251825591602001919060010190620005c0565b5b509050620005ed9190620005f1565b5090565b5b808211156200060c576000816000905550600101620005f2565b5090565b600081519050620006218162000726565b92915050565b60006020828403121562000640576200063f62000721565b5b6000620006508482850162000610565b91505092915050565b600062000666826200066d565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006002820490506001821680620006a657607f821691505b60208210811415620006bd57620006bc620006f2565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600080fd5b620007318162000659565b81146200073d57600080fd5b50565b614c1280620007506000396000f3fe60806040526004361061023b5760003560e01c80638da5cb5b1161012e578063c87b56dd116100ab578063e985e9c51161006f578063e985e9c514610866578063f2fde38b146108a3578063f6252c5a146108cc578063f6769819146108e8578063ff89168a146109115761023b565b8063c87b56dd1461075b578063ca15c87314610798578063d445b978146107d5578063d547741f14610812578063dc53fd921461083b5761023b565b8063a22cb465116100f2578063a22cb46514610692578063af4cd4a9146106bb578063b88d4fde146106f8578063b977fe5514610714578063c364260b146107305761023b565b80638da5cb5b146105975780639010d07c146105c257806391d14854146105ff57806395d89b411461063c578063a217fddf146106675761023b565b80633ccfd60b116101bc578063603f4d5211610180578063603f4d52146104b25780636352211e146104dd57806370a082311461051a578063715018a6146105575780637cb647591461056e5761023b565b80633ccfd60b1461040257806342842e0e1461041957806355a373d61461043557806355f804b3146104605780635a67de07146104895761023b565b806323b872dd1161020357806323b872dd1461032c578063248a9ca3146103485780632ab4d052146103855780632f2ff15d146103b057806336568abe146103d95761023b565b806301ffc9a71461024057806306fdde031461027d578063081812fc146102a8578063095ea7b3146102e557806318160ddd14610301575b600080fd5b34801561024c57600080fd5b5061026760048036038101906102629190613a35565b61093a565b6040516102749190614057565b60405180910390f35b34801561028957600080fd5b5061029261094c565b60405161029f91906140a8565b60405180910390f35b3480156102b457600080fd5b506102cf60048036038101906102ca9190613b05565b6109de565b6040516102dc9190613f90565b60405180910390f35b6102ff60048036038101906102fa919061389a565b610a5d565b005b34801561030d57600080fd5b50610316610ba1565b60405161032391906142aa565b60405180910390f35b61034660048036038101906103419190613784565b610bb8565b005b34801561035457600080fd5b5061036f600480360381019061036a9190613988565b610edd565b60405161037c9190614072565b60405180910390f35b34801561039157600080fd5b5061039a610efd565b6040516103a791906142aa565b60405180910390f35b3480156103bc57600080fd5b506103d760048036038101906103d291906139b5565b610f03565b005b3480156103e557600080fd5b5061040060048036038101906103fb91906139b5565b610f24565b005b34801561040e57600080fd5b50610417610fa7565b005b610433600480360381019061042e9190613784565b6111d0565b005b34801561044157600080fd5b5061044a6111f0565b6040516104579190613f90565b60405180910390f35b34801561046c57600080fd5b5061048760048036038101906104829190613abc565b611216565b005b34801561049557600080fd5b506104b060048036038101906104ab9190613a8f565b611238565b005b3480156104be57600080fd5b506104c76112b8565b6040516104d4919061408d565b60405180910390f35b3480156104e957600080fd5b5061050460048036038101906104ff9190613b05565b6112cb565b6040516105119190613f90565b60405180910390f35b34801561052657600080fd5b50610541600480360381019061053c9190613717565b6112dd565b60405161054e91906142aa565b60405180910390f35b34801561056357600080fd5b5061056c611396565b005b34801561057a57600080fd5b5061059560048036038101906105909190613988565b6113aa565b005b3480156105a357600080fd5b506105ac611407565b6040516105b99190613f90565b60405180910390f35b3480156105ce57600080fd5b506105e960048036038101906105e491906139f5565b611431565b6040516105f69190613f90565b60405180910390f35b34801561060b57600080fd5b50610626600480360381019061062191906139b5565b611460565b6040516106339190614057565b60405180910390f35b34801561064857600080fd5b506106516114cb565b60405161065e91906140a8565b60405180910390f35b34801561067357600080fd5b5061067c61155d565b6040516106899190614072565b60405180910390f35b34801561069e57600080fd5b506106b960048036038101906106b4919061385a565b611564565b005b3480156106c757600080fd5b506106e260048036038101906106dd9190613717565b61166f565b6040516106ef91906142aa565b60405180910390f35b610712600480360381019061070d91906137d7565b611687565b005b61072e60048036038101906107299190613b5f565b6116fa565b005b34801561073c57600080fd5b506107456119d5565b60405161075291906142aa565b60405180910390f35b34801561076757600080fd5b50610782600480360381019061077d9190613b05565b6119db565b60405161078f91906140a8565b60405180910390f35b3480156107a457600080fd5b506107bf60048036038101906107ba9190613988565b611a7a565b6040516107cc91906142aa565b60405180910390f35b3480156107e157600080fd5b506107fc60048036038101906107f79190613717565b611a9e565b60405161080991906142aa565b60405180910390f35b34801561081e57600080fd5b50610839600480360381019061083491906139b5565b611ab6565b005b34801561084757600080fd5b50610850611ad7565b60405161085d91906142aa565b60405180910390f35b34801561087257600080fd5b5061088d60048036038101906108889190613744565b611add565b60405161089a9190614057565b60405180910390f35b3480156108af57600080fd5b506108ca60048036038101906108c59190613717565b611b71565b005b6108e660048036038101906108e19190613b05565b611bf5565b005b3480156108f457600080fd5b5061090f600480360381019061090a91906138da565b611e1a565b005b34801561091d57600080fd5b5061093860048036038101906109339190613b05565b611ece565b005b600061094582612323565b9050919050565b60606002805461095b90614582565b80601f016020809104026020016040519081016040528092919081815260200182805461098790614582565b80156109d45780601f106109a9576101008083540402835291602001916109d4565b820191906000526020600020905b8154815290600101906020018083116109b757829003601f168201915b5050505050905090565b60006109e98261239d565b610a1f576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a68826112cb565b90508073ffffffffffffffffffffffffffffffffffffffff16610a896123fc565b73ffffffffffffffffffffffffffffffffffffffff1614610aec57610ab581610ab06123fc565b611add565b610aeb576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610bab612404565b6001546000540303905090565b6000610bc382612409565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c2a576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610c36846124d7565b91509150610c4c8187610c476123fc565b6124fe565b610c9857610c6186610c5c6123fc565b611add565b610c97576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610cff576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d0c8686866001612542565b8015610d1757600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610de585610dc1888887612548565b7c020000000000000000000000000000000000000000000000000000000017612570565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084161415610e6d576000600185019050600060046000838152602001908152602001600020541415610e6b576000548114610e6a578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610ed5868686600161259b565b505050505050565b600060096000838152602001908152602001600020600101549050919050565b600b5481565b610f0c82610edd565b610f15816125a1565b610f1f83836125b5565b505050565b610f2c6125e9565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f909061426a565b60405180910390fd5b610fa382826125f1565b5050565b610faf612625565b610fc36000801b610fbe6125e9565b611460565b611002576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff99061412a565b60405180910390fd5b6000479050600081111561105f57611018611407565b73ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505015801561105d573d6000803e3d6000fd5b505b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016110ba9190613f90565b60206040518083038186803b1580156110d257600080fd5b505afa1580156110e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110a9190613b32565b905060008111156111cd57601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb61115b611407565b836040518363ffffffff1660e01b815260040161117992919061402e565b602060405180830381600087803b15801561119357600080fd5b505af11580156111a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111cb919061395b565b505b50565b6111eb83838360405180602001604052806000815250611687565b505050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61121e612625565b80601590805190602001906112349291906133d5565b5050565b61124c6000801b6112476125e9565b611460565b61128b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112829061414a565b60405180910390fd5b80600e60026101000a81548160ff021916908360028111156112b0576112af614681565b5b021790555050565b600e60029054906101000a900460ff1681565b60006112d682612409565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611345576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61139e612625565b6113a860006126a3565b565b6113be6000801b6113b96125e9565b611460565b6113fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113f49061424a565b60405180910390fd5b80600f8190555050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600061145882600a600086815260200190815260200160002061276990919063ffffffff16565b905092915050565b60006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6060600380546114da90614582565b80601f016020809104026020016040519081016040528092919081815260200182805461150690614582565b80156115535780601f1061152857610100808354040283529160200191611553565b820191906000526020600020905b81548152906001019060200180831161153657829003601f168201915b5050505050905090565b6000801b81565b80600760006115716123fc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661161e6123fc565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516116639190614057565b60405180910390a35050565b60116020528060005260406000206000915090505481565b611692848484610bb8565b60008373ffffffffffffffffffffffffffffffffffffffff163b146116f4576116bd84848484612783565b6116f3576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6001600281111561170e5761170d614681565b5b600e60029054906101000a900460ff1660028111156117305761172f614681565b5b14611770576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611767906141ca565b60405180910390fd5b600b548361177c610ba1565b611786919061438f565b11156117c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117be9061420a565b60405180910390fd5b61183b828280806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600f54336040516020016118209190613f17565b604051602081830303815290604052805190602001206128e3565b61187a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118719061428a565b60405180910390fd5b600e60009054906101000a900460ff1660ff16601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054846118d8919061438f565b1115611919576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119109061422a565b60405180910390fd5b34600d548461192891906143e5565b1115611969576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119609061416a565b60405180910390fd5b82601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546119b8919061438f565b925050819055506119d06119ca6125e9565b846128fa565b505050565b600c5481565b60606119e68261239d565b611a1c576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611a26612918565b9050600081511415611a475760405180602001604052806000815250611a72565b80611a51846129aa565b604051602001611a62929190613f32565b6040516020818303038152906040525b915050919050565b6000611a97600a6000848152602001908152602001600020612a03565b9050919050565b60126020528060005260406000206000915090505481565b611abf82610edd565b611ac8816125a1565b611ad283836125f1565b505050565b600d5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611b79612625565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611be9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be09061418a565b60405180910390fd5b611bf2816126a3565b50565b600280811115611c0857611c07614681565b5b600e60029054906101000a900460ff166002811115611c2a57611c29614681565b5b14611c6a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c61906140ea565b60405180910390fd5b600b5481611c76610ba1565b611c80919061438f565b1115611cc1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cb89061420a565b60405180910390fd5b600e60019054906101000a900460ff1660ff16601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482611d1f919061438f565b1115611d60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d57906141aa565b60405180910390fd5b34600d5482611d6f91906143e5565b1115611db0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611da79061416a565b60405180910390fd5b80601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dff919061438f565b92505081905550611e17611e116125e9565b826128fa565b50565b611e22612625565b60005b84849050811015611ec757828282818110611e4357611e4261470e565b5b9050602002013560116000878785818110611e6157611e6061470e565b5b9050602002016020810190611e769190613717565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508080611ebf906145e5565b915050611e25565b5050505050565b60016002811115611ee257611ee1614681565b5b600e60029054906101000a900460ff166002811115611f0457611f03614681565b5b14611f44576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3b906141ca565b60405180910390fd5b600b5481611f50610ba1565b611f5a919061438f565b1115611f9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f929061420a565b60405180910390fd5b6000601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541161201d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612014906140ca565b60405180910390fd5b601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054826120a8919061438f565b11156120e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120e09061422a565b60405180910390fd5b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd333084600c5461213791906143e5565b6040518463ffffffff1660e01b815260040161215593929190613fab565b602060405180830381600087803b15801561216f57600080fd5b505af1158015612183573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a7919061395b565b5080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546121f7919061438f565b9250508190555061220f6122096125e9565b826128fa565b50565b61221c8282611460565b6122ef5760016009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506122946125e9565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600061231b836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612a18565b905092915050565b60007f5a05180f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612396575061239582612a88565b5b9050919050565b6000816123a8612404565b111580156123b7575060005482105b80156123f5575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b600090565b60008082905080612418612404565b116124a05760005481101561249f5760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216141561249d575b6000811415612493576004600083600190039350838152602001908152602001600020549050612468565b80925050506124d2565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e861255f868684612b02565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6125b2816125ad6125e9565b612b0b565b50565b6125bf8282612212565b6125e481600a60008581526020019081526020016000206122f390919063ffffffff16565b505050565b600033905090565b6125fb8282612ba8565b61262081600a6000858152602001908152602001600020612c8a90919063ffffffff16565b505050565b61262d6125e9565b73ffffffffffffffffffffffffffffffffffffffff1661264b611407565b73ffffffffffffffffffffffffffffffffffffffff16146126a1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612698906141ea565b60405180910390fd5b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006127788360000183612cba565b60001c905092915050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026127a96123fc565b8786866040518563ffffffff1660e01b81526004016127cb9493929190613fe2565b602060405180830381600087803b1580156127e557600080fd5b505af192505050801561281657506040513d601f19601f820116820180604052508101906128139190613a62565b60015b612890573d8060008114612846576040519150601f19603f3d011682016040523d82523d6000602084013e61284b565b606091505b50600081511415612888576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6000826128f08584612ce5565b1490509392505050565b612914828260405180602001604052806000815250612d3b565b5050565b60606015805461292790614582565b80601f016020809104026020016040519081016040528092919081815260200182805461295390614582565b80156129a05780601f10612975576101008083540402835291602001916129a0565b820191906000526020600020905b81548152906001019060200180831161298357829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b6001156129ee57600184039350600a81066030018453600a81049050806129e9576129ee565b6129c3565b50828103602084039350808452505050919050565b6000612a1182600001612dd8565b9050919050565b6000612a248383612de9565b612a7d578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612a82565b600090505b92915050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612afb5750612afa82612e0c565b5b9050919050565b60009392505050565b612b158282611460565b612ba457612b3a8173ffffffffffffffffffffffffffffffffffffffff166014612e76565b612b488360001c6020612e76565b604051602001612b59929190613f56565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b9b91906140a8565b60405180910390fd5b5050565b612bb28282611460565b15612c865760006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550612c2b6125e9565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000612cb2836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6130b2565b905092915050565b6000826000018281548110612cd257612cd161470e565b5b9060005260206000200154905092915050565b60008082905060005b8451811015612d3057612d1b82868381518110612d0e57612d0d61470e565b5b60200260200101516131c6565b91508080612d28906145e5565b915050612cee565b508091505092915050565b612d4583836131f1565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612dd357600080549050600083820390505b612d856000868380600101945086612783565b612dbb576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110612d72578160005414612dd057600080fd5b50505b505050565b600081600001805490509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b606060006002836002612e8991906143e5565b612e93919061438f565b67ffffffffffffffff811115612eac57612eab61473d565b5b6040519080825280601f01601f191660200182016040528015612ede5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612f1657612f1561470e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612f7a57612f7961470e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612fba91906143e5565b612fc4919061438f565b90505b6001811115613064577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106130065761300561470e565b5b1a60f81b82828151811061301d5761301c61470e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c94508061305d90614558565b9050612fc7565b50600084146130a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161309f9061410a565b60405180910390fd5b8091505092915050565b600080836001016000848152602001908152602001600020549050600081146131ba5760006001826130e4919061443f565b90506000600186600001805490506130fc919061443f565b905081811461316b57600086600001828154811061311d5761311c61470e565b5b90600052602060002001549050808760000184815481106131415761314061470e565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061317f5761317e6146df565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506131c0565b60009150505b92915050565b60008183106131de576131d982846133ae565b6131e9565b6131e883836133ae565b5b905092915050565b6000805490506000821415613232576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61323f6000848385612542565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506132b6836132a76000866000612548565b6132b0856133c5565b17612570565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461335757808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460018101905061331c565b506000821415613393576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060008190555050506133a9600084838561259b565b505050565b600082600052816020526040600020905092915050565b60006001821460e11b9050919050565b8280546133e190614582565b90600052602060002090601f016020900481019282613403576000855561344a565b82601f1061341c57805160ff191683800117855561344a565b8280016001018555821561344a579182015b8281111561344957825182559160200191906001019061342e565b5b509050613457919061345b565b5090565b5b8082111561347457600081600090555060010161345c565b5090565b600061348b613486846142ea565b6142c5565b9050828152602081018484840111156134a7576134a661477b565b5b6134b2848285614516565b509392505050565b60006134cd6134c88461431b565b6142c5565b9050828152602081018484840111156134e9576134e861477b565b5b6134f4848285614516565b509392505050565b60008135905061350b81614b59565b92915050565b60008083601f84011261352757613526614771565b5b8235905067ffffffffffffffff8111156135445761354361476c565b5b6020830191508360208202830111156135605761355f614776565b5b9250929050565b60008083601f84011261357d5761357c614771565b5b8235905067ffffffffffffffff81111561359a5761359961476c565b5b6020830191508360208202830111156135b6576135b5614776565b5b9250929050565b60008083601f8401126135d3576135d2614771565b5b8235905067ffffffffffffffff8111156135f0576135ef61476c565b5b60208301915083602082028301111561360c5761360b614776565b5b9250929050565b60008135905061362281614b70565b92915050565b60008151905061363781614b70565b92915050565b60008135905061364c81614b87565b92915050565b60008135905061366181614b9e565b92915050565b60008151905061367681614b9e565b92915050565b600082601f83011261369157613690614771565b5b81356136a1848260208601613478565b91505092915050565b6000813590506136b981614bb5565b92915050565b600082601f8301126136d4576136d3614771565b5b81356136e48482602086016134ba565b91505092915050565b6000813590506136fc81614bc5565b92915050565b60008151905061371181614bc5565b92915050565b60006020828403121561372d5761372c614785565b5b600061373b848285016134fc565b91505092915050565b6000806040838503121561375b5761375a614785565b5b6000613769858286016134fc565b925050602061377a858286016134fc565b9150509250929050565b60008060006060848603121561379d5761379c614785565b5b60006137ab868287016134fc565b93505060206137bc868287016134fc565b92505060406137cd868287016136ed565b9150509250925092565b600080600080608085870312156137f1576137f0614785565b5b60006137ff878288016134fc565b9450506020613810878288016134fc565b9350506040613821878288016136ed565b925050606085013567ffffffffffffffff81111561384257613841614780565b5b61384e8782880161367c565b91505092959194509250565b6000806040838503121561387157613870614785565b5b600061387f858286016134fc565b925050602061389085828601613613565b9150509250929050565b600080604083850312156138b1576138b0614785565b5b60006138bf858286016134fc565b92505060206138d0858286016136ed565b9150509250929050565b600080600080604085870312156138f4576138f3614785565b5b600085013567ffffffffffffffff81111561391257613911614780565b5b61391e87828801613511565b9450945050602085013567ffffffffffffffff81111561394157613940614780565b5b61394d878288016135bd565b925092505092959194509250565b60006020828403121561397157613970614785565b5b600061397f84828501613628565b91505092915050565b60006020828403121561399e5761399d614785565b5b60006139ac8482850161363d565b91505092915050565b600080604083850312156139cc576139cb614785565b5b60006139da8582860161363d565b92505060206139eb858286016134fc565b9150509250929050565b60008060408385031215613a0c57613a0b614785565b5b6000613a1a8582860161363d565b9250506020613a2b858286016136ed565b9150509250929050565b600060208284031215613a4b57613a4a614785565b5b6000613a5984828501613652565b91505092915050565b600060208284031215613a7857613a77614785565b5b6000613a8684828501613667565b91505092915050565b600060208284031215613aa557613aa4614785565b5b6000613ab3848285016136aa565b91505092915050565b600060208284031215613ad257613ad1614785565b5b600082013567ffffffffffffffff811115613af057613aef614780565b5b613afc848285016136bf565b91505092915050565b600060208284031215613b1b57613b1a614785565b5b6000613b29848285016136ed565b91505092915050565b600060208284031215613b4857613b47614785565b5b6000613b5684828501613702565b91505092915050565b600080600060408486031215613b7857613b77614785565b5b6000613b86868287016136ed565b935050602084013567ffffffffffffffff811115613ba757613ba6614780565b5b613bb386828701613567565b92509250509250925092565b613bc881614473565b82525050565b613bdf613bda82614473565b61462e565b82525050565b613bee81614485565b82525050565b613bfd81614491565b82525050565b6000613c0e8261434c565b613c188185614362565b9350613c28818560208601614525565b613c318161478a565b840191505092915050565b613c4581614504565b82525050565b6000613c5682614357565b613c608185614373565b9350613c70818560208601614525565b613c798161478a565b840191505092915050565b6000613c8f82614357565b613c998185614384565b9350613ca9818560208601614525565b80840191505092915050565b6000613cc2601483614373565b9150613ccd826147a8565b602082019050919050565b6000613ce5601b83614373565b9150613cf0826147d1565b602082019050919050565b6000613d08602083614373565b9150613d13826147fa565b602082019050919050565b6000613d2b600f83614373565b9150613d3682614823565b602082019050919050565b6000613d4e601783614373565b9150613d598261484c565b602082019050919050565b6000613d71602683614373565b9150613d7c82614875565b604082019050919050565b6000613d94602683614373565b9150613d9f826148c4565b604082019050919050565b6000613db7602183614373565b9150613dc282614913565b604082019050919050565b6000613dda601c83614373565b9150613de582614962565b602082019050919050565b6000613dfd602083614373565b9150613e088261498b565b602082019050919050565b6000613e20601283614373565b9150613e2b826149b4565b602082019050919050565b6000613e43601783614384565b9150613e4e826149dd565b601782019050919050565b6000613e66603c83614373565b9150613e7182614a06565b604082019050919050565b6000613e89601683614373565b9150613e9482614a55565b602082019050919050565b6000613eac601183614384565b9150613eb782614a7e565b601182019050919050565b6000613ecf602f83614373565b9150613eda82614aa7565b604082019050919050565b6000613ef2602283614373565b9150613efd82614af6565b604082019050919050565b613f11816144fa565b82525050565b6000613f238284613bce565b60148201915081905092915050565b6000613f3e8285613c84565b9150613f4a8284613c84565b91508190509392505050565b6000613f6182613e36565b9150613f6d8285613c84565b9150613f7882613e9f565b9150613f848284613c84565b91508190509392505050565b6000602082019050613fa56000830184613bbf565b92915050565b6000606082019050613fc06000830186613bbf565b613fcd6020830185613bbf565b613fda6040830184613f08565b949350505050565b6000608082019050613ff76000830187613bbf565b6140046020830186613bbf565b6140116040830185613f08565b81810360608301526140238184613c03565b905095945050505050565b60006040820190506140436000830185613bbf565b6140506020830184613f08565b9392505050565b600060208201905061406c6000830184613be5565b92915050565b60006020820190506140876000830184613bf4565b92915050565b60006020820190506140a26000830184613c3c565b92915050565b600060208201905081810360008301526140c28184613c4b565b905092915050565b600060208201905081810360008301526140e381613cb5565b9050919050565b6000602082019050818103600083015261410381613cd8565b9050919050565b6000602082019050818103600083015261412381613cfb565b9050919050565b6000602082019050818103600083015261414381613d1e565b9050919050565b6000602082019050818103600083015261416381613d41565b9050919050565b6000602082019050818103600083015261418381613d64565b9050919050565b600060208201905081810360008301526141a381613d87565b9050919050565b600060208201905081810360008301526141c381613daa565b9050919050565b600060208201905081810360008301526141e381613dcd565b9050919050565b6000602082019050818103600083015261420381613df0565b9050919050565b6000602082019050818103600083015261422381613e13565b9050919050565b6000602082019050818103600083015261424381613e59565b9050919050565b6000602082019050818103600083015261426381613e7c565b9050919050565b6000602082019050818103600083015261428381613ec2565b9050919050565b600060208201905081810360008301526142a381613ee5565b9050919050565b60006020820190506142bf6000830184613f08565b92915050565b60006142cf6142e0565b90506142db82826145b4565b919050565b6000604051905090565b600067ffffffffffffffff8211156143055761430461473d565b5b61430e8261478a565b9050602081019050919050565b600067ffffffffffffffff8211156143365761433561473d565b5b61433f8261478a565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600061439a826144fa565b91506143a5836144fa565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156143da576143d9614652565b5b828201905092915050565b60006143f0826144fa565b91506143fb836144fa565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561443457614433614652565b5b828202905092915050565b600061444a826144fa565b9150614455836144fa565b92508282101561446857614467614652565b5b828203905092915050565b600061447e826144da565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60008190506144d582614b45565b919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600061450f826144c7565b9050919050565b82818337600083830152505050565b60005b83811015614543578082015181840152602081019050614528565b83811115614552576000848401525b50505050565b6000614563826144fa565b9150600082141561457757614576614652565b5b600182039050919050565b6000600282049050600182168061459a57607f821691505b602082108114156145ae576145ad6146b0565b5b50919050565b6145bd8261478a565b810181811067ffffffffffffffff821117156145dc576145db61473d565b5b80604052505050565b60006145f0826144fa565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561462357614622614652565b5b600182019050919050565b600061463982614640565b9050919050565b600061464b8261479b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f596f7520617265206e6f74206120686f6c646572000000000000000000000000600082015250565b7f53616c652073746174652073686f756c64206265207075626c69630000000000600082015250565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f43616e6e6f742077697468647261770000000000000000000000000000000000600082015250565b7f43616e6e6f7420616c7465722073616c65207374617465000000000000000000600082015250565b7f50726f7669646564206e6f7420656e6f75676820457468657220666f7220707560008201527f7263686173650000000000000000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f596f757220746f6b656e20616d6f756e742072656163686564206f7574206d6160008201527f7800000000000000000000000000000000000000000000000000000000000000602082015250565b7f53616c652073746174652073686f756c64206265207072697661746500000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4d617820737570706c7920726561636865640000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f73656e64657220616464726573732063616e6e6f74206d696e74206d6f72652060008201527f7468616e206d61784d696e7450657241646472657373206c616e647300000000602082015250565b7f43616e6e6f7420736574206d65726b6c6520726f6f7400000000000000000000600082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b7f596f7520617265206e6f7420696e207468652076616c69642077686974656c6960008201527f7374000000000000000000000000000000000000000000000000000000000000602082015250565b60038110614b5657614b55614681565b5b50565b614b6281614473565b8114614b6d57600080fd5b50565b614b7981614485565b8114614b8457600080fd5b50565b614b9081614491565b8114614b9b57600080fd5b50565b614ba78161449b565b8114614bb257600080fd5b50565b60038110614bc257600080fd5b50565b614bce816144fa565b8114614bd957600080fd5b5056fea264697066735822122077b8ce4a679b6d99ece6fe862f312a60f146f8bf241c6cd703e5e1a580ad330064736f6c63430008070033000000000000000000000000d405f9908dec587a5ed77ea06760ea868f5de7c3
Deployed Bytecode
0x60806040526004361061023b5760003560e01c80638da5cb5b1161012e578063c87b56dd116100ab578063e985e9c51161006f578063e985e9c514610866578063f2fde38b146108a3578063f6252c5a146108cc578063f6769819146108e8578063ff89168a146109115761023b565b8063c87b56dd1461075b578063ca15c87314610798578063d445b978146107d5578063d547741f14610812578063dc53fd921461083b5761023b565b8063a22cb465116100f2578063a22cb46514610692578063af4cd4a9146106bb578063b88d4fde146106f8578063b977fe5514610714578063c364260b146107305761023b565b80638da5cb5b146105975780639010d07c146105c257806391d14854146105ff57806395d89b411461063c578063a217fddf146106675761023b565b80633ccfd60b116101bc578063603f4d5211610180578063603f4d52146104b25780636352211e146104dd57806370a082311461051a578063715018a6146105575780637cb647591461056e5761023b565b80633ccfd60b1461040257806342842e0e1461041957806355a373d61461043557806355f804b3146104605780635a67de07146104895761023b565b806323b872dd1161020357806323b872dd1461032c578063248a9ca3146103485780632ab4d052146103855780632f2ff15d146103b057806336568abe146103d95761023b565b806301ffc9a71461024057806306fdde031461027d578063081812fc146102a8578063095ea7b3146102e557806318160ddd14610301575b600080fd5b34801561024c57600080fd5b5061026760048036038101906102629190613a35565b61093a565b6040516102749190614057565b60405180910390f35b34801561028957600080fd5b5061029261094c565b60405161029f91906140a8565b60405180910390f35b3480156102b457600080fd5b506102cf60048036038101906102ca9190613b05565b6109de565b6040516102dc9190613f90565b60405180910390f35b6102ff60048036038101906102fa919061389a565b610a5d565b005b34801561030d57600080fd5b50610316610ba1565b60405161032391906142aa565b60405180910390f35b61034660048036038101906103419190613784565b610bb8565b005b34801561035457600080fd5b5061036f600480360381019061036a9190613988565b610edd565b60405161037c9190614072565b60405180910390f35b34801561039157600080fd5b5061039a610efd565b6040516103a791906142aa565b60405180910390f35b3480156103bc57600080fd5b506103d760048036038101906103d291906139b5565b610f03565b005b3480156103e557600080fd5b5061040060048036038101906103fb91906139b5565b610f24565b005b34801561040e57600080fd5b50610417610fa7565b005b610433600480360381019061042e9190613784565b6111d0565b005b34801561044157600080fd5b5061044a6111f0565b6040516104579190613f90565b60405180910390f35b34801561046c57600080fd5b5061048760048036038101906104829190613abc565b611216565b005b34801561049557600080fd5b506104b060048036038101906104ab9190613a8f565b611238565b005b3480156104be57600080fd5b506104c76112b8565b6040516104d4919061408d565b60405180910390f35b3480156104e957600080fd5b5061050460048036038101906104ff9190613b05565b6112cb565b6040516105119190613f90565b60405180910390f35b34801561052657600080fd5b50610541600480360381019061053c9190613717565b6112dd565b60405161054e91906142aa565b60405180910390f35b34801561056357600080fd5b5061056c611396565b005b34801561057a57600080fd5b5061059560048036038101906105909190613988565b6113aa565b005b3480156105a357600080fd5b506105ac611407565b6040516105b99190613f90565b60405180910390f35b3480156105ce57600080fd5b506105e960048036038101906105e491906139f5565b611431565b6040516105f69190613f90565b60405180910390f35b34801561060b57600080fd5b50610626600480360381019061062191906139b5565b611460565b6040516106339190614057565b60405180910390f35b34801561064857600080fd5b506106516114cb565b60405161065e91906140a8565b60405180910390f35b34801561067357600080fd5b5061067c61155d565b6040516106899190614072565b60405180910390f35b34801561069e57600080fd5b506106b960048036038101906106b4919061385a565b611564565b005b3480156106c757600080fd5b506106e260048036038101906106dd9190613717565b61166f565b6040516106ef91906142aa565b60405180910390f35b610712600480360381019061070d91906137d7565b611687565b005b61072e60048036038101906107299190613b5f565b6116fa565b005b34801561073c57600080fd5b506107456119d5565b60405161075291906142aa565b60405180910390f35b34801561076757600080fd5b50610782600480360381019061077d9190613b05565b6119db565b60405161078f91906140a8565b60405180910390f35b3480156107a457600080fd5b506107bf60048036038101906107ba9190613988565b611a7a565b6040516107cc91906142aa565b60405180910390f35b3480156107e157600080fd5b506107fc60048036038101906107f79190613717565b611a9e565b60405161080991906142aa565b60405180910390f35b34801561081e57600080fd5b50610839600480360381019061083491906139b5565b611ab6565b005b34801561084757600080fd5b50610850611ad7565b60405161085d91906142aa565b60405180910390f35b34801561087257600080fd5b5061088d60048036038101906108889190613744565b611add565b60405161089a9190614057565b60405180910390f35b3480156108af57600080fd5b506108ca60048036038101906108c59190613717565b611b71565b005b6108e660048036038101906108e19190613b05565b611bf5565b005b3480156108f457600080fd5b5061090f600480360381019061090a91906138da565b611e1a565b005b34801561091d57600080fd5b5061093860048036038101906109339190613b05565b611ece565b005b600061094582612323565b9050919050565b60606002805461095b90614582565b80601f016020809104026020016040519081016040528092919081815260200182805461098790614582565b80156109d45780601f106109a9576101008083540402835291602001916109d4565b820191906000526020600020905b8154815290600101906020018083116109b757829003601f168201915b5050505050905090565b60006109e98261239d565b610a1f576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a68826112cb565b90508073ffffffffffffffffffffffffffffffffffffffff16610a896123fc565b73ffffffffffffffffffffffffffffffffffffffff1614610aec57610ab581610ab06123fc565b611add565b610aeb576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610bab612404565b6001546000540303905090565b6000610bc382612409565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c2a576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610c36846124d7565b91509150610c4c8187610c476123fc565b6124fe565b610c9857610c6186610c5c6123fc565b611add565b610c97576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610cff576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d0c8686866001612542565b8015610d1757600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610de585610dc1888887612548565b7c020000000000000000000000000000000000000000000000000000000017612570565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084161415610e6d576000600185019050600060046000838152602001908152602001600020541415610e6b576000548114610e6a578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610ed5868686600161259b565b505050505050565b600060096000838152602001908152602001600020600101549050919050565b600b5481565b610f0c82610edd565b610f15816125a1565b610f1f83836125b5565b505050565b610f2c6125e9565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f909061426a565b60405180910390fd5b610fa382826125f1565b5050565b610faf612625565b610fc36000801b610fbe6125e9565b611460565b611002576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff99061412a565b60405180910390fd5b6000479050600081111561105f57611018611407565b73ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505015801561105d573d6000803e3d6000fd5b505b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016110ba9190613f90565b60206040518083038186803b1580156110d257600080fd5b505afa1580156110e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110a9190613b32565b905060008111156111cd57601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb61115b611407565b836040518363ffffffff1660e01b815260040161117992919061402e565b602060405180830381600087803b15801561119357600080fd5b505af11580156111a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111cb919061395b565b505b50565b6111eb83838360405180602001604052806000815250611687565b505050565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61121e612625565b80601590805190602001906112349291906133d5565b5050565b61124c6000801b6112476125e9565b611460565b61128b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112829061414a565b60405180910390fd5b80600e60026101000a81548160ff021916908360028111156112b0576112af614681565b5b021790555050565b600e60029054906101000a900460ff1681565b60006112d682612409565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611345576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61139e612625565b6113a860006126a3565b565b6113be6000801b6113b96125e9565b611460565b6113fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113f49061424a565b60405180910390fd5b80600f8190555050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600061145882600a600086815260200190815260200160002061276990919063ffffffff16565b905092915050565b60006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6060600380546114da90614582565b80601f016020809104026020016040519081016040528092919081815260200182805461150690614582565b80156115535780601f1061152857610100808354040283529160200191611553565b820191906000526020600020905b81548152906001019060200180831161153657829003601f168201915b5050505050905090565b6000801b81565b80600760006115716123fc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661161e6123fc565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516116639190614057565b60405180910390a35050565b60116020528060005260406000206000915090505481565b611692848484610bb8565b60008373ffffffffffffffffffffffffffffffffffffffff163b146116f4576116bd84848484612783565b6116f3576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6001600281111561170e5761170d614681565b5b600e60029054906101000a900460ff1660028111156117305761172f614681565b5b14611770576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611767906141ca565b60405180910390fd5b600b548361177c610ba1565b611786919061438f565b11156117c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117be9061420a565b60405180910390fd5b61183b828280806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600f54336040516020016118209190613f17565b604051602081830303815290604052805190602001206128e3565b61187a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118719061428a565b60405180910390fd5b600e60009054906101000a900460ff1660ff16601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054846118d8919061438f565b1115611919576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119109061422a565b60405180910390fd5b34600d548461192891906143e5565b1115611969576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119609061416a565b60405180910390fd5b82601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546119b8919061438f565b925050819055506119d06119ca6125e9565b846128fa565b505050565b600c5481565b60606119e68261239d565b611a1c576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611a26612918565b9050600081511415611a475760405180602001604052806000815250611a72565b80611a51846129aa565b604051602001611a62929190613f32565b6040516020818303038152906040525b915050919050565b6000611a97600a6000848152602001908152602001600020612a03565b9050919050565b60126020528060005260406000206000915090505481565b611abf82610edd565b611ac8816125a1565b611ad283836125f1565b505050565b600d5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611b79612625565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611be9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be09061418a565b60405180910390fd5b611bf2816126a3565b50565b600280811115611c0857611c07614681565b5b600e60029054906101000a900460ff166002811115611c2a57611c29614681565b5b14611c6a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c61906140ea565b60405180910390fd5b600b5481611c76610ba1565b611c80919061438f565b1115611cc1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cb89061420a565b60405180910390fd5b600e60019054906101000a900460ff1660ff16601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482611d1f919061438f565b1115611d60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d57906141aa565b60405180910390fd5b34600d5482611d6f91906143e5565b1115611db0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611da79061416a565b60405180910390fd5b80601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dff919061438f565b92505081905550611e17611e116125e9565b826128fa565b50565b611e22612625565b60005b84849050811015611ec757828282818110611e4357611e4261470e565b5b9050602002013560116000878785818110611e6157611e6061470e565b5b9050602002016020810190611e769190613717565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508080611ebf906145e5565b915050611e25565b5050505050565b60016002811115611ee257611ee1614681565b5b600e60029054906101000a900460ff166002811115611f0457611f03614681565b5b14611f44576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3b906141ca565b60405180910390fd5b600b5481611f50610ba1565b611f5a919061438f565b1115611f9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f929061420a565b60405180910390fd5b6000601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541161201d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612014906140ca565b60405180910390fd5b601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054826120a8919061438f565b11156120e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120e09061422a565b60405180910390fd5b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd333084600c5461213791906143e5565b6040518463ffffffff1660e01b815260040161215593929190613fab565b602060405180830381600087803b15801561216f57600080fd5b505af1158015612183573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a7919061395b565b5080601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546121f7919061438f565b9250508190555061220f6122096125e9565b826128fa565b50565b61221c8282611460565b6122ef5760016009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506122946125e9565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600061231b836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612a18565b905092915050565b60007f5a05180f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612396575061239582612a88565b5b9050919050565b6000816123a8612404565b111580156123b7575060005482105b80156123f5575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b600090565b60008082905080612418612404565b116124a05760005481101561249f5760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216141561249d575b6000811415612493576004600083600190039350838152602001908152602001600020549050612468565b80925050506124d2565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e861255f868684612b02565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6125b2816125ad6125e9565b612b0b565b50565b6125bf8282612212565b6125e481600a60008581526020019081526020016000206122f390919063ffffffff16565b505050565b600033905090565b6125fb8282612ba8565b61262081600a6000858152602001908152602001600020612c8a90919063ffffffff16565b505050565b61262d6125e9565b73ffffffffffffffffffffffffffffffffffffffff1661264b611407565b73ffffffffffffffffffffffffffffffffffffffff16146126a1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612698906141ea565b60405180910390fd5b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006127788360000183612cba565b60001c905092915050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026127a96123fc565b8786866040518563ffffffff1660e01b81526004016127cb9493929190613fe2565b602060405180830381600087803b1580156127e557600080fd5b505af192505050801561281657506040513d601f19601f820116820180604052508101906128139190613a62565b60015b612890573d8060008114612846576040519150601f19603f3d011682016040523d82523d6000602084013e61284b565b606091505b50600081511415612888576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6000826128f08584612ce5565b1490509392505050565b612914828260405180602001604052806000815250612d3b565b5050565b60606015805461292790614582565b80601f016020809104026020016040519081016040528092919081815260200182805461295390614582565b80156129a05780601f10612975576101008083540402835291602001916129a0565b820191906000526020600020905b81548152906001019060200180831161298357829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b6001156129ee57600184039350600a81066030018453600a81049050806129e9576129ee565b6129c3565b50828103602084039350808452505050919050565b6000612a1182600001612dd8565b9050919050565b6000612a248383612de9565b612a7d578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612a82565b600090505b92915050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612afb5750612afa82612e0c565b5b9050919050565b60009392505050565b612b158282611460565b612ba457612b3a8173ffffffffffffffffffffffffffffffffffffffff166014612e76565b612b488360001c6020612e76565b604051602001612b59929190613f56565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b9b91906140a8565b60405180910390fd5b5050565b612bb28282611460565b15612c865760006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550612c2b6125e9565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000612cb2836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6130b2565b905092915050565b6000826000018281548110612cd257612cd161470e565b5b9060005260206000200154905092915050565b60008082905060005b8451811015612d3057612d1b82868381518110612d0e57612d0d61470e565b5b60200260200101516131c6565b91508080612d28906145e5565b915050612cee565b508091505092915050565b612d4583836131f1565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612dd357600080549050600083820390505b612d856000868380600101945086612783565b612dbb576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110612d72578160005414612dd057600080fd5b50505b505050565b600081600001805490509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b606060006002836002612e8991906143e5565b612e93919061438f565b67ffffffffffffffff811115612eac57612eab61473d565b5b6040519080825280601f01601f191660200182016040528015612ede5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612f1657612f1561470e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612f7a57612f7961470e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612fba91906143e5565b612fc4919061438f565b90505b6001811115613064577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106130065761300561470e565b5b1a60f81b82828151811061301d5761301c61470e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c94508061305d90614558565b9050612fc7565b50600084146130a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161309f9061410a565b60405180910390fd5b8091505092915050565b600080836001016000848152602001908152602001600020549050600081146131ba5760006001826130e4919061443f565b90506000600186600001805490506130fc919061443f565b905081811461316b57600086600001828154811061311d5761311c61470e565b5b90600052602060002001549050808760000184815481106131415761314061470e565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061317f5761317e6146df565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506131c0565b60009150505b92915050565b60008183106131de576131d982846133ae565b6131e9565b6131e883836133ae565b5b905092915050565b6000805490506000821415613232576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61323f6000848385612542565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506132b6836132a76000866000612548565b6132b0856133c5565b17612570565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461335757808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460018101905061331c565b506000821415613393576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060008190555050506133a9600084838561259b565b505050565b600082600052816020526040600020905092915050565b60006001821460e11b9050919050565b8280546133e190614582565b90600052602060002090601f016020900481019282613403576000855561344a565b82601f1061341c57805160ff191683800117855561344a565b8280016001018555821561344a579182015b8281111561344957825182559160200191906001019061342e565b5b509050613457919061345b565b5090565b5b8082111561347457600081600090555060010161345c565b5090565b600061348b613486846142ea565b6142c5565b9050828152602081018484840111156134a7576134a661477b565b5b6134b2848285614516565b509392505050565b60006134cd6134c88461431b565b6142c5565b9050828152602081018484840111156134e9576134e861477b565b5b6134f4848285614516565b509392505050565b60008135905061350b81614b59565b92915050565b60008083601f84011261352757613526614771565b5b8235905067ffffffffffffffff8111156135445761354361476c565b5b6020830191508360208202830111156135605761355f614776565b5b9250929050565b60008083601f84011261357d5761357c614771565b5b8235905067ffffffffffffffff81111561359a5761359961476c565b5b6020830191508360208202830111156135b6576135b5614776565b5b9250929050565b60008083601f8401126135d3576135d2614771565b5b8235905067ffffffffffffffff8111156135f0576135ef61476c565b5b60208301915083602082028301111561360c5761360b614776565b5b9250929050565b60008135905061362281614b70565b92915050565b60008151905061363781614b70565b92915050565b60008135905061364c81614b87565b92915050565b60008135905061366181614b9e565b92915050565b60008151905061367681614b9e565b92915050565b600082601f83011261369157613690614771565b5b81356136a1848260208601613478565b91505092915050565b6000813590506136b981614bb5565b92915050565b600082601f8301126136d4576136d3614771565b5b81356136e48482602086016134ba565b91505092915050565b6000813590506136fc81614bc5565b92915050565b60008151905061371181614bc5565b92915050565b60006020828403121561372d5761372c614785565b5b600061373b848285016134fc565b91505092915050565b6000806040838503121561375b5761375a614785565b5b6000613769858286016134fc565b925050602061377a858286016134fc565b9150509250929050565b60008060006060848603121561379d5761379c614785565b5b60006137ab868287016134fc565b93505060206137bc868287016134fc565b92505060406137cd868287016136ed565b9150509250925092565b600080600080608085870312156137f1576137f0614785565b5b60006137ff878288016134fc565b9450506020613810878288016134fc565b9350506040613821878288016136ed565b925050606085013567ffffffffffffffff81111561384257613841614780565b5b61384e8782880161367c565b91505092959194509250565b6000806040838503121561387157613870614785565b5b600061387f858286016134fc565b925050602061389085828601613613565b9150509250929050565b600080604083850312156138b1576138b0614785565b5b60006138bf858286016134fc565b92505060206138d0858286016136ed565b9150509250929050565b600080600080604085870312156138f4576138f3614785565b5b600085013567ffffffffffffffff81111561391257613911614780565b5b61391e87828801613511565b9450945050602085013567ffffffffffffffff81111561394157613940614780565b5b61394d878288016135bd565b925092505092959194509250565b60006020828403121561397157613970614785565b5b600061397f84828501613628565b91505092915050565b60006020828403121561399e5761399d614785565b5b60006139ac8482850161363d565b91505092915050565b600080604083850312156139cc576139cb614785565b5b60006139da8582860161363d565b92505060206139eb858286016134fc565b9150509250929050565b60008060408385031215613a0c57613a0b614785565b5b6000613a1a8582860161363d565b9250506020613a2b858286016136ed565b9150509250929050565b600060208284031215613a4b57613a4a614785565b5b6000613a5984828501613652565b91505092915050565b600060208284031215613a7857613a77614785565b5b6000613a8684828501613667565b91505092915050565b600060208284031215613aa557613aa4614785565b5b6000613ab3848285016136aa565b91505092915050565b600060208284031215613ad257613ad1614785565b5b600082013567ffffffffffffffff811115613af057613aef614780565b5b613afc848285016136bf565b91505092915050565b600060208284031215613b1b57613b1a614785565b5b6000613b29848285016136ed565b91505092915050565b600060208284031215613b4857613b47614785565b5b6000613b5684828501613702565b91505092915050565b600080600060408486031215613b7857613b77614785565b5b6000613b86868287016136ed565b935050602084013567ffffffffffffffff811115613ba757613ba6614780565b5b613bb386828701613567565b92509250509250925092565b613bc881614473565b82525050565b613bdf613bda82614473565b61462e565b82525050565b613bee81614485565b82525050565b613bfd81614491565b82525050565b6000613c0e8261434c565b613c188185614362565b9350613c28818560208601614525565b613c318161478a565b840191505092915050565b613c4581614504565b82525050565b6000613c5682614357565b613c608185614373565b9350613c70818560208601614525565b613c798161478a565b840191505092915050565b6000613c8f82614357565b613c998185614384565b9350613ca9818560208601614525565b80840191505092915050565b6000613cc2601483614373565b9150613ccd826147a8565b602082019050919050565b6000613ce5601b83614373565b9150613cf0826147d1565b602082019050919050565b6000613d08602083614373565b9150613d13826147fa565b602082019050919050565b6000613d2b600f83614373565b9150613d3682614823565b602082019050919050565b6000613d4e601783614373565b9150613d598261484c565b602082019050919050565b6000613d71602683614373565b9150613d7c82614875565b604082019050919050565b6000613d94602683614373565b9150613d9f826148c4565b604082019050919050565b6000613db7602183614373565b9150613dc282614913565b604082019050919050565b6000613dda601c83614373565b9150613de582614962565b602082019050919050565b6000613dfd602083614373565b9150613e088261498b565b602082019050919050565b6000613e20601283614373565b9150613e2b826149b4565b602082019050919050565b6000613e43601783614384565b9150613e4e826149dd565b601782019050919050565b6000613e66603c83614373565b9150613e7182614a06565b604082019050919050565b6000613e89601683614373565b9150613e9482614a55565b602082019050919050565b6000613eac601183614384565b9150613eb782614a7e565b601182019050919050565b6000613ecf602f83614373565b9150613eda82614aa7565b604082019050919050565b6000613ef2602283614373565b9150613efd82614af6565b604082019050919050565b613f11816144fa565b82525050565b6000613f238284613bce565b60148201915081905092915050565b6000613f3e8285613c84565b9150613f4a8284613c84565b91508190509392505050565b6000613f6182613e36565b9150613f6d8285613c84565b9150613f7882613e9f565b9150613f848284613c84565b91508190509392505050565b6000602082019050613fa56000830184613bbf565b92915050565b6000606082019050613fc06000830186613bbf565b613fcd6020830185613bbf565b613fda6040830184613f08565b949350505050565b6000608082019050613ff76000830187613bbf565b6140046020830186613bbf565b6140116040830185613f08565b81810360608301526140238184613c03565b905095945050505050565b60006040820190506140436000830185613bbf565b6140506020830184613f08565b9392505050565b600060208201905061406c6000830184613be5565b92915050565b60006020820190506140876000830184613bf4565b92915050565b60006020820190506140a26000830184613c3c565b92915050565b600060208201905081810360008301526140c28184613c4b565b905092915050565b600060208201905081810360008301526140e381613cb5565b9050919050565b6000602082019050818103600083015261410381613cd8565b9050919050565b6000602082019050818103600083015261412381613cfb565b9050919050565b6000602082019050818103600083015261414381613d1e565b9050919050565b6000602082019050818103600083015261416381613d41565b9050919050565b6000602082019050818103600083015261418381613d64565b9050919050565b600060208201905081810360008301526141a381613d87565b9050919050565b600060208201905081810360008301526141c381613daa565b9050919050565b600060208201905081810360008301526141e381613dcd565b9050919050565b6000602082019050818103600083015261420381613df0565b9050919050565b6000602082019050818103600083015261422381613e13565b9050919050565b6000602082019050818103600083015261424381613e59565b9050919050565b6000602082019050818103600083015261426381613e7c565b9050919050565b6000602082019050818103600083015261428381613ec2565b9050919050565b600060208201905081810360008301526142a381613ee5565b9050919050565b60006020820190506142bf6000830184613f08565b92915050565b60006142cf6142e0565b90506142db82826145b4565b919050565b6000604051905090565b600067ffffffffffffffff8211156143055761430461473d565b5b61430e8261478a565b9050602081019050919050565b600067ffffffffffffffff8211156143365761433561473d565b5b61433f8261478a565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600061439a826144fa565b91506143a5836144fa565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156143da576143d9614652565b5b828201905092915050565b60006143f0826144fa565b91506143fb836144fa565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561443457614433614652565b5b828202905092915050565b600061444a826144fa565b9150614455836144fa565b92508282101561446857614467614652565b5b828203905092915050565b600061447e826144da565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60008190506144d582614b45565b919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600061450f826144c7565b9050919050565b82818337600083830152505050565b60005b83811015614543578082015181840152602081019050614528565b83811115614552576000848401525b50505050565b6000614563826144fa565b9150600082141561457757614576614652565b5b600182039050919050565b6000600282049050600182168061459a57607f821691505b602082108114156145ae576145ad6146b0565b5b50919050565b6145bd8261478a565b810181811067ffffffffffffffff821117156145dc576145db61473d565b5b80604052505050565b60006145f0826144fa565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561462357614622614652565b5b600182019050919050565b600061463982614640565b9050919050565b600061464b8261479b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f596f7520617265206e6f74206120686f6c646572000000000000000000000000600082015250565b7f53616c652073746174652073686f756c64206265207075626c69630000000000600082015250565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f43616e6e6f742077697468647261770000000000000000000000000000000000600082015250565b7f43616e6e6f7420616c7465722073616c65207374617465000000000000000000600082015250565b7f50726f7669646564206e6f7420656e6f75676820457468657220666f7220707560008201527f7263686173650000000000000000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f596f757220746f6b656e20616d6f756e742072656163686564206f7574206d6160008201527f7800000000000000000000000000000000000000000000000000000000000000602082015250565b7f53616c652073746174652073686f756c64206265207072697661746500000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4d617820737570706c7920726561636865640000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f73656e64657220616464726573732063616e6e6f74206d696e74206d6f72652060008201527f7468616e206d61784d696e7450657241646472657373206c616e647300000000602082015250565b7f43616e6e6f7420736574206d65726b6c6520726f6f7400000000000000000000600082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b7f596f7520617265206e6f7420696e207468652076616c69642077686974656c6960008201527f7374000000000000000000000000000000000000000000000000000000000000602082015250565b60038110614b5657614b55614681565b5b50565b614b6281614473565b8114614b6d57600080fd5b50565b614b7981614485565b8114614b8457600080fd5b50565b614b9081614491565b8114614b9b57600080fd5b50565b614ba78161449b565b8114614bb257600080fd5b50565b60038110614bc257600080fd5b50565b614bce816144fa565b8114614bd957600080fd5b5056fea264697066735822122077b8ce4a679b6d99ece6fe862f312a60f146f8bf241c6cd703e5e1a580ad330064736f6c63430008070033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d405f9908dec587a5ed77ea06760ea868f5de7c3
-----Decoded View---------------
Arg [0] : _tokenContract (address): 0xd405f9908dEC587a5ed77EA06760EA868f5De7c3
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000d405f9908dec587a5ed77ea06760ea868f5de7c3
Deployed Bytecode Sourcemap
100504:4046:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104366:181;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67003:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73494:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72927:408;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;62754:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77133:2825;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;38753:131;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100577:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39194:147;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;40338:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103159:402;;;;;;;;;;;;;:::i;:::-;;80054:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;100927:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104262:96;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103567:166;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;100842:45;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68396:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63938:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46880:103;;;;;;;;;;;;;:::i;:::-;;103739:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;46232:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43991:153;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37213:147;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67179:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36318:49;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74052:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;100962:52;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80845:407;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101977:680;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;100618:48;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67389:318;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44318:142;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101019:51;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39634:149;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;100671:44;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74443:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47138:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;102663:490;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103916:226;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101363:608;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;104366:181;104485:4;104505:36;104529:11;104505:23;:36::i;:::-;104498:43;;104366:181;;;:::o;67003:100::-;67057:13;67090:5;67083:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67003:100;:::o;73494:218::-;73570:7;73595:16;73603:7;73595;:16::i;:::-;73590:64;;73620:34;;;;;;;;;;;;;;73590:64;73674:15;:24;73690:7;73674:24;;;;;;;;;;;:30;;;;;;;;;;;;73667:37;;73494:218;;;:::o;72927:408::-;73016:13;73032:16;73040:7;73032;:16::i;:::-;73016:32;;73088:5;73065:28;;:19;:17;:19::i;:::-;:28;;;73061:175;;73113:44;73130:5;73137:19;:17;:19::i;:::-;73113:16;:44::i;:::-;73108:128;;73185:35;;;;;;;;;;;;;;73108:128;73061:175;73281:2;73248:15;:24;73264:7;73248:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;73319:7;73315:2;73299:28;;73308:5;73299:28;;;;;;;;;;;;73005:330;72927:408;;:::o;62754:323::-;62815:7;63043:15;:13;:15::i;:::-;63028:12;;63012:13;;:28;:46;63005:53;;62754:323;:::o;77133:2825::-;77275:27;77305;77324:7;77305:18;:27::i;:::-;77275:57;;77390:4;77349:45;;77365:19;77349:45;;;77345:86;;77403:28;;;;;;;;;;;;;;77345:86;77445:27;77474:23;77501:35;77528:7;77501:26;:35::i;:::-;77444:92;;;;77636:68;77661:15;77678:4;77684:19;:17;:19::i;:::-;77636:24;:68::i;:::-;77631:180;;77724:43;77741:4;77747:19;:17;:19::i;:::-;77724:16;:43::i;:::-;77719:92;;77776:35;;;;;;;;;;;;;;77719:92;77631:180;77842:1;77828:16;;:2;:16;;;77824:52;;;77853:23;;;;;;;;;;;;;;77824:52;77889:43;77911:4;77917:2;77921:7;77930:1;77889:21;:43::i;:::-;78025:15;78022:160;;;78165:1;78144:19;78137:30;78022:160;78562:18;:24;78581:4;78562:24;;;;;;;;;;;;;;;;78560:26;;;;;;;;;;;;78631:18;:22;78650:2;78631:22;;;;;;;;;;;;;;;;78629:24;;;;;;;;;;;78953:146;78990:2;79039:45;79054:4;79060:2;79064:19;79039:14;:45::i;:::-;59153:8;79011:73;78953:18;:146::i;:::-;78924:17;:26;78942:7;78924:26;;;;;;;;;;;:175;;;;79270:1;59153:8;79219:19;:47;:52;79215:627;;;79292:19;79324:1;79314:7;:11;79292:33;;79481:1;79447:17;:30;79465:11;79447:30;;;;;;;;;;;;:35;79443:384;;;79585:13;;79570:11;:28;79566:242;;79765:19;79732:17;:30;79750:11;79732:30;;;;;;;;;;;:52;;;;79566:242;79443:384;79273:569;79215:627;79889:7;79885:2;79870:27;;79879:4;79870:27;;;;;;;;;;;;79908:42;79929:4;79935:2;79939:7;79948:1;79908:20;:42::i;:::-;77264:2694;;;77133:2825;;;:::o;38753:131::-;38827:7;38854:6;:12;38861:4;38854:12;;;;;;;;;;;:22;;;38847:29;;38753:131;;;:::o;100577:36::-;;;;:::o;39194:147::-;39277:18;39290:4;39277:12;:18::i;:::-;36809:16;36820:4;36809:10;:16::i;:::-;39308:25:::1;39319:4;39325:7;39308:10;:25::i;:::-;39194:147:::0;;;:::o;40338:218::-;40445:12;:10;:12::i;:::-;40434:23;;:7;:23;;;40426:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;40522:26;40534:4;40540:7;40522:11;:26::i;:::-;40338:218;;:::o;103159:402::-;46118:13;:11;:13::i;:::-;103211:41:::1;36363:4;103219:18:::0;::::1;103239:12;:10;:12::i;:::-;103211:7;:41::i;:::-;103203:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;103281:15;103299:21;103281:39;;103340:1;103330:7;:11;103327:80;;;103359:7;:5;:7::i;:::-;103351:25;;:48;103377:21;103351:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;103327:80;103430:13;;;;;;;;;;;103423:31;;;103463:4;103423:46;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;103413:56;;103489:1;103479:7;:11;103476:80;;;103507:13;;;;;;;;;;;103500:30;;;103531:7;:5;:7::i;:::-;103540;103500:48;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;103476:80;103196:365;103159:402::o:0;80054:193::-;80200:39;80217:4;80223:2;80227:7;80200:39;;;;;;;;;;;;:16;:39::i;:::-;80054:193;;;:::o;100927:28::-;;;;;;;;;;;;;:::o;104262:96::-;46118:13;:11;:13::i;:::-;104345:7:::1;104329:13;:23;;;;;;;;;;;;:::i;:::-;;104262:96:::0;:::o;103567:166::-;103631:41;36363:4;103639:18;;103659:12;:10;:12::i;:::-;103631:7;:41::i;:::-;103623:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;103719:8;103707:9;;:20;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;103567:166;:::o;100842:45::-;;;;;;;;;;;;;:::o;68396:152::-;68468:7;68511:27;68530:7;68511:18;:27::i;:::-;68488:52;;68396:152;;;:::o;63938:233::-;64010:7;64051:1;64034:19;;:5;:19;;;64030:60;;;64062:28;;;;;;;;;;;;;;64030:60;58097:13;64108:18;:25;64127:5;64108:25;;;;;;;;;;;;;;;;:55;64101:62;;63938:233;;;:::o;46880:103::-;46118:13;:11;:13::i;:::-;46945:30:::1;46972:1;46945:18;:30::i;:::-;46880:103::o:0;103739:171::-;103805:41;36363:4;103813:18;;103833:12;:10;:12::i;:::-;103805:7;:41::i;:::-;103797:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;103893:11;103880:10;:24;;;;103739:171;:::o;46232:87::-;46278:7;46305:6;;;;;;;;;;;46298:13;;46232:87;:::o;43991:153::-;44081:7;44108:28;44130:5;44108:12;:18;44121:4;44108:18;;;;;;;;;;;:21;;:28;;;;:::i;:::-;44101:35;;43991:153;;;;:::o;37213:147::-;37299:4;37323:6;:12;37330:4;37323:12;;;;;;;;;;;:20;;:29;37344:7;37323:29;;;;;;;;;;;;;;;;;;;;;;;;;37316:36;;37213:147;;;;:::o;67179:104::-;67235:13;67268:7;67261:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67179:104;:::o;36318:49::-;36363:4;36318:49;;;:::o;74052:234::-;74199:8;74147:18;:39;74166:19;:17;:19::i;:::-;74147:39;;;;;;;;;;;;;;;:49;74187:8;74147:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;74259:8;74223:55;;74238:19;:17;:19::i;:::-;74223:55;;;74269:8;74223:55;;;;;;:::i;:::-;;;;;;;;74052:234;;:::o;100962:52::-;;;;;;;;;;;;;;;;;:::o;80845:407::-;81020:31;81033:4;81039:2;81043:7;81020:12;:31::i;:::-;81084:1;81066:2;:14;;;:19;81062:183;;81105:56;81136:4;81142:2;81146:7;81155:5;81105:30;:56::i;:::-;81100:145;;81189:40;;;;;;;;;;;;;;81100:145;81062:183;80845:407;;;;:::o;101977:680::-;102084:17;102071:30;;;;;;;;:::i;:::-;;:9;;;;;;;;;;;:30;;;;;;;;:::i;:::-;;;102062:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;102175:14;;102165:6;102149:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:40;;102141:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;102227:78;102246:5;;102227:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102253:10;;102292;102275:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;102265:39;;;;;;102227:18;:78::i;:::-;102219:125;;;;;;;;;;;;:::i;:::-;;;;;;;;;102396:15;;;;;;;;;;;102359:52;;102368:12;:24;102381:10;102368:24;;;;;;;;;;;;;;;;102359:6;:33;;;;:::i;:::-;:52;;102351:125;;;;;;;;;;;;:::i;:::-;;;;;;;;;102519:9;102500:15;;102491:6;:24;;;;:::i;:::-;:37;;102483:88;;;;;;;;;;;;:::i;:::-;;;;;;;;;102607:6;102578:13;:25;102592:10;102578:25;;;;;;;;;;;;;;;;:35;;;;;;;:::i;:::-;;;;;;;;102620:31;102630:12;:10;:12::i;:::-;102644:6;102620:9;:31::i;:::-;101977:680;;;:::o;100618:48::-;;;;:::o;67389:318::-;67462:13;67493:16;67501:7;67493;:16::i;:::-;67488:59;;67518:29;;;;;;;;;;;;;;67488:59;67560:21;67584:10;:8;:10::i;:::-;67560:34;;67637:1;67618:7;67612:21;:26;;:87;;;;;;;;;;;;;;;;;67665:7;67674:18;67684:7;67674:9;:18::i;:::-;67648:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;67612:87;67605:94;;;67389:318;;;:::o;44318:142::-;44398:7;44425:27;:12;:18;44438:4;44425:18;;;;;;;;;;;:25;:27::i;:::-;44418:34;;44318:142;;;:::o;101019:51::-;;;;;;;;;;;;;;;;;:::o;39634:149::-;39718:18;39731:4;39718:12;:18::i;:::-;36809:16;36820:4;36809:10;:16::i;:::-;39749:26:::1;39761:4;39767:7;39749:11;:26::i;:::-;39634:149:::0;;;:::o;100671:44::-;;;;:::o;74443:164::-;74540:4;74564:18;:25;74583:5;74564:25;;;;;;;;;;;;;;;:35;74590:8;74564:35;;;;;;;;;;;;;;;;;;;;;;;;;74557:42;;74443:164;;;;:::o;47138:201::-;46118:13;:11;:13::i;:::-;47247:1:::1;47227:22;;:8;:22;;;;47219:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;47303:28;47322:8;47303:18;:28::i;:::-;47138:201:::0;:::o;102663:490::-;102743:16;102730:29;;;;;;;;:::i;:::-;;:9;;;;;;;;;;;:29;;;;;;;;:::i;:::-;;;102721:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;102832:14;;102822:6;102806:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:40;;102798:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;102921:14;;;;;;;;;;;102884:51;;102893:12;:24;102906:10;102893:24;;;;;;;;;;;;;;;;102884:6;:33;;;;:::i;:::-;:51;;102876:97;;;;;;;;;;;;:::i;:::-;;;;;;;;;103016:9;102997:15;;102988:6;:24;;;;:::i;:::-;:37;;102980:88;;;;;;;;;;;;:::i;:::-;;;;;;;;;103103:6;103075:12;:24;103088:10;103075:24;;;;;;;;;;;;;;;;:34;;;;;;;:::i;:::-;;;;;;;;103116:31;103126:12;:10;:12::i;:::-;103140:6;103116:9;:31::i;:::-;102663:490;:::o;103916:226::-;46118:13;:11;:13::i;:::-;104031:9:::1;104027:110;104050:10;;:17;;104046:1;:21;104027:110;;;104120:6;;104127:1;104120:9;;;;;;;:::i;:::-;;;;;;;;104085:17;:32;104103:10;;104114:1;104103:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;104085:32;;;;;;;;;;;;;;;:44;;;;104069:3;;;;;:::i;:::-;;;;104027:110;;;;103916:226:::0;;;;:::o;101363:608::-;101437:17;101424:30;;;;;;;;:::i;:::-;;:9;;;;;;;;;;;:30;;;;;;;;:::i;:::-;;;101415:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;101528:14;;101518:6;101502:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:40;;101494:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;101612:1;101580:17;:29;101598:10;101580:29;;;;;;;;;;;;;;;;:33;101572:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;101694:17;:29;101712:10;101694:29;;;;;;;;;;;;;;;;101662:16;:28;101679:10;101662:28;;;;;;;;;;;;;;;;101653:6;:37;;;;:::i;:::-;:70;;101645:143;;;;;;;;;;;;:::i;:::-;;;;;;;;;101802:13;;;;;;;;;;;101795:34;;;101830:10;101850:4;101875:6;101857:15;;:24;;;;:::i;:::-;101795:87;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;101921:6;101889:16;:28;101906:10;101889:28;;;;;;;;;;;;;;;;:38;;;;;;;:::i;:::-;;;;;;;;101934:31;101944:12;:10;:12::i;:::-;101958:6;101934:9;:31::i;:::-;101363:608;:::o;41935:238::-;42019:22;42027:4;42033:7;42019;:22::i;:::-;42014:152;;42090:4;42058:6;:12;42065:4;42058:12;;;;;;;;;;;:20;;:29;42079:7;42058:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;42141:12;:10;:12::i;:::-;42114:40;;42132:7;42114:40;;42126:4;42114:40;;;;;;;;;;42014:152;41935:238;;:::o;8296:152::-;8366:4;8390:50;8395:3;:10;;8431:5;8415:23;;8407:32;;8390:4;:50::i;:::-;8383:57;;8296:152;;;;:::o;43178:214::-;43263:4;43302:42;43287:57;;;:11;:57;;;;:97;;;;43348:36;43372:11;43348:23;:36::i;:::-;43287:97;43280:104;;43178:214;;;:::o;74865:282::-;74930:4;74986:7;74967:15;:13;:15::i;:::-;:26;;:66;;;;;75020:13;;75010:7;:23;74967:66;:153;;;;;75119:1;58873:8;75071:17;:26;75089:7;75071:26;;;;;;;;;;;;:44;:49;74967:153;74947:173;;74865:282;;;:::o;97173:105::-;97233:7;97260:10;97253:17;;97173:105;:::o;62270:92::-;62326:7;62270:92;:::o;69551:1275::-;69618:7;69638:12;69653:7;69638:22;;69721:4;69702:15;:13;:15::i;:::-;:23;69698:1061;;69755:13;;69748:4;:20;69744:1015;;;69793:14;69810:17;:23;69828:4;69810:23;;;;;;;;;;;;69793:40;;69927:1;58873:8;69899:6;:24;:29;69895:845;;;70564:113;70581:1;70571:6;:11;70564:113;;;70624:17;:25;70642:6;;;;;;;70624:25;;;;;;;;;;;;70615:34;;70564:113;;;70710:6;70703:13;;;;;;69895:845;69770:989;69744:1015;69698:1061;70787:31;;;;;;;;;;;;;;69551:1275;;;;:::o;76028:485::-;76130:27;76159:23;76200:38;76241:15;:24;76257:7;76241:24;;;;;;;;;;;76200:65;;76418:18;76395:41;;76475:19;76469:26;76450:45;;76380:126;76028:485;;;:::o;75256:659::-;75405:11;75570:16;75563:5;75559:28;75550:37;;75730:16;75719:9;75715:32;75702:45;;75880:15;75869:9;75866:30;75858:5;75847:9;75844:20;75841:56;75831:66;;75256:659;;;;;:::o;81914:159::-;;;;;:::o;96482:311::-;96617:7;96637:16;59277:3;96663:19;:41;;96637:68;;59277:3;96731:31;96742:4;96748:2;96752:9;96731:10;:31::i;:::-;96723:40;;:62;;96716:69;;;96482:311;;;;;:::o;71374:450::-;71454:14;71622:16;71615:5;71611:28;71602:37;;71799:5;71785:11;71760:23;71756:41;71753:52;71746:5;71743:63;71733:73;;71374:450;;;;:::o;82738:158::-;;;;;:::o;37664:105::-;37731:30;37742:4;37748:12;:10;:12::i;:::-;37731:10;:30::i;:::-;37664:105;:::o;44553:169::-;44641:31;44658:4;44664:7;44641:16;:31::i;:::-;44683;44706:7;44683:12;:18;44696:4;44683:18;;;;;;;;;;;:22;;:31;;;;:::i;:::-;;44553:169;;:::o;34126:98::-;34179:7;34206:10;34199:17;;34126:98;:::o;44816:174::-;44905:32;44923:4;44929:7;44905:17;:32::i;:::-;44948:34;44974:7;44948:12;:18;44961:4;44948:18;;;;;;;;;;;:25;;:34;;;;:::i;:::-;;44816:174;;:::o;46397:132::-;46472:12;:10;:12::i;:::-;46461:23;;:7;:5;:7::i;:::-;:23;;;46453:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;46397:132::o;47499:191::-;47573:16;47592:6;;;;;;;;;;;47573:25;;47618:8;47609:6;;:17;;;;;;;;;;;;;;;;;;47673:8;47642:40;;47663:8;47642:40;;;;;;;;;;;;47562:128;47499:191;:::o;9592:158::-;9666:7;9717:22;9721:3;:10;;9733:5;9717:3;:22::i;:::-;9709:31;;9686:56;;9592:158;;;;:::o;83336:716::-;83499:4;83545:2;83520:45;;;83566:19;:17;:19::i;:::-;83587:4;83593:7;83602:5;83520:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;83516:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83820:1;83803:6;:13;:18;83799:235;;;83849:40;;;;;;;;;;;;;;83799:235;83992:6;83986:13;83977:6;83973:2;83969:15;83962:38;83516:529;83689:54;;;83679:64;;;:6;:64;;;;83672:71;;;83336:716;;;;;;:::o;23062:190::-;23187:4;23240;23211:25;23224:5;23231:4;23211:12;:25::i;:::-;:33;23204:40;;23062:190;;;;;:::o;91005:112::-;91082:27;91092:2;91096:8;91082:27;;;;;;;;;;;;:9;:27::i;:::-;91005:112;;:::o;104148:108::-;104208:13;104237;104230:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104148:108;:::o;97380:1745::-;97445:17;97879:4;97872;97866:11;97862:22;97971:1;97965:4;97958:15;98046:4;98043:1;98039:12;98032:19;;98128:1;98123:3;98116:14;98232:3;98471:5;98453:428;98479:1;98453:428;;;98519:1;98514:3;98510:11;98503:18;;98690:2;98684:4;98680:13;98676:2;98672:22;98667:3;98659:36;98784:2;98778:4;98774:13;98766:21;;98851:4;98841:25;;98859:5;;98841:25;98453:428;;;98457:21;98920:3;98915;98911:13;99035:4;99030:3;99026:14;99019:21;;99100:6;99095:3;99088:19;97484:1634;;;97380:1745;;;:::o;9121:117::-;9184:7;9211:19;9219:3;:10;;9211:7;:19::i;:::-;9204:26;;9121:117;;;:::o;2211:414::-;2274:4;2296:21;2306:3;2311:5;2296:9;:21::i;:::-;2291:327;;2334:3;:11;;2351:5;2334:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2517:3;:11;;:18;;;;2495:3;:12;;:19;2508:5;2495:19;;;;;;;;;;;:40;;;;2557:4;2550:11;;;;2291:327;2601:5;2594:12;;2211:414;;;;;:::o;36917:204::-;37002:4;37041:32;37026:47;;;:11;:47;;;;:87;;;;37077:36;37101:11;37077:23;:36::i;:::-;37026:87;37019:94;;36917:204;;;:::o;96183:147::-;96320:6;96183:147;;;;;:::o;38059:505::-;38148:22;38156:4;38162:7;38148;:22::i;:::-;38143:414;;38336:41;38364:7;38336:41;;38374:2;38336:19;:41::i;:::-;38450:38;38478:4;38470:13;;38485:2;38450:19;:38::i;:::-;38241:270;;;;;;;;;:::i;:::-;;;;;;;;;;;;;38187:358;;;;;;;;;;;:::i;:::-;;;;;;;;38143:414;38059:505;;:::o;42353:239::-;42437:22;42445:4;42451:7;42437;:22::i;:::-;42433:152;;;42508:5;42476:6;:12;42483:4;42476:12;;;;;;;;;;;:20;;:29;42497:7;42476:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;42560:12;:10;:12::i;:::-;42533:40;;42551:7;42533:40;;42545:4;42533:40;;;;;;;;;;42433:152;42353:239;;:::o;8624:158::-;8697:4;8721:53;8729:3;:10;;8765:5;8749:23;;8741:32;;8721:7;:53::i;:::-;8714:60;;8624:158;;;;:::o;4985:120::-;5052:7;5079:3;:11;;5091:5;5079:18;;;;;;;;:::i;:::-;;;;;;;;;;5072:25;;4985:120;;;;:::o;23929:296::-;24012:7;24032:20;24055:4;24032:27;;24075:9;24070:118;24094:5;:12;24090:1;:16;24070:118;;;24143:33;24153:12;24167:5;24173:1;24167:8;;;;;;;;:::i;:::-;;;;;;;;24143:9;:33::i;:::-;24128:48;;24108:3;;;;;:::i;:::-;;;;24070:118;;;;24205:12;24198:19;;;23929:296;;;;:::o;90232:689::-;90363:19;90369:2;90373:8;90363:5;:19::i;:::-;90442:1;90424:2;:14;;;:19;90420:483;;90464:11;90478:13;;90464:27;;90510:13;90532:8;90526:3;:14;90510:30;;90559:233;90590:62;90629:1;90633:2;90637:7;;;;;;90646:5;90590:30;:62::i;:::-;90585:167;;90688:40;;;;;;;;;;;;;;90585:167;90787:3;90779:5;:11;90559:233;;90874:3;90857:13;;:20;90853:34;;90879:8;;;90853:34;90445:458;;90420:483;90232:689;;;:::o;4522:109::-;4578:7;4605:3;:11;;:18;;;;4598:25;;4522:109;;;:::o;4307:129::-;4380:4;4427:1;4404:3;:12;;:19;4417:5;4404:19;;;;;;;;;;;;:24;;4397:31;;4307:129;;;;:::o;14871:157::-;14956:4;14995:25;14980:40;;;:11;:40;;;;14973:47;;14871:157;;;:::o;16766:451::-;16841:13;16867:19;16912:1;16903:6;16899:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;16889:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16867:47;;16925:15;:6;16932:1;16925:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;16951;:6;16958:1;16951:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;16982:9;17007:1;16998:6;16994:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;16982:26;;16977:135;17014:1;17010;:5;16977:135;;;17049:12;17070:3;17062:5;:11;17049:25;;;;;;;:::i;:::-;;;;;17037:6;17044:1;17037:9;;;;;;;;:::i;:::-;;;;;:37;;;;;;;;;;;17099:1;17089:11;;;;;17017:3;;;;:::i;:::-;;;16977:135;;;;17139:1;17130:5;:10;17122:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;17202:6;17188:21;;;16766:451;;;;:::o;2801:1420::-;2867:4;2985:18;3006:3;:12;;:19;3019:5;3006:19;;;;;;;;;;;;2985:40;;3056:1;3042:10;:15;3038:1176;;3417:21;3454:1;3441:10;:14;;;;:::i;:::-;3417:38;;3470:17;3511:1;3490:3;:11;;:18;;;;:22;;;;:::i;:::-;3470:42;;3546:13;3533:9;:26;3529:405;;3580:17;3600:3;:11;;3612:9;3600:22;;;;;;;;:::i;:::-;;;;;;;;;;3580:42;;3754:9;3725:3;:11;;3737:13;3725:26;;;;;;;;:::i;:::-;;;;;;;;;:38;;;;3865:10;3839:3;:12;;:23;3852:9;3839:23;;;;;;;;;;;:36;;;;3561:373;3529:405;4015:3;:11;;:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;4110:3;:12;;:19;4123:5;4110:19;;;;;;;;;;;4103:26;;;4153:4;4146:11;;;;;;;3038:1176;4197:5;4190:12;;;2801:1420;;;;;:::o;30136:149::-;30199:7;30230:1;30226;:5;:51;;30257:20;30272:1;30275;30257:14;:20::i;:::-;30226:51;;;30234:20;30249:1;30252;30234:14;:20::i;:::-;30226:51;30219:58;;30136:149;;;;:::o;84514:2966::-;84587:20;84610:13;;84587:36;;84650:1;84638:8;:13;84634:44;;;84660:18;;;;;;;;;;;;;;84634:44;84691:61;84721:1;84725:2;84729:12;84743:8;84691:21;:61::i;:::-;85235:1;58235:2;85205:1;:26;;85204:32;85192:8;:45;85166:18;:22;85185:2;85166:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;85514:139;85551:2;85605:33;85628:1;85632:2;85636:1;85605:14;:33::i;:::-;85572:30;85593:8;85572:20;:30::i;:::-;:66;85514:18;:139::i;:::-;85480:17;:31;85498:12;85480:31;;;;;;;;;;;:173;;;;85670:16;85701:11;85730:8;85715:12;:23;85701:37;;86251:16;86247:2;86243:25;86231:37;;86623:12;86583:8;86542:1;86480:25;86421:1;86360;86333:335;86994:1;86980:12;86976:20;86934:346;87035:3;87026:7;87023:16;86934:346;;87253:7;87243:8;87240:1;87213:25;87210:1;87207;87202:59;87088:1;87079:7;87075:15;87064:26;;86934:346;;;86938:77;87325:1;87313:8;:13;87309:45;;;87335:19;;;;;;;;;;;;;;87309:45;87387:3;87371:13;:19;;;;84940:2462;;87412:60;87441:1;87445:2;87449:12;87463:8;87412:20;:60::i;:::-;84576:2904;84514:2966;;:::o;30293:268::-;30361:13;30468:1;30462:4;30455:15;30497:1;30491:4;30484:15;30538:4;30532;30522:21;30513:30;;30293:268;;;;:::o;71926:324::-;71996:14;72229:1;72219:8;72216:15;72190:24;72186:46;72176:56;;71926:324;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:410:1:-;84:5;109:65;125:48;166:6;125:48;:::i;:::-;109:65;:::i;:::-;100:74;;197:6;190:5;183:21;235:4;228:5;224:16;273:3;264:6;259:3;255:16;252:25;249:112;;;280:79;;:::i;:::-;249:112;370:41;404:6;399:3;394;370:41;:::i;:::-;90:327;7:410;;;;;:::o;423:412::-;501:5;526:66;542:49;584:6;542:49;:::i;:::-;526:66;:::i;:::-;517:75;;615:6;608:5;601:21;653:4;646:5;642:16;691:3;682:6;677:3;673:16;670:25;667:112;;;698:79;;:::i;:::-;667:112;788:41;822:6;817:3;812;788:41;:::i;:::-;507:328;423:412;;;;;:::o;841:139::-;887:5;925:6;912:20;903:29;;941:33;968:5;941:33;:::i;:::-;841:139;;;;:::o;1003:568::-;1076:8;1086:6;1136:3;1129:4;1121:6;1117:17;1113:27;1103:122;;1144:79;;:::i;:::-;1103:122;1257:6;1244:20;1234:30;;1287:18;1279:6;1276:30;1273:117;;;1309:79;;:::i;:::-;1273:117;1423:4;1415:6;1411:17;1399:29;;1477:3;1469:4;1461:6;1457:17;1447:8;1443:32;1440:41;1437:128;;;1484:79;;:::i;:::-;1437:128;1003:568;;;;;:::o;1594:::-;1667:8;1677:6;1727:3;1720:4;1712:6;1708:17;1704:27;1694:122;;1735:79;;:::i;:::-;1694:122;1848:6;1835:20;1825:30;;1878:18;1870:6;1867:30;1864:117;;;1900:79;;:::i;:::-;1864:117;2014:4;2006:6;2002:17;1990:29;;2068:3;2060:4;2052:6;2048:17;2038:8;2034:32;2031:41;2028:128;;;2075:79;;:::i;:::-;2028:128;1594:568;;;;;:::o;2185:::-;2258:8;2268:6;2318:3;2311:4;2303:6;2299:17;2295:27;2285:122;;2326:79;;:::i;:::-;2285:122;2439:6;2426:20;2416:30;;2469:18;2461:6;2458:30;2455:117;;;2491:79;;:::i;:::-;2455:117;2605:4;2597:6;2593:17;2581:29;;2659:3;2651:4;2643:6;2639:17;2629:8;2625:32;2622:41;2619:128;;;2666:79;;:::i;:::-;2619:128;2185:568;;;;;:::o;2759:133::-;2802:5;2840:6;2827:20;2818:29;;2856:30;2880:5;2856:30;:::i;:::-;2759:133;;;;:::o;2898:137::-;2952:5;2983:6;2977:13;2968:22;;2999:30;3023:5;2999:30;:::i;:::-;2898:137;;;;:::o;3041:139::-;3087:5;3125:6;3112:20;3103:29;;3141:33;3168:5;3141:33;:::i;:::-;3041:139;;;;:::o;3186:137::-;3231:5;3269:6;3256:20;3247:29;;3285:32;3311:5;3285:32;:::i;:::-;3186:137;;;;:::o;3329:141::-;3385:5;3416:6;3410:13;3401:22;;3432:32;3458:5;3432:32;:::i;:::-;3329:141;;;;:::o;3489:338::-;3544:5;3593:3;3586:4;3578:6;3574:17;3570:27;3560:122;;3601:79;;:::i;:::-;3560:122;3718:6;3705:20;3743:78;3817:3;3809:6;3802:4;3794:6;3790:17;3743:78;:::i;:::-;3734:87;;3550:277;3489:338;;;;:::o;3833:167::-;3893:5;3931:6;3918:20;3909:29;;3947:47;3988:5;3947:47;:::i;:::-;3833:167;;;;:::o;4020:340::-;4076:5;4125:3;4118:4;4110:6;4106:17;4102:27;4092:122;;4133:79;;:::i;:::-;4092:122;4250:6;4237:20;4275:79;4350:3;4342:6;4335:4;4327:6;4323:17;4275:79;:::i;:::-;4266:88;;4082:278;4020:340;;;;:::o;4366:139::-;4412:5;4450:6;4437:20;4428:29;;4466:33;4493:5;4466:33;:::i;:::-;4366:139;;;;:::o;4511:143::-;4568:5;4599:6;4593:13;4584:22;;4615:33;4642:5;4615:33;:::i;:::-;4511:143;;;;:::o;4660:329::-;4719:6;4768:2;4756:9;4747:7;4743:23;4739:32;4736:119;;;4774:79;;:::i;:::-;4736:119;4894:1;4919:53;4964:7;4955:6;4944:9;4940:22;4919:53;:::i;:::-;4909:63;;4865:117;4660:329;;;;:::o;4995:474::-;5063:6;5071;5120:2;5108:9;5099:7;5095:23;5091:32;5088:119;;;5126:79;;:::i;:::-;5088:119;5246:1;5271:53;5316:7;5307:6;5296:9;5292:22;5271:53;:::i;:::-;5261:63;;5217:117;5373:2;5399:53;5444:7;5435:6;5424:9;5420:22;5399:53;:::i;:::-;5389:63;;5344:118;4995:474;;;;;:::o;5475:619::-;5552:6;5560;5568;5617:2;5605:9;5596:7;5592:23;5588:32;5585:119;;;5623:79;;:::i;:::-;5585:119;5743:1;5768:53;5813:7;5804:6;5793:9;5789:22;5768:53;:::i;:::-;5758:63;;5714:117;5870:2;5896:53;5941:7;5932:6;5921:9;5917:22;5896:53;:::i;:::-;5886:63;;5841:118;5998:2;6024:53;6069:7;6060:6;6049:9;6045:22;6024:53;:::i;:::-;6014:63;;5969:118;5475:619;;;;;:::o;6100:943::-;6195:6;6203;6211;6219;6268:3;6256:9;6247:7;6243:23;6239:33;6236:120;;;6275:79;;:::i;:::-;6236:120;6395:1;6420:53;6465:7;6456:6;6445:9;6441:22;6420:53;:::i;:::-;6410:63;;6366:117;6522:2;6548:53;6593:7;6584:6;6573:9;6569:22;6548:53;:::i;:::-;6538:63;;6493:118;6650:2;6676:53;6721:7;6712:6;6701:9;6697:22;6676:53;:::i;:::-;6666:63;;6621:118;6806:2;6795:9;6791:18;6778:32;6837:18;6829:6;6826:30;6823:117;;;6859:79;;:::i;:::-;6823:117;6964:62;7018:7;7009:6;6998:9;6994:22;6964:62;:::i;:::-;6954:72;;6749:287;6100:943;;;;;;;:::o;7049:468::-;7114:6;7122;7171:2;7159:9;7150:7;7146:23;7142:32;7139:119;;;7177:79;;:::i;:::-;7139:119;7297:1;7322:53;7367:7;7358:6;7347:9;7343:22;7322:53;:::i;:::-;7312:63;;7268:117;7424:2;7450:50;7492:7;7483:6;7472:9;7468:22;7450:50;:::i;:::-;7440:60;;7395:115;7049:468;;;;;:::o;7523:474::-;7591:6;7599;7648:2;7636:9;7627:7;7623:23;7619:32;7616:119;;;7654:79;;:::i;:::-;7616:119;7774:1;7799:53;7844:7;7835:6;7824:9;7820:22;7799:53;:::i;:::-;7789:63;;7745:117;7901:2;7927:53;7972:7;7963:6;7952:9;7948:22;7927:53;:::i;:::-;7917:63;;7872:118;7523:474;;;;;:::o;8003:934::-;8125:6;8133;8141;8149;8198:2;8186:9;8177:7;8173:23;8169:32;8166:119;;;8204:79;;:::i;:::-;8166:119;8352:1;8341:9;8337:17;8324:31;8382:18;8374:6;8371:30;8368:117;;;8404:79;;:::i;:::-;8368:117;8517:80;8589:7;8580:6;8569:9;8565:22;8517:80;:::i;:::-;8499:98;;;;8295:312;8674:2;8663:9;8659:18;8646:32;8705:18;8697:6;8694:30;8691:117;;;8727:79;;:::i;:::-;8691:117;8840:80;8912:7;8903:6;8892:9;8888:22;8840:80;:::i;:::-;8822:98;;;;8617:313;8003:934;;;;;;;:::o;8943:345::-;9010:6;9059:2;9047:9;9038:7;9034:23;9030:32;9027:119;;;9065:79;;:::i;:::-;9027:119;9185:1;9210:61;9263:7;9254:6;9243:9;9239:22;9210:61;:::i;:::-;9200:71;;9156:125;8943:345;;;;:::o;9294:329::-;9353:6;9402:2;9390:9;9381:7;9377:23;9373:32;9370:119;;;9408:79;;:::i;:::-;9370:119;9528:1;9553:53;9598:7;9589:6;9578:9;9574:22;9553:53;:::i;:::-;9543:63;;9499:117;9294:329;;;;:::o;9629:474::-;9697:6;9705;9754:2;9742:9;9733:7;9729:23;9725:32;9722:119;;;9760:79;;:::i;:::-;9722:119;9880:1;9905:53;9950:7;9941:6;9930:9;9926:22;9905:53;:::i;:::-;9895:63;;9851:117;10007:2;10033:53;10078:7;10069:6;10058:9;10054:22;10033:53;:::i;:::-;10023:63;;9978:118;9629:474;;;;;:::o;10109:::-;10177:6;10185;10234:2;10222:9;10213:7;10209:23;10205:32;10202:119;;;10240:79;;:::i;:::-;10202:119;10360:1;10385:53;10430:7;10421:6;10410:9;10406:22;10385:53;:::i;:::-;10375:63;;10331:117;10487:2;10513:53;10558:7;10549:6;10538:9;10534:22;10513:53;:::i;:::-;10503:63;;10458:118;10109:474;;;;;:::o;10589:327::-;10647:6;10696:2;10684:9;10675:7;10671:23;10667:32;10664:119;;;10702:79;;:::i;:::-;10664:119;10822:1;10847:52;10891:7;10882:6;10871:9;10867:22;10847:52;:::i;:::-;10837:62;;10793:116;10589:327;;;;:::o;10922:349::-;10991:6;11040:2;11028:9;11019:7;11015:23;11011:32;11008:119;;;11046:79;;:::i;:::-;11008:119;11166:1;11191:63;11246:7;11237:6;11226:9;11222:22;11191:63;:::i;:::-;11181:73;;11137:127;10922:349;;;;:::o;11277:357::-;11350:6;11399:2;11387:9;11378:7;11374:23;11370:32;11367:119;;;11405:79;;:::i;:::-;11367:119;11525:1;11550:67;11609:7;11600:6;11589:9;11585:22;11550:67;:::i;:::-;11540:77;;11496:131;11277:357;;;;:::o;11640:509::-;11709:6;11758:2;11746:9;11737:7;11733:23;11729:32;11726:119;;;11764:79;;:::i;:::-;11726:119;11912:1;11901:9;11897:17;11884:31;11942:18;11934:6;11931:30;11928:117;;;11964:79;;:::i;:::-;11928:117;12069:63;12124:7;12115:6;12104:9;12100:22;12069:63;:::i;:::-;12059:73;;11855:287;11640:509;;;;:::o;12155:329::-;12214:6;12263:2;12251:9;12242:7;12238:23;12234:32;12231:119;;;12269:79;;:::i;:::-;12231:119;12389:1;12414:53;12459:7;12450:6;12439:9;12435:22;12414:53;:::i;:::-;12404:63;;12360:117;12155:329;;;;:::o;12490:351::-;12560:6;12609:2;12597:9;12588:7;12584:23;12580:32;12577:119;;;12615:79;;:::i;:::-;12577:119;12735:1;12760:64;12816:7;12807:6;12796:9;12792:22;12760:64;:::i;:::-;12750:74;;12706:128;12490:351;;;;:::o;12847:704::-;12942:6;12950;12958;13007:2;12995:9;12986:7;12982:23;12978:32;12975:119;;;13013:79;;:::i;:::-;12975:119;13133:1;13158:53;13203:7;13194:6;13183:9;13179:22;13158:53;:::i;:::-;13148:63;;13104:117;13288:2;13277:9;13273:18;13260:32;13319:18;13311:6;13308:30;13305:117;;;13341:79;;:::i;:::-;13305:117;13454:80;13526:7;13517:6;13506:9;13502:22;13454:80;:::i;:::-;13436:98;;;;13231:313;12847:704;;;;;:::o;13557:118::-;13644:24;13662:5;13644:24;:::i;:::-;13639:3;13632:37;13557:118;;:::o;13681:157::-;13786:45;13806:24;13824:5;13806:24;:::i;:::-;13786:45;:::i;:::-;13781:3;13774:58;13681:157;;:::o;13844:109::-;13925:21;13940:5;13925:21;:::i;:::-;13920:3;13913:34;13844:109;;:::o;13959:118::-;14046:24;14064:5;14046:24;:::i;:::-;14041:3;14034:37;13959:118;;:::o;14083:360::-;14169:3;14197:38;14229:5;14197:38;:::i;:::-;14251:70;14314:6;14309:3;14251:70;:::i;:::-;14244:77;;14330:52;14375:6;14370:3;14363:4;14356:5;14352:16;14330:52;:::i;:::-;14407:29;14429:6;14407:29;:::i;:::-;14402:3;14398:39;14391:46;;14173:270;14083:360;;;;:::o;14449:155::-;14548:49;14591:5;14548:49;:::i;:::-;14543:3;14536:62;14449:155;;:::o;14610:364::-;14698:3;14726:39;14759:5;14726:39;:::i;:::-;14781:71;14845:6;14840:3;14781:71;:::i;:::-;14774:78;;14861:52;14906:6;14901:3;14894:4;14887:5;14883:16;14861:52;:::i;:::-;14938:29;14960:6;14938:29;:::i;:::-;14933:3;14929:39;14922:46;;14702:272;14610:364;;;;:::o;14980:377::-;15086:3;15114:39;15147:5;15114:39;:::i;:::-;15169:89;15251:6;15246:3;15169:89;:::i;:::-;15162:96;;15267:52;15312:6;15307:3;15300:4;15293:5;15289:16;15267:52;:::i;:::-;15344:6;15339:3;15335:16;15328:23;;15090:267;14980:377;;;;:::o;15363:366::-;15505:3;15526:67;15590:2;15585:3;15526:67;:::i;:::-;15519:74;;15602:93;15691:3;15602:93;:::i;:::-;15720:2;15715:3;15711:12;15704:19;;15363:366;;;:::o;15735:::-;15877:3;15898:67;15962:2;15957:3;15898:67;:::i;:::-;15891:74;;15974:93;16063:3;15974:93;:::i;:::-;16092:2;16087:3;16083:12;16076:19;;15735:366;;;:::o;16107:::-;16249:3;16270:67;16334:2;16329:3;16270:67;:::i;:::-;16263:74;;16346:93;16435:3;16346:93;:::i;:::-;16464:2;16459:3;16455:12;16448:19;;16107:366;;;:::o;16479:::-;16621:3;16642:67;16706:2;16701:3;16642:67;:::i;:::-;16635:74;;16718:93;16807:3;16718:93;:::i;:::-;16836:2;16831:3;16827:12;16820:19;;16479:366;;;:::o;16851:::-;16993:3;17014:67;17078:2;17073:3;17014:67;:::i;:::-;17007:74;;17090:93;17179:3;17090:93;:::i;:::-;17208:2;17203:3;17199:12;17192:19;;16851:366;;;:::o;17223:::-;17365:3;17386:67;17450:2;17445:3;17386:67;:::i;:::-;17379:74;;17462:93;17551:3;17462:93;:::i;:::-;17580:2;17575:3;17571:12;17564:19;;17223:366;;;:::o;17595:::-;17737:3;17758:67;17822:2;17817:3;17758:67;:::i;:::-;17751:74;;17834:93;17923:3;17834:93;:::i;:::-;17952:2;17947:3;17943:12;17936:19;;17595:366;;;:::o;17967:::-;18109:3;18130:67;18194:2;18189:3;18130:67;:::i;:::-;18123:74;;18206:93;18295:3;18206:93;:::i;:::-;18324:2;18319:3;18315:12;18308:19;;17967:366;;;:::o;18339:::-;18481:3;18502:67;18566:2;18561:3;18502:67;:::i;:::-;18495:74;;18578:93;18667:3;18578:93;:::i;:::-;18696:2;18691:3;18687:12;18680:19;;18339:366;;;:::o;18711:::-;18853:3;18874:67;18938:2;18933:3;18874:67;:::i;:::-;18867:74;;18950:93;19039:3;18950:93;:::i;:::-;19068:2;19063:3;19059:12;19052:19;;18711:366;;;:::o;19083:::-;19225:3;19246:67;19310:2;19305:3;19246:67;:::i;:::-;19239:74;;19322:93;19411:3;19322:93;:::i;:::-;19440:2;19435:3;19431:12;19424:19;;19083:366;;;:::o;19455:402::-;19615:3;19636:85;19718:2;19713:3;19636:85;:::i;:::-;19629:92;;19730:93;19819:3;19730:93;:::i;:::-;19848:2;19843:3;19839:12;19832:19;;19455:402;;;:::o;19863:366::-;20005:3;20026:67;20090:2;20085:3;20026:67;:::i;:::-;20019:74;;20102:93;20191:3;20102:93;:::i;:::-;20220:2;20215:3;20211:12;20204:19;;19863:366;;;:::o;20235:::-;20377:3;20398:67;20462:2;20457:3;20398:67;:::i;:::-;20391:74;;20474:93;20563:3;20474:93;:::i;:::-;20592:2;20587:3;20583:12;20576:19;;20235:366;;;:::o;20607:402::-;20767:3;20788:85;20870:2;20865:3;20788:85;:::i;:::-;20781:92;;20882:93;20971:3;20882:93;:::i;:::-;21000:2;20995:3;20991:12;20984:19;;20607:402;;;:::o;21015:366::-;21157:3;21178:67;21242:2;21237:3;21178:67;:::i;:::-;21171:74;;21254:93;21343:3;21254:93;:::i;:::-;21372:2;21367:3;21363:12;21356:19;;21015:366;;;:::o;21387:::-;21529:3;21550:67;21614:2;21609:3;21550:67;:::i;:::-;21543:74;;21626:93;21715:3;21626:93;:::i;:::-;21744:2;21739:3;21735:12;21728:19;;21387:366;;;:::o;21759:118::-;21846:24;21864:5;21846:24;:::i;:::-;21841:3;21834:37;21759:118;;:::o;21883:256::-;21995:3;22010:75;22081:3;22072:6;22010:75;:::i;:::-;22110:2;22105:3;22101:12;22094:19;;22130:3;22123:10;;21883:256;;;;:::o;22145:435::-;22325:3;22347:95;22438:3;22429:6;22347:95;:::i;:::-;22340:102;;22459:95;22550:3;22541:6;22459:95;:::i;:::-;22452:102;;22571:3;22564:10;;22145:435;;;;;:::o;22586:967::-;22968:3;22990:148;23134:3;22990:148;:::i;:::-;22983:155;;23155:95;23246:3;23237:6;23155:95;:::i;:::-;23148:102;;23267:148;23411:3;23267:148;:::i;:::-;23260:155;;23432:95;23523:3;23514:6;23432:95;:::i;:::-;23425:102;;23544:3;23537:10;;22586:967;;;;;:::o;23559:222::-;23652:4;23690:2;23679:9;23675:18;23667:26;;23703:71;23771:1;23760:9;23756:17;23747:6;23703:71;:::i;:::-;23559:222;;;;:::o;23787:442::-;23936:4;23974:2;23963:9;23959:18;23951:26;;23987:71;24055:1;24044:9;24040:17;24031:6;23987:71;:::i;:::-;24068:72;24136:2;24125:9;24121:18;24112:6;24068:72;:::i;:::-;24150;24218:2;24207:9;24203:18;24194:6;24150:72;:::i;:::-;23787:442;;;;;;:::o;24235:640::-;24430:4;24468:3;24457:9;24453:19;24445:27;;24482:71;24550:1;24539:9;24535:17;24526:6;24482:71;:::i;:::-;24563:72;24631:2;24620:9;24616:18;24607:6;24563:72;:::i;:::-;24645;24713:2;24702:9;24698:18;24689:6;24645:72;:::i;:::-;24764:9;24758:4;24754:20;24749:2;24738:9;24734:18;24727:48;24792:76;24863:4;24854:6;24792:76;:::i;:::-;24784:84;;24235:640;;;;;;;:::o;24881:332::-;25002:4;25040:2;25029:9;25025:18;25017:26;;25053:71;25121:1;25110:9;25106:17;25097:6;25053:71;:::i;:::-;25134:72;25202:2;25191:9;25187:18;25178:6;25134:72;:::i;:::-;24881:332;;;;;:::o;25219:210::-;25306:4;25344:2;25333:9;25329:18;25321:26;;25357:65;25419:1;25408:9;25404:17;25395:6;25357:65;:::i;:::-;25219:210;;;;:::o;25435:222::-;25528:4;25566:2;25555:9;25551:18;25543:26;;25579:71;25647:1;25636:9;25632:17;25623:6;25579:71;:::i;:::-;25435:222;;;;:::o;25663:246::-;25768:4;25806:2;25795:9;25791:18;25783:26;;25819:83;25899:1;25888:9;25884:17;25875:6;25819:83;:::i;:::-;25663:246;;;;:::o;25915:313::-;26028:4;26066:2;26055:9;26051:18;26043:26;;26115:9;26109:4;26105:20;26101:1;26090:9;26086:17;26079:47;26143:78;26216:4;26207:6;26143:78;:::i;:::-;26135:86;;25915:313;;;;:::o;26234:419::-;26400:4;26438:2;26427:9;26423:18;26415:26;;26487:9;26481:4;26477:20;26473:1;26462:9;26458:17;26451:47;26515:131;26641:4;26515:131;:::i;:::-;26507:139;;26234:419;;;:::o;26659:::-;26825:4;26863:2;26852:9;26848:18;26840:26;;26912:9;26906:4;26902:20;26898:1;26887:9;26883:17;26876:47;26940:131;27066:4;26940:131;:::i;:::-;26932:139;;26659:419;;;:::o;27084:::-;27250:4;27288:2;27277:9;27273:18;27265:26;;27337:9;27331:4;27327:20;27323:1;27312:9;27308:17;27301:47;27365:131;27491:4;27365:131;:::i;:::-;27357:139;;27084:419;;;:::o;27509:::-;27675:4;27713:2;27702:9;27698:18;27690:26;;27762:9;27756:4;27752:20;27748:1;27737:9;27733:17;27726:47;27790:131;27916:4;27790:131;:::i;:::-;27782:139;;27509:419;;;:::o;27934:::-;28100:4;28138:2;28127:9;28123:18;28115:26;;28187:9;28181:4;28177:20;28173:1;28162:9;28158:17;28151:47;28215:131;28341:4;28215:131;:::i;:::-;28207:139;;27934:419;;;:::o;28359:::-;28525:4;28563:2;28552:9;28548:18;28540:26;;28612:9;28606:4;28602:20;28598:1;28587:9;28583:17;28576:47;28640:131;28766:4;28640:131;:::i;:::-;28632:139;;28359:419;;;:::o;28784:::-;28950:4;28988:2;28977:9;28973:18;28965:26;;29037:9;29031:4;29027:20;29023:1;29012:9;29008:17;29001:47;29065:131;29191:4;29065:131;:::i;:::-;29057:139;;28784:419;;;:::o;29209:::-;29375:4;29413:2;29402:9;29398:18;29390:26;;29462:9;29456:4;29452:20;29448:1;29437:9;29433:17;29426:47;29490:131;29616:4;29490:131;:::i;:::-;29482:139;;29209:419;;;:::o;29634:::-;29800:4;29838:2;29827:9;29823:18;29815:26;;29887:9;29881:4;29877:20;29873:1;29862:9;29858:17;29851:47;29915:131;30041:4;29915:131;:::i;:::-;29907:139;;29634:419;;;:::o;30059:::-;30225:4;30263:2;30252:9;30248:18;30240:26;;30312:9;30306:4;30302:20;30298:1;30287:9;30283:17;30276:47;30340:131;30466:4;30340:131;:::i;:::-;30332:139;;30059:419;;;:::o;30484:::-;30650:4;30688:2;30677:9;30673:18;30665:26;;30737:9;30731:4;30727:20;30723:1;30712:9;30708:17;30701:47;30765:131;30891:4;30765:131;:::i;:::-;30757:139;;30484:419;;;:::o;30909:::-;31075:4;31113:2;31102:9;31098:18;31090:26;;31162:9;31156:4;31152:20;31148:1;31137:9;31133:17;31126:47;31190:131;31316:4;31190:131;:::i;:::-;31182:139;;30909:419;;;:::o;31334:::-;31500:4;31538:2;31527:9;31523:18;31515:26;;31587:9;31581:4;31577:20;31573:1;31562:9;31558:17;31551:47;31615:131;31741:4;31615:131;:::i;:::-;31607:139;;31334:419;;;:::o;31759:::-;31925:4;31963:2;31952:9;31948:18;31940:26;;32012:9;32006:4;32002:20;31998:1;31987:9;31983:17;31976:47;32040:131;32166:4;32040:131;:::i;:::-;32032:139;;31759:419;;;:::o;32184:::-;32350:4;32388:2;32377:9;32373:18;32365:26;;32437:9;32431:4;32427:20;32423:1;32412:9;32408:17;32401:47;32465:131;32591:4;32465:131;:::i;:::-;32457:139;;32184:419;;;:::o;32609:222::-;32702:4;32740:2;32729:9;32725:18;32717:26;;32753:71;32821:1;32810:9;32806:17;32797:6;32753:71;:::i;:::-;32609:222;;;;:::o;32837:129::-;32871:6;32898:20;;:::i;:::-;32888:30;;32927:33;32955:4;32947:6;32927:33;:::i;:::-;32837:129;;;:::o;32972:75::-;33005:6;33038:2;33032:9;33022:19;;32972:75;:::o;33053:307::-;33114:4;33204:18;33196:6;33193:30;33190:56;;;33226:18;;:::i;:::-;33190:56;33264:29;33286:6;33264:29;:::i;:::-;33256:37;;33348:4;33342;33338:15;33330:23;;33053:307;;;:::o;33366:308::-;33428:4;33518:18;33510:6;33507:30;33504:56;;;33540:18;;:::i;:::-;33504:56;33578:29;33600:6;33578:29;:::i;:::-;33570:37;;33662:4;33656;33652:15;33644:23;;33366:308;;;:::o;33680:98::-;33731:6;33765:5;33759:12;33749:22;;33680:98;;;:::o;33784:99::-;33836:6;33870:5;33864:12;33854:22;;33784:99;;;:::o;33889:168::-;33972:11;34006:6;34001:3;33994:19;34046:4;34041:3;34037:14;34022:29;;33889:168;;;;:::o;34063:169::-;34147:11;34181:6;34176:3;34169:19;34221:4;34216:3;34212:14;34197:29;;34063:169;;;;:::o;34238:148::-;34340:11;34377:3;34362:18;;34238:148;;;;:::o;34392:305::-;34432:3;34451:20;34469:1;34451:20;:::i;:::-;34446:25;;34485:20;34503:1;34485:20;:::i;:::-;34480:25;;34639:1;34571:66;34567:74;34564:1;34561:81;34558:107;;;34645:18;;:::i;:::-;34558:107;34689:1;34686;34682:9;34675:16;;34392:305;;;;:::o;34703:348::-;34743:7;34766:20;34784:1;34766:20;:::i;:::-;34761:25;;34800:20;34818:1;34800:20;:::i;:::-;34795:25;;34988:1;34920:66;34916:74;34913:1;34910:81;34905:1;34898:9;34891:17;34887:105;34884:131;;;34995:18;;:::i;:::-;34884:131;35043:1;35040;35036:9;35025:20;;34703:348;;;;:::o;35057:191::-;35097:4;35117:20;35135:1;35117:20;:::i;:::-;35112:25;;35151:20;35169:1;35151:20;:::i;:::-;35146:25;;35190:1;35187;35184:8;35181:34;;;35195:18;;:::i;:::-;35181:34;35240:1;35237;35233:9;35225:17;;35057:191;;;;:::o;35254:96::-;35291:7;35320:24;35338:5;35320:24;:::i;:::-;35309:35;;35254:96;;;:::o;35356:90::-;35390:7;35433:5;35426:13;35419:21;35408:32;;35356:90;;;:::o;35452:77::-;35489:7;35518:5;35507:16;;35452:77;;;:::o;35535:149::-;35571:7;35611:66;35604:5;35600:78;35589:89;;35535:149;;;:::o;35690:139::-;35741:7;35770:5;35759:16;;35776:47;35817:5;35776:47;:::i;:::-;35690:139;;;:::o;35835:126::-;35872:7;35912:42;35905:5;35901:54;35890:65;;35835:126;;;:::o;35967:77::-;36004:7;36033:5;36022:16;;35967:77;;;:::o;36050:139::-;36112:9;36145:38;36177:5;36145:38;:::i;:::-;36132:51;;36050:139;;;:::o;36195:154::-;36279:6;36274:3;36269;36256:30;36341:1;36332:6;36327:3;36323:16;36316:27;36195:154;;;:::o;36355:307::-;36423:1;36433:113;36447:6;36444:1;36441:13;36433:113;;;36532:1;36527:3;36523:11;36517:18;36513:1;36508:3;36504:11;36497:39;36469:2;36466:1;36462:10;36457:15;;36433:113;;;36564:6;36561:1;36558:13;36555:101;;;36644:1;36635:6;36630:3;36626:16;36619:27;36555:101;36404:258;36355:307;;;:::o;36668:171::-;36707:3;36730:24;36748:5;36730:24;:::i;:::-;36721:33;;36776:4;36769:5;36766:15;36763:41;;;36784:18;;:::i;:::-;36763:41;36831:1;36824:5;36820:13;36813:20;;36668:171;;;:::o;36845:320::-;36889:6;36926:1;36920:4;36916:12;36906:22;;36973:1;36967:4;36963:12;36994:18;36984:81;;37050:4;37042:6;37038:17;37028:27;;36984:81;37112:2;37104:6;37101:14;37081:18;37078:38;37075:84;;;37131:18;;:::i;:::-;37075:84;36896:269;36845:320;;;:::o;37171:281::-;37254:27;37276:4;37254:27;:::i;:::-;37246:6;37242:40;37384:6;37372:10;37369:22;37348:18;37336:10;37333:34;37330:62;37327:88;;;37395:18;;:::i;:::-;37327:88;37435:10;37431:2;37424:22;37214:238;37171:281;;:::o;37458:233::-;37497:3;37520:24;37538:5;37520:24;:::i;:::-;37511:33;;37566:66;37559:5;37556:77;37553:103;;;37636:18;;:::i;:::-;37553:103;37683:1;37676:5;37672:13;37665:20;;37458:233;;;:::o;37697:100::-;37736:7;37765:26;37785:5;37765:26;:::i;:::-;37754:37;;37697:100;;;:::o;37803:94::-;37842:7;37871:20;37885:5;37871:20;:::i;:::-;37860:31;;37803:94;;;:::o;37903:180::-;37951:77;37948:1;37941:88;38048:4;38045:1;38038:15;38072:4;38069:1;38062:15;38089:180;38137:77;38134:1;38127:88;38234:4;38231:1;38224:15;38258:4;38255:1;38248:15;38275:180;38323:77;38320:1;38313:88;38420:4;38417:1;38410:15;38444:4;38441:1;38434:15;38461:180;38509:77;38506:1;38499:88;38606:4;38603:1;38596:15;38630:4;38627:1;38620:15;38647:180;38695:77;38692:1;38685:88;38792:4;38789:1;38782:15;38816:4;38813:1;38806:15;38833:180;38881:77;38878:1;38871:88;38978:4;38975:1;38968:15;39002:4;38999:1;38992:15;39019:117;39128:1;39125;39118:12;39142:117;39251:1;39248;39241:12;39265:117;39374:1;39371;39364:12;39388:117;39497:1;39494;39487:12;39511:117;39620:1;39617;39610:12;39634:117;39743:1;39740;39733:12;39757:102;39798:6;39849:2;39845:7;39840:2;39833:5;39829:14;39825:28;39815:38;;39757:102;;;:::o;39865:94::-;39898:8;39946:5;39942:2;39938:14;39917:35;;39865:94;;;:::o;39965:170::-;40105:22;40101:1;40093:6;40089:14;40082:46;39965:170;:::o;40141:177::-;40281:29;40277:1;40269:6;40265:14;40258:53;40141:177;:::o;40324:182::-;40464:34;40460:1;40452:6;40448:14;40441:58;40324:182;:::o;40512:165::-;40652:17;40648:1;40640:6;40636:14;40629:41;40512:165;:::o;40683:173::-;40823:25;40819:1;40811:6;40807:14;40800:49;40683:173;:::o;40862:225::-;41002:34;40998:1;40990:6;40986:14;40979:58;41071:8;41066:2;41058:6;41054:15;41047:33;40862:225;:::o;41093:::-;41233:34;41229:1;41221:6;41217:14;41210:58;41302:8;41297:2;41289:6;41285:15;41278:33;41093:225;:::o;41324:220::-;41464:34;41460:1;41452:6;41448:14;41441:58;41533:3;41528:2;41520:6;41516:15;41509:28;41324:220;:::o;41550:178::-;41690:30;41686:1;41678:6;41674:14;41667:54;41550:178;:::o;41734:182::-;41874:34;41870:1;41862:6;41858:14;41851:58;41734:182;:::o;41922:168::-;42062:20;42058:1;42050:6;42046:14;42039:44;41922:168;:::o;42096:173::-;42236:25;42232:1;42224:6;42220:14;42213:49;42096:173;:::o;42275:247::-;42415:34;42411:1;42403:6;42399:14;42392:58;42484:30;42479:2;42471:6;42467:15;42460:55;42275:247;:::o;42528:172::-;42668:24;42664:1;42656:6;42652:14;42645:48;42528:172;:::o;42706:167::-;42846:19;42842:1;42834:6;42830:14;42823:43;42706:167;:::o;42879:234::-;43019:34;43015:1;43007:6;43003:14;42996:58;43088:17;43083:2;43075:6;43071:15;43064:42;42879:234;:::o;43119:221::-;43259:34;43255:1;43247:6;43243:14;43236:58;43328:4;43323:2;43315:6;43311:15;43304:29;43119:221;:::o;43346:119::-;43433:1;43426:5;43423:12;43413:46;;43439:18;;:::i;:::-;43413:46;43346:119;:::o;43471:122::-;43544:24;43562:5;43544:24;:::i;:::-;43537:5;43534:35;43524:63;;43583:1;43580;43573:12;43524:63;43471:122;:::o;43599:116::-;43669:21;43684:5;43669:21;:::i;:::-;43662:5;43659:32;43649:60;;43705:1;43702;43695:12;43649:60;43599:116;:::o;43721:122::-;43794:24;43812:5;43794:24;:::i;:::-;43787:5;43784:35;43774:63;;43833:1;43830;43823:12;43774:63;43721:122;:::o;43849:120::-;43921:23;43938:5;43921:23;:::i;:::-;43914:5;43911:34;43901:62;;43959:1;43956;43949:12;43901:62;43849:120;:::o;43975:113::-;44062:1;44055:5;44052:12;44042:40;;44078:1;44075;44068:12;44042:40;43975:113;:::o;44094:122::-;44167:24;44185:5;44167:24;:::i;:::-;44160:5;44157:35;44147:63;;44206:1;44203;44196:12;44147:63;44094:122;:::o
Swarm Source
ipfs://77b8ce4a679b6d99ece6fe862f312a60f146f8bf241c6cd703e5e1a580ad3300
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.