ERC-721
Overview
Max Total Supply
5,000 DA
Holders
1,484
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 DALoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
DeApes
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-04-01 */ /** *Submitted for verification at Etherscan.io on 2022-12-28 */ // SPDX-License-Identifier: MIT // File: @openzeppelin/contracts/utils/structs/EnumerableSet.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. 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) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // 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 in 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: contracts/IOperatorFilterRegistry.sol pragma solidity ^0.8.13; interface IOperatorFilterRegistry { function isOperatorAllowed(address registrant, address operator) external view returns (bool); function register(address registrant) external; function registerAndSubscribe(address registrant, address subscription) external; function registerAndCopyEntries(address registrant, address registrantToCopy) external; function unregister(address addr) external; function updateOperator(address registrant, address operator, bool filtered) external; function updateOperators(address registrant, address[] calldata operators, bool filtered) external; function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external; function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external; function subscribe(address registrant, address registrantToSubscribe) external; function unsubscribe(address registrant, bool copyExistingEntries) external; function subscriptionOf(address addr) external returns (address registrant); function subscribers(address registrant) external returns (address[] memory); function subscriberAt(address registrant, uint256 index) external returns (address); function copyEntriesOf(address registrant, address registrantToCopy) external; function isOperatorFiltered(address registrant, address operator) external returns (bool); function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); function filteredOperators(address addr) external returns (address[] memory); function filteredCodeHashes(address addr) external returns (bytes32[] memory); function filteredOperatorAt(address registrant, uint256 index) external returns (address); function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); function isRegistered(address addr) external returns (bool); function codeHashOf(address addr) external returns (bytes32); } // File: contracts/OperatorFilterer.sol // OpenZeppelin Contracts (last updated v4.8.0) (access/Ownable2Step.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides 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} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ pragma solidity ^0.8.13; /** * @title OwnedRegistrant * @notice Ownable contract that registers itself with the OperatorFilterRegistry and administers its own entries, * to facilitate a subscription whose ownership can be transferred. */ pragma solidity ^0.8.13; contract OperatorFilterRegistryErrorsAndEvents { error CannotFilterEOAs(); error AddressAlreadyFiltered(address operator); error AddressNotFiltered(address operator); error CodeHashAlreadyFiltered(bytes32 codeHash); error CodeHashNotFiltered(bytes32 codeHash); error OnlyAddressOrOwner(); error NotRegistered(address registrant); error AlreadyRegistered(); error AlreadySubscribed(address subscription); error NotSubscribed(); error CannotUpdateWhileSubscribed(address subscription); error CannotSubscribeToSelf(); error CannotSubscribeToZeroAddress(); error NotOwnable(); error AddressFiltered(address filtered); error CodeHashFiltered(address account, bytes32 codeHash); error CannotSubscribeToRegistrantWithSubscription(address registrant); error CannotCopyFromSelf(); event RegistrationUpdated(address indexed registrant, bool indexed registered); event OperatorUpdated(address indexed registrant, address indexed operator, bool indexed filtered); event OperatorsUpdated(address indexed registrant, address[] operators, bool indexed filtered); event CodeHashUpdated(address indexed registrant, bytes32 indexed codeHash, bool indexed filtered); event CodeHashesUpdated(address indexed registrant, bytes32[] codeHashes, bool indexed filtered); event SubscriptionUpdated(address indexed registrant, address indexed subscription, bool indexed subscribed); } pragma solidity ^0.8.13; /** * @title OperatorFilterRegistry * @notice Borrows heavily from the QQL BlacklistOperatorFilter contract: * https://github.com/qql-art/contracts/blob/main/contracts/BlacklistOperatorFilter.sol * @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be * * restricted according to the isOperatorAllowed function. */ contract OperatorFilterRegistry is IOperatorFilterRegistry, OperatorFilterRegistryErrorsAndEvents { using EnumerableSet for EnumerableSet.AddressSet; using EnumerableSet for EnumerableSet.Bytes32Set; /// @dev initialized accounts have a nonzero codehash (see https://eips.ethereum.org/EIPS/eip-1052) /// Note that this will also be a smart contract's codehash when making calls from its constructor. bytes32 constant EOA_CODEHASH = keccak256(""); mapping(address => EnumerableSet.AddressSet) private _filteredOperators; mapping(address => EnumerableSet.Bytes32Set) private _filteredCodeHashes; mapping(address => address) private _registrations; mapping(address => EnumerableSet.AddressSet) private _subscribers; /** * @notice restricts method caller to the address or EIP-173 "owner()" */ modifier onlyAddressOrOwner(address addr) { if (msg.sender != addr) { try Ownable(addr).owner() returns (address owner) { if (msg.sender != owner) { revert OnlyAddressOrOwner(); } } catch (bytes memory reason) { if (reason.length == 0) { revert NotOwnable(); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } _; } /** * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns * true if supplied registrant address is not registered. */ function isOperatorAllowed(address registrant, address operator) external view returns (bool) { address registration = _registrations[registrant]; if (registration != address(0)) { EnumerableSet.AddressSet storage filteredOperatorsRef; EnumerableSet.Bytes32Set storage filteredCodeHashesRef; filteredOperatorsRef = _filteredOperators[registration]; filteredCodeHashesRef = _filteredCodeHashes[registration]; if (filteredOperatorsRef.contains(operator)) { revert AddressFiltered(operator); } if (operator.code.length > 0) { bytes32 codeHash = operator.codehash; if (filteredCodeHashesRef.contains(codeHash)) { revert CodeHashFiltered(operator, codeHash); } } } return true; } ////////////////// // AUTH METHODS // ////////////////// /** * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner. */ function register(address registrant) external onlyAddressOrOwner(registrant) { if (_registrations[registrant] != address(0)) { revert AlreadyRegistered(); } _registrations[registrant] = registrant; emit RegistrationUpdated(registrant, true); } /** * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner. * Note that this does not remove any filtered addresses or codeHashes. * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes. */ function unregister(address registrant) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { _subscribers[registration].remove(registrant); emit SubscriptionUpdated(registrant, registration, false); } _registrations[registrant] = address(0); emit RegistrationUpdated(registrant, false); } /** * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes. */ function registerAndSubscribe(address registrant, address subscription) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration != address(0)) { revert AlreadyRegistered(); } if (registrant == subscription) { revert CannotSubscribeToSelf(); } address subscriptionRegistration = _registrations[subscription]; if (subscriptionRegistration == address(0)) { revert NotRegistered(subscription); } if (subscriptionRegistration != subscription) { revert CannotSubscribeToRegistrantWithSubscription(subscription); } _registrations[registrant] = subscription; _subscribers[subscription].add(registrant); emit RegistrationUpdated(registrant, true); emit SubscriptionUpdated(registrant, subscription, true); } /** * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another * address without subscribing. */ function registerAndCopyEntries(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) { if (registrantToCopy == registrant) { revert CannotCopyFromSelf(); } address registration = _registrations[registrant]; if (registration != address(0)) { revert AlreadyRegistered(); } address registrantRegistration = _registrations[registrantToCopy]; if (registrantRegistration == address(0)) { revert NotRegistered(registrantToCopy); } _registrations[registrant] = registrant; emit RegistrationUpdated(registrant, true); _copyEntries(registrant, registrantToCopy); } /** * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered. */ function updateOperator(address registrant, address operator, bool filtered) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { revert CannotUpdateWhileSubscribed(registration); } EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant]; if (!filtered) { bool removed = filteredOperatorsRef.remove(operator); if (!removed) { revert AddressNotFiltered(operator); } } else { bool added = filteredOperatorsRef.add(operator); if (!added) { revert AddressAlreadyFiltered(operator); } } emit OperatorUpdated(registrant, operator, filtered); } /** * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered. */ function updateCodeHash(address registrant, bytes32 codeHash, bool filtered) external onlyAddressOrOwner(registrant) { if (codeHash == EOA_CODEHASH) { revert CannotFilterEOAs(); } address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { revert CannotUpdateWhileSubscribed(registration); } EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant]; if (!filtered) { bool removed = filteredCodeHashesRef.remove(codeHash); if (!removed) { revert CodeHashNotFiltered(codeHash); } } else { bool added = filteredCodeHashesRef.add(codeHash); if (!added) { revert CodeHashAlreadyFiltered(codeHash); } } emit CodeHashUpdated(registrant, codeHash, filtered); } /** * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates. */ function updateOperators(address registrant, address[] calldata operators, bool filtered) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { revert CannotUpdateWhileSubscribed(registration); } EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant]; uint256 operatorsLength = operators.length; unchecked { if (!filtered) { for (uint256 i = 0; i < operatorsLength; ++i) { address operator = operators[i]; bool removed = filteredOperatorsRef.remove(operator); if (!removed) { revert AddressNotFiltered(operator); } } } else { for (uint256 i = 0; i < operatorsLength; ++i) { address operator = operators[i]; bool added = filteredOperatorsRef.add(operator); if (!added) { revert AddressAlreadyFiltered(operator); } } } } emit OperatorsUpdated(registrant, operators, filtered); } /** * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates. */ function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { revert CannotUpdateWhileSubscribed(registration); } EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant]; uint256 codeHashesLength = codeHashes.length; unchecked { if (!filtered) { for (uint256 i = 0; i < codeHashesLength; ++i) { bytes32 codeHash = codeHashes[i]; bool removed = filteredCodeHashesRef.remove(codeHash); if (!removed) { revert CodeHashNotFiltered(codeHash); } } } else { for (uint256 i = 0; i < codeHashesLength; ++i) { bytes32 codeHash = codeHashes[i]; if (codeHash == EOA_CODEHASH) { revert CannotFilterEOAs(); } bool added = filteredCodeHashesRef.add(codeHash); if (!added) { revert CodeHashAlreadyFiltered(codeHash); } } } } emit CodeHashesUpdated(registrant, codeHashes, filtered); } /** * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous * subscription if present. * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case, * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be * used. */ function subscribe(address registrant, address newSubscription) external onlyAddressOrOwner(registrant) { if (registrant == newSubscription) { revert CannotSubscribeToSelf(); } if (newSubscription == address(0)) { revert CannotSubscribeToZeroAddress(); } address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration == newSubscription) { revert AlreadySubscribed(newSubscription); } address newSubscriptionRegistration = _registrations[newSubscription]; if (newSubscriptionRegistration == address(0)) { revert NotRegistered(newSubscription); } if (newSubscriptionRegistration != newSubscription) { revert CannotSubscribeToRegistrantWithSubscription(newSubscription); } if (registration != registrant) { _subscribers[registration].remove(registrant); emit SubscriptionUpdated(registrant, registration, false); } _registrations[registrant] = newSubscription; _subscribers[newSubscription].add(registrant); emit SubscriptionUpdated(registrant, newSubscription, true); } /** * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes. */ function unsubscribe(address registrant, bool copyExistingEntries) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration == registrant) { revert NotSubscribed(); } _subscribers[registration].remove(registrant); _registrations[registrant] = registrant; emit SubscriptionUpdated(registrant, registration, false); if (copyExistingEntries) { _copyEntries(registrant, registration); } } /** * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr. */ function copyEntriesOf(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) { if (registrant == registrantToCopy) { revert CannotCopyFromSelf(); } address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { revert CannotUpdateWhileSubscribed(registration); } address registrantRegistration = _registrations[registrantToCopy]; if (registrantRegistration == address(0)) { revert NotRegistered(registrantToCopy); } _copyEntries(registrant, registrantToCopy); } /// @dev helper to copy entries from registrantToCopy to registrant and emit events function _copyEntries(address registrant, address registrantToCopy) private { EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrantToCopy]; EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrantToCopy]; uint256 filteredOperatorsLength = filteredOperatorsRef.length(); uint256 filteredCodeHashesLength = filteredCodeHashesRef.length(); unchecked { for (uint256 i = 0; i < filteredOperatorsLength; ++i) { address operator = filteredOperatorsRef.at(i); bool added = _filteredOperators[registrant].add(operator); if (added) { emit OperatorUpdated(registrant, operator, true); } } for (uint256 i = 0; i < filteredCodeHashesLength; ++i) { bytes32 codehash = filteredCodeHashesRef.at(i); bool added = _filteredCodeHashes[registrant].add(codehash); if (added) { emit CodeHashUpdated(registrant, codehash, true); } } } } ////////////////// // VIEW METHODS // ////////////////// /** * @notice Get the subscription address of a given registrant, if any. */ function subscriptionOf(address registrant) external view returns (address subscription) { subscription = _registrations[registrant]; if (subscription == address(0)) { revert NotRegistered(registrant); } else if (subscription == registrant) { subscription = address(0); } } /** * @notice Get the set of addresses subscribed to a given registrant. * Note that order is not guaranteed as updates are made. */ function subscribers(address registrant) external view returns (address[] memory) { return _subscribers[registrant].values(); } /** * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant. * Note that order is not guaranteed as updates are made. */ function subscriberAt(address registrant, uint256 index) external view returns (address) { return _subscribers[registrant].at(index); } /** * @notice Returns true if operator is filtered by a given address or its subscription. */ function isOperatorFiltered(address registrant, address operator) external view returns (bool) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredOperators[registration].contains(operator); } return _filteredOperators[registrant].contains(operator); } /** * @notice Returns true if a codeHash is filtered by a given address or its subscription. */ function isCodeHashFiltered(address registrant, bytes32 codeHash) external view returns (bool) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredCodeHashes[registration].contains(codeHash); } return _filteredCodeHashes[registrant].contains(codeHash); } /** * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription. */ function isCodeHashOfFiltered(address registrant, address operatorWithCode) external view returns (bool) { bytes32 codeHash = operatorWithCode.codehash; address registration = _registrations[registrant]; if (registration != registrant) { return _filteredCodeHashes[registration].contains(codeHash); } return _filteredCodeHashes[registrant].contains(codeHash); } /** * @notice Returns true if an address has registered */ function isRegistered(address registrant) external view returns (bool) { return _registrations[registrant] != address(0); } /** * @notice Returns a list of filtered operators for a given address or its subscription. */ function filteredOperators(address registrant) external view returns (address[] memory) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredOperators[registration].values(); } return _filteredOperators[registrant].values(); } /** * @notice Returns the set of filtered codeHashes for a given address or its subscription. * Note that order is not guaranteed as updates are made. */ function filteredCodeHashes(address registrant) external view returns (bytes32[] memory) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredCodeHashes[registration].values(); } return _filteredCodeHashes[registrant].values(); } /** * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or * its subscription. * Note that order is not guaranteed as updates are made. */ function filteredOperatorAt(address registrant, uint256 index) external view returns (address) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredOperators[registration].at(index); } return _filteredOperators[registrant].at(index); } /** * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or * its subscription. * Note that order is not guaranteed as updates are made. */ function filteredCodeHashAt(address registrant, uint256 index) external view returns (bytes32) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredCodeHashes[registration].at(index); } return _filteredCodeHashes[registrant].at(index); } /// @dev Convenience method to compute the code hash of an arbitrary contract function codeHashOf(address a) external view returns (bytes32) { return a.codehash; } } pragma solidity ^0.8.13; abstract contract OperatorFilterer { error OperatorNotAllowed(address operator); IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); constructor(address subscriptionOrRegistrantToCopy, bool subscribe) { // If an inheriting token contract is deployed to a network without the registry deployed, the modifier // will not revert, but the contract will need to be registered with the registry once it is deployed in // order for the modifier to filter addresses. if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { if (subscribe) { OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy); } else { if (subscriptionOrRegistrantToCopy != address(0)) { OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy); } else { OPERATOR_FILTER_REGISTRY.register(address(this)); } } } } modifier onlyAllowedOperator(address from) virtual { // Allow spending tokens from addresses with balance // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred // from an EOA. if (from != msg.sender) { _checkFilterOperator(msg.sender); } _; } modifier onlyAllowedOperatorApproval(address operator) virtual { _checkFilterOperator(operator); _; } function _checkFilterOperator(address operator) internal view virtual { // Check registry code length to facilitate testing in environments without a deployed registry. if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) { revert OperatorNotAllowed(operator); } } } } // File: contracts/DefaultOperatorFilterer.sol pragma solidity ^0.8.13; /** * @title DefaultOperatorFilterer * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription. */ abstract contract DefaultOperatorFilterer is OperatorFilterer { address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {} } // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _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) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @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] = _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/utils/Address.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.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); } 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/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external ; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } // File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // File: @openzeppelin/contracts/utils/Context.sol pragma solidity ^0.8.0; interface IERC721Enumerable is IERC721 { function totalSupply() external view returns (uint256); function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); function tokenByIndex(uint256 index) external view returns (uint256); } pragma solidity ^0.8.0; abstract contract ReentrancyGuard { uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } modifier nonReentrant() { require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); _status = _ENTERED; _; _status = _NOT_ENTERED; } } // 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/token/ERC721/ERC721.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable, DefaultOperatorFilterer { using Address for address; using Strings for uint256; struct TokenOwnership { address addr; uint64 startTimestamp; } struct AddressData { uint128 balance; uint128 numberMinted; } uint256 internal currentIndex; string private _name; string private _symbol; mapping(uint256 => TokenOwnership) internal _ownerships; mapping(address => AddressData) private _addressData; mapping(uint256 => address) private _tokenApprovals; mapping(address => mapping(address => bool)) private _operatorApprovals; constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } function totalSupply() public view override returns (uint256) { return currentIndex; } function tokenByIndex(uint256 index) public view override returns (uint256) { require(index < totalSupply(), "ERC721A: global index out of bounds"); return index; } function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) { require(index < balanceOf(owner), "ERC721A: owner index out of bounds"); uint256 numMintedSoFar = totalSupply(); uint256 tokenIdsIdx; address currOwnershipAddr; unchecked { for (uint256 i; i < numMintedSoFar; i++) { TokenOwnership memory ownership = _ownerships[i]; if (ownership.addr != address(0)) { currOwnershipAddr = ownership.addr; } if (currOwnershipAddr == owner) { if (tokenIdsIdx == index) { return i; } tokenIdsIdx++; } } } revert("ERC721A: unable to get token of owner by index"); } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } function balanceOf(address owner) public view override returns (uint256) { require(owner != address(0), "ERC721A: balance query for the zero address"); return uint256(_addressData[owner].balance); } function _numberMinted(address owner) internal view returns (uint256) { require(owner != address(0), "ERC721A: number minted query for the zero address"); return uint256(_addressData[owner].numberMinted); } function ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) { require(_exists(tokenId), "ERC721A: owner query for nonexistent token"); unchecked { for (uint256 curr = tokenId; curr >= 0; curr--) { TokenOwnership memory ownership = _ownerships[curr]; if (ownership.addr != address(0)) { return ownership; } } } revert("ERC721A: unable to determine the owner of token"); } function ownerOf(uint256 tokenId) public view override returns (address) { return ownershipOf(tokenId).addr; } function name() public view virtual override returns (string memory) { return _name; } function symbol() public view virtual override returns (string memory) { return _symbol; } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } function _baseURI() internal view virtual returns (string memory) { return ""; } function approve(address to, uint256 tokenId) public virtual override onlyAllowedOperator(to) { address owner = ERC721A.ownerOf(tokenId); require(to != owner, "ERC721A: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721A: approve caller is not owner nor approved for all" ); _approve(to, tokenId, owner); } function getApproved(uint256 tokenId) public view override returns (address) { require(_exists(tokenId), "ERC721A: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } function setApprovalForAll(address operator, bool approved) public virtual override onlyAllowedOperator(operator) { require(operator != _msgSender(), "ERC721A: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_msgSender(), operator, approved); } function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } function transferFrom( address from, address to, uint256 tokenId ) public virtual override onlyAllowedOperator(from){ _transfer(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override onlyAllowedOperator(from) { safeTransferFrom(from, to, tokenId, ""); } function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override onlyAllowedOperator(from){ _transfer(from, to, tokenId); require( _checkOnERC721Received(from, to, tokenId, _data), "ERC721A: transfer to non ERC721Receiver implementer" ); } function _exists(uint256 tokenId) internal view returns (bool) { return tokenId < currentIndex; } function _safeMint(address to, uint256 quantity) internal { _safeMint(to, quantity, ""); } function _safeMint( address to, uint256 quantity, bytes memory _data ) internal { _mint(to, quantity, _data, true); } function _mint( address to, uint256 quantity, bytes memory _data, bool safe ) internal { uint256 startTokenId = currentIndex; require(to != address(0), "ERC721A: mint to the zero address"); require(quantity != 0, "ERC721A: quantity must be greater than 0"); _beforeTokenTransfers(address(0), to, startTokenId, quantity); unchecked { _addressData[to].balance += uint128(quantity); _addressData[to].numberMinted += uint128(quantity); _ownerships[startTokenId].addr = to; _ownerships[startTokenId].startTimestamp = uint64(block.timestamp); uint256 updatedIndex = startTokenId; for (uint256 i; i < quantity; i++) { emit Transfer(address(0), to, updatedIndex); if (safe) { require( _checkOnERC721Received(address(0), to, updatedIndex, _data), "ERC721A: transfer to non ERC721Receiver implementer" ); } updatedIndex++; } currentIndex = updatedIndex; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } function _transfer( address from, address to, uint256 tokenId ) private { TokenOwnership memory prevOwnership = ownershipOf(tokenId); bool isApprovedOrOwner = (_msgSender() == prevOwnership.addr || getApproved(tokenId) == _msgSender() || isApprovedForAll(prevOwnership.addr, _msgSender())); require(isApprovedOrOwner, "ERC721A: transfer caller is not owner nor approved"); require(prevOwnership.addr == from, "ERC721A: transfer from incorrect owner"); require(to != address(0), "ERC721A: transfer to the zero address"); _beforeTokenTransfers(from, to, tokenId, 1); _approve(address(0), tokenId, prevOwnership.addr); unchecked { _addressData[from].balance -= 1; _addressData[to].balance += 1; _ownerships[tokenId].addr = to; _ownerships[tokenId].startTimestamp = uint64(block.timestamp); uint256 nextTokenId = tokenId + 1; if (_ownerships[nextTokenId].addr == address(0)) { if (_exists(nextTokenId)) { _ownerships[nextTokenId].addr = prevOwnership.addr; _ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp; } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } function _approve( address to, uint256 tokenId, address owner ) private { _tokenApprovals[tokenId] = to; emit Approval(owner, to, tokenId); } function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721A: transfer to non ERC721Receiver implementer"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} } /** * @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); } } abstract contract Ownable2Step is Ownable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() external { address sender = _msgSender(); require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner"); _transferOwnership(sender); } } contract OwnedRegistrant is Ownable2Step { address constant registry = 0x000000000000AAeB6D7670E522A718067333cd4E; constructor(address _owner) { IOperatorFilterRegistry(registry).register(address(this)); transferOwnership(_owner); } } pragma solidity ^0.8.13; /** * @title UpdatableOperatorFilterer * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another * registrant's entries in the OperatorFilterRegistry. This contract allows the Owner to update the * OperatorFilterRegistry address via updateOperatorFilterRegistryAddress, including to the zero address, * which will bypass registry checks. * Note that OpenSea will still disable creator fee enforcement if filtered operators begin fulfilling orders * on-chain, eg, if the registry is revoked or bypassed. * @dev This smart contract is meant to be inherited by token contracts so they can use the following: * - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods. * - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods. */ abstract contract UpdatableOperatorFilterer { error OperatorNotAllowed(address operator); error OnlyOwner(); IOperatorFilterRegistry public operatorFilterRegistry; constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe) { IOperatorFilterRegistry registry = IOperatorFilterRegistry(_registry); operatorFilterRegistry = registry; // If an inheriting token contract is deployed to a network without the registry deployed, the modifier // will not revert, but the contract will need to be registered with the registry once it is deployed in // order for the modifier to filter addresses. if (address(registry).code.length > 0) { if (subscribe) { registry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy); } else { if (subscriptionOrRegistrantToCopy != address(0)) { registry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy); } else { registry.register(address(this)); } } } } modifier onlyAllowedOperator(address from) virtual { // Allow spending tokens from addresses with balance // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred // from an EOA. if (from != msg.sender) { _checkFilterOperator(msg.sender); } _; } modifier onlyAllowedOperatorApproval(address operator) virtual { _checkFilterOperator(operator); _; } /** * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero * address, checks will be bypassed. OnlyOwner. */ function updateOperatorFilterRegistryAddress(address newRegistry) public virtual { if (msg.sender != owner()) { revert OnlyOwner(); } operatorFilterRegistry = IOperatorFilterRegistry(newRegistry); } /** * @dev assume the contract has an owner, but leave specific Ownable implementation up to inheriting contract */ function owner() public view virtual returns (address); function _checkFilterOperator(address operator) internal view virtual { IOperatorFilterRegistry registry = operatorFilterRegistry; // Check registry code length to facilitate testing in environments without a deployed registry. if (address(registry) != address(0) && address(registry).code.length > 0) { if (!registry.isOperatorAllowed(address(this), operator)) { revert OperatorNotAllowed(operator); } } } } pragma solidity ^0.8.13; /** * @title RevokableOperatorFilterer * @notice This contract is meant to allow contracts to permanently skip OperatorFilterRegistry checks if desired. The * Registry itself has an "unregister" function, but if the contract is ownable, the owner can re-register at * any point. As implemented, this abstract contract allows the contract owner to permanently skip the * OperatorFilterRegistry checks by calling revokeOperatorFilterRegistry. Once done, the registry * address cannot be further updated. * Note that OpenSea will still disable creator fee enforcement if filtered operators begin fulfilling orders * on-chain, eg, if the registry is revoked or bypassed. */ abstract contract RevokableOperatorFilterer is UpdatableOperatorFilterer { error RegistryHasBeenRevoked(); error InitialRegistryAddressCannotBeZeroAddress(); bool public isOperatorFilterRegistryRevoked; constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe) UpdatableOperatorFilterer(_registry, subscriptionOrRegistrantToCopy, subscribe) { // don't allow creating a contract with a permanently revoked registry if (_registry == address(0)) { revert InitialRegistryAddressCannotBeZeroAddress(); } } function _checkFilterOperator(address operator) internal view virtual override { if (address(operatorFilterRegistry) != address(0)) { super._checkFilterOperator(operator); } } /** * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero * address, checks will be permanently bypassed, and the address cannot be updated again. OnlyOwner. */ function updateOperatorFilterRegistryAddress(address newRegistry) public override { if (msg.sender != owner()) { revert OnlyOwner(); } // if registry has been revoked, do not allow further updates if (isOperatorFilterRegistryRevoked) { revert RegistryHasBeenRevoked(); } operatorFilterRegistry = IOperatorFilterRegistry(newRegistry); } /** * @notice Revoke the OperatorFilterRegistry address, permanently bypassing checks. OnlyOwner. */ function revokeOperatorFilterRegistry() public { if (msg.sender != owner()) { revert OnlyOwner(); } // if registry has been revoked, do not allow further updates if (isOperatorFilterRegistryRevoked) { revert RegistryHasBeenRevoked(); } // set to zero address to bypass checks operatorFilterRegistry = IOperatorFilterRegistry(address(0)); isOperatorFilterRegistryRevoked = true; } } pragma solidity ^0.8.13; /** * @title RevokableDefaultOperatorFilterer * @notice Inherits from RevokableOperatorFilterer and automatically subscribes to the default OpenSea subscription. * Note that OpenSea will disable creator fee enforcement if filtered operators begin fulfilling orders * on-chain, eg, if the registry is revoked or bypassed. */ abstract contract RevokableDefaultOperatorFilterer is RevokableOperatorFilterer { address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); constructor() RevokableOperatorFilterer(0x000000000000AAeB6D7670E522A718067333cd4E, DEFAULT_SUBSCRIPTION, true) {} } pragma solidity ^0.8.9; contract DeApes is ERC721A, Ownable, ReentrancyGuard { using Strings for uint256; uint private _totalStake; address private _bozoContract; uint public price = 0.005 ether; uint public maxTx = 20; uint public maxSupply = 5000; uint256 public reservedSupply = 10; string private baseURI; bool public mintLive; uint public maxFreePerWallet = 1; uint public freeMinted = 0; uint public totalFreeAvailable = 5000; mapping(address => uint256) public _senderFreeMinted; constructor() ERC721A("DeApes", "DA") {} function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) { require(_exists(_tokenId),"ERC721Metadata: URI query for nonexistent token"); string memory currentBaseURI = _baseURI(); return bytes(currentBaseURI).length > 0 ? string(abi.encodePacked(currentBaseURI,Strings.toString(_tokenId),".json")) : ""; } function _baseURI() internal view virtual override returns (string memory) { return baseURI; } function mint(uint256 amount) external payable { if ((freeMinted < totalFreeAvailable) && (_senderFreeMinted[msg.sender] < maxFreePerWallet)) { require(mintLive, "not live yet"); require(msg.value >= (amount * price) - price, "Eth Amount Invalid"); require(totalSupply() + amount <= maxSupply, "No more supply"); require(amount <= maxTx, "Max per TX reached."); _senderFreeMinted[msg.sender] = maxFreePerWallet; freeMinted += maxFreePerWallet; } else{ require(mintLive, "not live yet"); require(msg.value >= amount * price, "Eth Amount Invalid"); require(totalSupply() + amount <= maxSupply, "No more supply"); require(amount <= maxTx, "Max per TX reached."); } _safeMint(msg.sender, amount); } function reservedMint(uint256 Amount) external onlyOwner { uint256 Remaining = reservedSupply; require(totalSupply() + Amount <= maxSupply, "No more supply to be minted"); require(Remaining >= Amount, "Reserved Supply Minted"); reservedSupply = Remaining - Amount; _safeMint(msg.sender, Amount); } function enableMinting() external onlyOwner { mintLive = !mintLive; } function setBaseUri(string memory baseuri_) public onlyOwner { baseURI = baseuri_; } function setCost(uint256 price_) external onlyOwner { price = price_; } function costInspect() public view returns (uint256) { return price; } function setmaxTx(uint256 _MaxTx) external onlyOwner { maxTx = _MaxTx; } function setMaxTotalFreeAvailable(uint256 MaxTotalFree_) external onlyOwner { totalFreeAvailable = MaxTotalFree_; } function setmaxFreePerWallet(uint256 maxFreePerWallet_) external onlyOwner { maxFreePerWallet = maxFreePerWallet_; } function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { super.setApprovalForAll(operator, approved); } function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) { super.approve(operator, tokenId); } function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { super.transferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId, data); } function withdraw() external onlyOwner nonReentrant { (bool success, ) = msg.sender.call{value: address(this).balance}(""); require(success, "Transfer failed."); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","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":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_senderFreeMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"costInspect","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"freeMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxFreePerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintLive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"Amount","type":"uint256"}],"name":"reservedMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reservedSupply","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":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseuri_","type":"string"}],"name":"setBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price_","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"MaxTotalFree_","type":"uint256"}],"name":"setMaxTotalFreeAvailable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxFreePerWallet_","type":"uint256"}],"name":"setmaxFreePerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_MaxTx","type":"uint256"}],"name":"setmaxTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"totalFreeAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526611c37937e08000600b556014600c55611388600d55600a600e55600160115560006012556113886013553480156200003c57600080fd5b506040518060400160405280600681526020017f44654170657300000000000000000000000000000000000000000000000000008152506040518060400160405280600281526020017f4441000000000000000000000000000000000000000000000000000000000000815250733cc6cdda760b79bafa08df41ecfa224f810dceb6600160006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115620002b55780156200017b576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b8152600401620001419291906200041e565b600060405180830381600087803b1580156200015c57600080fd5b505af115801562000171573d6000803e3d6000fd5b50505050620002b4565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462000235576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b8152600401620001fb9291906200041e565b600060405180830381600087803b1580156200021657600080fd5b505af11580156200022b573d6000803e3d6000fd5b50505050620002b3565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b81526004016200027e91906200044b565b600060405180830381600087803b1580156200029957600080fd5b505af1158015620002ae573d6000803e3d6000fd5b505050505b5b5b50508160019081620002c89190620006e2565b508060029081620002da9190620006e2565b505050620002fd620002f16200030b60201b60201c565b6200031360201b60201c565b6001600881905550620007c9565b600033905090565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200040682620003d9565b9050919050565b6200041881620003f9565b82525050565b60006040820190506200043560008301856200040d565b6200044460208301846200040d565b9392505050565b60006020820190506200046260008301846200040d565b92915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620004ea57607f821691505b6020821081036200050057620004ff620004a2565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026200056a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200052b565b6200057686836200052b565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620005c3620005bd620005b7846200058e565b62000598565b6200058e565b9050919050565b6000819050919050565b620005df83620005a2565b620005f7620005ee82620005ca565b84845462000538565b825550505050565b600090565b6200060e620005ff565b6200061b818484620005d4565b505050565b5b8181101562000643576200063760008262000604565b60018101905062000621565b5050565b601f82111562000692576200065c8162000506565b62000667846200051b565b8101602085101562000677578190505b6200068f62000686856200051b565b83018262000620565b50505b505050565b600082821c905092915050565b6000620006b76000198460080262000697565b1980831691505092915050565b6000620006d28383620006a4565b9150826002028217905092915050565b620006ed8262000468565b67ffffffffffffffff81111562000709576200070862000473565b5b620007158254620004d1565b6200072282828562000647565b600060209050601f8311600181146200075a576000841562000745578287015190505b620007518582620006c4565b865550620007c1565b601f1984166200076a8662000506565b60005b8281101562000794578489015182556001820191506020850194506020810190506200076d565b86831015620007b45784890151620007b0601f891682620006a4565b8355505b6001600288020188555050505b505050505050565b614ae480620007d96000396000f3fe6080604052600436106102305760003560e01c80638c74bf0e1161012e578063b88d4fde116100ab578063e02a61421161006f578063e02a61421461081c578063e797ec1b14610859578063e8656fcc14610870578063e985e9c51461089b578063f2fde38b146108d857610230565b8063b88d4fde14610735578063b94116011461075e578063c87b56dd14610789578063d10a1a2b146107c6578063d5abeb01146107f157610230565b8063a0712d68116100f2578063a0712d6814610673578063a0bcfc7f1461068f578063a22cb465146106b8578063a7027357146106e1578063b0c2b5611461070c57610230565b80638c74bf0e146105a05780638da5cb5b146105c95780639254d4f4146105f457806395d89b411461061d578063a035b1fe1461064857610230565b806342842e0e116101bc5780636352211e116101805780636352211e146104b95780636bf67d71146104f657806370a0823114610521578063715018a61461055e5780637437681e1461057557610230565b806342842e0e146103d657806344a0d68a146103ff57806344d19d2b146104285780634f6ccce714610453578063536c35761461049057610230565b806318160ddd1161020357806318160ddd1461030357806323b872dd1461032e5780632f745c59146103575780633ccfd60b1461039457806341f43434146103ab57610230565b806301ffc9a71461023557806306fdde0314610272578063081812fc1461029d578063095ea7b3146102da575b600080fd5b34801561024157600080fd5b5061025c60048036038101906102579190612feb565b610901565b6040516102699190613033565b60405180910390f35b34801561027e57600080fd5b50610287610a4b565b60405161029491906130de565b60405180910390f35b3480156102a957600080fd5b506102c460048036038101906102bf9190613136565b610add565b6040516102d191906131a4565b60405180910390f35b3480156102e657600080fd5b5061030160048036038101906102fc91906131eb565b610b62565b005b34801561030f57600080fd5b50610318610b7b565b604051610325919061323a565b60405180910390f35b34801561033a57600080fd5b5061035560048036038101906103509190613255565b610b84565b005b34801561036357600080fd5b5061037e600480360381019061037991906131eb565b610bd3565b60405161038b919061323a565b60405180910390f35b3480156103a057600080fd5b506103a9610dc3565b005b3480156103b757600080fd5b506103c0610ecf565b6040516103cd9190613307565b60405180910390f35b3480156103e257600080fd5b506103fd60048036038101906103f89190613255565b610ee1565b005b34801561040b57600080fd5b5061042660048036038101906104219190613136565b610f30565b005b34801561043457600080fd5b5061043d610f42565b60405161044a919061323a565b60405180910390f35b34801561045f57600080fd5b5061047a60048036038101906104759190613136565b610f48565b604051610487919061323a565b60405180910390f35b34801561049c57600080fd5b506104b760048036038101906104b29190613136565b610f9b565b005b3480156104c557600080fd5b506104e060048036038101906104db9190613136565b610fad565b6040516104ed91906131a4565b60405180910390f35b34801561050257600080fd5b5061050b610fc3565b604051610518919061323a565b60405180910390f35b34801561052d57600080fd5b5061054860048036038101906105439190613322565b610fc9565b604051610555919061323a565b60405180910390f35b34801561056a57600080fd5b506105736110b1565b005b34801561058157600080fd5b5061058a6110c5565b604051610597919061323a565b60405180910390f35b3480156105ac57600080fd5b506105c760048036038101906105c29190613136565b6110cb565b005b3480156105d557600080fd5b506105de611194565b6040516105eb91906131a4565b60405180910390f35b34801561060057600080fd5b5061061b60048036038101906106169190613136565b6111be565b005b34801561062957600080fd5b506106326111d0565b60405161063f91906130de565b60405180910390f35b34801561065457600080fd5b5061065d611262565b60405161066a919061323a565b60405180910390f35b61068d60048036038101906106889190613136565b611268565b005b34801561069b57600080fd5b506106b660048036038101906106b19190613484565b6115b7565b005b3480156106c457600080fd5b506106df60048036038101906106da91906134f9565b6115d2565b005b3480156106ed57600080fd5b506106f66115eb565b604051610703919061323a565b60405180910390f35b34801561071857600080fd5b50610733600480360381019061072e9190613136565b6115f1565b005b34801561074157600080fd5b5061075c600480360381019061075791906135da565b611603565b005b34801561076a57600080fd5b50610773611654565b604051610780919061323a565b60405180910390f35b34801561079557600080fd5b506107b060048036038101906107ab9190613136565b61165e565b6040516107bd91906130de565b60405180910390f35b3480156107d257600080fd5b506107db611705565b6040516107e8919061323a565b60405180910390f35b3480156107fd57600080fd5b5061080661170b565b604051610813919061323a565b60405180910390f35b34801561082857600080fd5b50610843600480360381019061083e9190613322565b611711565b604051610850919061323a565b60405180910390f35b34801561086557600080fd5b5061086e611729565b005b34801561087c57600080fd5b5061088561175d565b6040516108929190613033565b60405180910390f35b3480156108a757600080fd5b506108c260048036038101906108bd919061365d565b611770565b6040516108cf9190613033565b60405180910390f35b3480156108e457600080fd5b506108ff60048036038101906108fa9190613322565b611804565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109cc57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a3457507f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a445750610a4382611887565b5b9050919050565b606060018054610a5a906136cc565b80601f0160208091040260200160405190810160405280929190818152602001828054610a86906136cc565b8015610ad35780601f10610aa857610100808354040283529160200191610ad3565b820191906000526020600020905b815481529060010190602001808311610ab657829003601f168201915b5050505050905090565b6000610ae8826118f1565b610b27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1e9061376f565b60405180910390fd5b6005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610b6c816118fe565b610b7683836119fb565b505050565b60008054905090565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610bc257610bc1336118fe565b5b610bcd848484611b52565b50505050565b6000610bde83610fc9565b8210610c1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1690613801565b60405180910390fd5b6000610c29610b7b565b905060008060005b83811015610d81576000600360008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614610d2357806000015192505b8773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610d7357868403610d6a578195505050505050610dbd565b83806001019450505b508080600101915050610c31565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db490613893565b60405180910390fd5b92915050565b610dcb611ba1565b600260085403610e10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e07906138ff565b60405180910390fd5b600260088190555060003373ffffffffffffffffffffffffffffffffffffffff1647604051610e3e90613950565b60006040518083038185875af1925050503d8060008114610e7b576040519150601f19603f3d011682016040523d82523d6000602084013e610e80565b606091505b5050905080610ec4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebb906139b1565b60405180910390fd5b506001600881905550565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f1f57610f1e336118fe565b5b610f2a848484611c1f565b50505050565b610f38611ba1565b80600b8190555050565b600e5481565b6000610f52610b7b565b8210610f93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8a90613a43565b60405180910390fd5b819050919050565b610fa3611ba1565b8060138190555050565b6000610fb882611c7e565b600001519050919050565b60135481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611039576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103090613ad5565b60405180910390fd5b600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff169050919050565b6110b9611ba1565b6110c36000611e18565b565b600c5481565b6110d3611ba1565b6000600e549050600d54826110e6610b7b565b6110f09190613b24565b1115611131576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112890613ba4565b60405180910390fd5b81811015611174576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116b90613c10565b60405180910390fd5b81816111809190613c30565b600e819055506111903383611ede565b5050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6111c6611ba1565b8060118190555050565b6060600280546111df906136cc565b80601f016020809104026020016040519081016040528092919081815260200182805461120b906136cc565b80156112585780601f1061122d57610100808354040283529160200191611258565b820191906000526020600020905b81548152906001019060200180831161123b57829003601f168201915b5050505050905090565b600b5481565b6013546012541080156112bb5750601154601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054105b1561146e57601060009054906101000a900460ff1661130f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130690613cb0565b60405180910390fd5b600b54600b54826113209190613cd0565b61132a9190613c30565b34101561136c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136390613d5e565b60405180910390fd5b600d5481611378610b7b565b6113829190613b24565b11156113c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ba90613dca565b60405180910390fd5b600c54811115611408576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ff90613e36565b60405180910390fd5b601154601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550601154601260008282546114629190613b24565b925050819055506115aa565b601060009054906101000a900460ff166114bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114b490613cb0565b60405180910390fd5b600b54816114cb9190613cd0565b34101561150d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161150490613d5e565b60405180910390fd5b600d5481611519610b7b565b6115239190613b24565b1115611564576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155b90613dca565b60405180910390fd5b600c548111156115a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115a090613e36565b60405180910390fd5b5b6115b43382611ede565b50565b6115bf611ba1565b80600f90816115ce9190613ff8565b5050565b816115dc816118fe565b6115e68383611efc565b505050565b60115481565b6115f9611ba1565b80600c8190555050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461164157611640336118fe565b5b61164d858585856120bb565b5050505050565b6000600b54905090565b6060611669826118f1565b6116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169f9061413c565b60405180910390fd5b60006116b2612156565b905060008151116116d257604051806020016040528060008152506116fd565b806116dc846121e8565b6040516020016116ed9291906141e4565b6040516020818303038152906040525b915050919050565b60125481565b600d5481565b60146020528060005260406000206000915090505481565b611731611ba1565b601060009054906101000a900460ff1615601060006101000a81548160ff021916908315150217905550565b601060009054906101000a900460ff1681565b6000600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61180c611ba1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361187b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187290614285565b60405180910390fd5b61188481611e18565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6000805482109050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156119f8576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016119759291906142a5565b602060405180830381865afa158015611992573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b691906142e3565b6119f757806040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016119ee91906131a4565b60405180910390fd5b5b50565b813373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611a3957611a38336118fe565b5b6000611a4483610fad565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611ab4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aab90614382565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16611ad36122b6565b73ffffffffffffffffffffffffffffffffffffffff161480611b025750611b0181611afc6122b6565b611770565b5b611b41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3890614414565b60405180910390fd5b611b4c8484836122be565b50505050565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611b9057611b8f336118fe565b5b611b9b848484612370565b50505050565b611ba96122b6565b73ffffffffffffffffffffffffffffffffffffffff16611bc7611194565b73ffffffffffffffffffffffffffffffffffffffff1614611c1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c1490614480565b60405180910390fd5b565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611c5d57611c5c336118fe565b5b611c7884848460405180602001604052806000815250611603565b50505050565b611c86612f45565b611c8f826118f1565b611cce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc590614512565b60405180910390fd5b60008290505b60008110611dd7576000600360008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614611dc8578092505050611e13565b50808060019003915050611cd4565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0a906145a4565b60405180910390fd5b919050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611ef88282604051806020016040528060008152506128ae565b5050565b813373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611f3a57611f39336118fe565b5b611f426122b6565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611faf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa690614610565b60405180910390fd5b8160066000611fbc6122b6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508273ffffffffffffffffffffffffffffffffffffffff166120696122b6565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31846040516120ae9190613033565b60405180910390a3505050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146120f9576120f8336118fe565b5b612104858585612370565b612110858585856128c0565b61214f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612146906146a2565b60405180910390fd5b5050505050565b6060600f8054612165906136cc565b80601f0160208091040260200160405190810160405280929190818152602001828054612191906136cc565b80156121de5780601f106121b3576101008083540402835291602001916121de565b820191906000526020600020905b8154815290600101906020018083116121c157829003601f168201915b5050505050905090565b6060600060016121f784612a47565b01905060008167ffffffffffffffff81111561221657612215613359565b5b6040519080825280601f01601f1916602001820160405280156122485781602001600182028036833780820191505090505b509050600082602001820190505b6001156122ab578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161229f5761229e6146c2565b5b04945060008503612256575b819350505050919050565b600033905090565b826005600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600061237b82611c7e565b90506000816000015173ffffffffffffffffffffffffffffffffffffffff166123a26122b6565b73ffffffffffffffffffffffffffffffffffffffff1614806123fe57506123c76122b6565b73ffffffffffffffffffffffffffffffffffffffff166123e684610add565b73ffffffffffffffffffffffffffffffffffffffff16145b8061241a575061241982600001516124146122b6565b611770565b5b90508061245c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161245390614763565b60405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16146124ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124c5906147f5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361253d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161253490614887565b60405180910390fd5b61254a8585856001612b9a565b61255a60008484600001516122be565b6001600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a90046fffffffffffffffffffffffffffffffff160392506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506001600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550836003600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426003600085815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600184019050600073ffffffffffffffffffffffffffffffffffffffff166003600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361283e5761279d816118f1565b1561283d5782600001516003600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082602001516003600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b50828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46128a78585856001612ba0565b5050505050565b6128bb8383836001612ba6565b505050565b60006128e18473ffffffffffffffffffffffffffffffffffffffff16612f22565b15612a3a578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261290a6122b6565b8786866040518563ffffffff1660e01b815260040161292c94939291906148fc565b6020604051808303816000875af192505050801561296857506040513d601f19601f82011682018060405250810190612965919061495d565b60015b6129ea573d8060008114612998576040519150601f19603f3d011682016040523d82523d6000602084013e61299d565b606091505b5060008151036129e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129d9906146a2565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612a3f565b600190505b949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612aa5577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612a9b57612a9a6146c2565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612ae2576d04ee2d6d415b85acef81000000008381612ad857612ad76146c2565b5b0492506020810190505b662386f26fc100008310612b1157662386f26fc100008381612b0757612b066146c2565b5b0492506010810190505b6305f5e1008310612b3a576305f5e1008381612b3057612b2f6146c2565b5b0492506008810190505b6127108310612b5f576127108381612b5557612b546146c2565b5b0492506004810190505b60648310612b825760648381612b7857612b776146c2565b5b0492506002810190505b600a8310612b91576001810190505b80915050919050565b50505050565b50505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612c1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c12906149fc565b60405180910390fd5b60008403612c5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c5590614a8e565b60405180910390fd5b612c6b6000868387612b9a565b83600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160108282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550846003600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426003600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600081905060005b85811015612f0557818773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48315612ef057612eb060008884886128c0565b612eef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ee6906146a2565b60405180910390fd5b5b81806001019250508080600101915050612e39565b508060008190555050612f1b6000868387612ba0565b5050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fc881612f93565b8114612fd357600080fd5b50565b600081359050612fe581612fbf565b92915050565b60006020828403121561300157613000612f89565b5b600061300f84828501612fd6565b91505092915050565b60008115159050919050565b61302d81613018565b82525050565b60006020820190506130486000830184613024565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561308857808201518184015260208101905061306d565b60008484015250505050565b6000601f19601f8301169050919050565b60006130b08261304e565b6130ba8185613059565b93506130ca81856020860161306a565b6130d381613094565b840191505092915050565b600060208201905081810360008301526130f881846130a5565b905092915050565b6000819050919050565b61311381613100565b811461311e57600080fd5b50565b6000813590506131308161310a565b92915050565b60006020828403121561314c5761314b612f89565b5b600061315a84828501613121565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061318e82613163565b9050919050565b61319e81613183565b82525050565b60006020820190506131b96000830184613195565b92915050565b6131c881613183565b81146131d357600080fd5b50565b6000813590506131e5816131bf565b92915050565b6000806040838503121561320257613201612f89565b5b6000613210858286016131d6565b925050602061322185828601613121565b9150509250929050565b61323481613100565b82525050565b600060208201905061324f600083018461322b565b92915050565b60008060006060848603121561326e5761326d612f89565b5b600061327c868287016131d6565b935050602061328d868287016131d6565b925050604061329e86828701613121565b9150509250925092565b6000819050919050565b60006132cd6132c86132c384613163565b6132a8565b613163565b9050919050565b60006132df826132b2565b9050919050565b60006132f1826132d4565b9050919050565b613301816132e6565b82525050565b600060208201905061331c60008301846132f8565b92915050565b60006020828403121561333857613337612f89565b5b6000613346848285016131d6565b91505092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61339182613094565b810181811067ffffffffffffffff821117156133b0576133af613359565b5b80604052505050565b60006133c3612f7f565b90506133cf8282613388565b919050565b600067ffffffffffffffff8211156133ef576133ee613359565b5b6133f882613094565b9050602081019050919050565b82818337600083830152505050565b6000613427613422846133d4565b6133b9565b90508281526020810184848401111561344357613442613354565b5b61344e848285613405565b509392505050565b600082601f83011261346b5761346a61334f565b5b813561347b848260208601613414565b91505092915050565b60006020828403121561349a57613499612f89565b5b600082013567ffffffffffffffff8111156134b8576134b7612f8e565b5b6134c484828501613456565b91505092915050565b6134d681613018565b81146134e157600080fd5b50565b6000813590506134f3816134cd565b92915050565b600080604083850312156135105761350f612f89565b5b600061351e858286016131d6565b925050602061352f858286016134e4565b9150509250929050565b600067ffffffffffffffff82111561355457613553613359565b5b61355d82613094565b9050602081019050919050565b600061357d61357884613539565b6133b9565b90508281526020810184848401111561359957613598613354565b5b6135a4848285613405565b509392505050565b600082601f8301126135c1576135c061334f565b5b81356135d184826020860161356a565b91505092915050565b600080600080608085870312156135f4576135f3612f89565b5b6000613602878288016131d6565b9450506020613613878288016131d6565b935050604061362487828801613121565b925050606085013567ffffffffffffffff81111561364557613644612f8e565b5b613651878288016135ac565b91505092959194509250565b6000806040838503121561367457613673612f89565b5b6000613682858286016131d6565b9250506020613693858286016131d6565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806136e457607f821691505b6020821081036136f7576136f661369d565b5b50919050565b7f455243373231413a20617070726f76656420717565727920666f72206e6f6e6560008201527f78697374656e7420746f6b656e00000000000000000000000000000000000000602082015250565b6000613759602d83613059565b9150613764826136fd565b604082019050919050565b600060208201905081810360008301526137888161374c565b9050919050565b7f455243373231413a206f776e657220696e646578206f7574206f6620626f756e60008201527f6473000000000000000000000000000000000000000000000000000000000000602082015250565b60006137eb602283613059565b91506137f68261378f565b604082019050919050565b6000602082019050818103600083015261381a816137de565b9050919050565b7f455243373231413a20756e61626c6520746f2067657420746f6b656e206f662060008201527f6f776e657220627920696e646578000000000000000000000000000000000000602082015250565b600061387d602e83613059565b915061388882613821565b604082019050919050565b600060208201905081810360008301526138ac81613870565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006138e9601f83613059565b91506138f4826138b3565b602082019050919050565b60006020820190508181036000830152613918816138dc565b9050919050565b600081905092915050565b50565b600061393a60008361391f565b91506139458261392a565b600082019050919050565b600061395b8261392d565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b600061399b601083613059565b91506139a682613965565b602082019050919050565b600060208201905081810360008301526139ca8161398e565b9050919050565b7f455243373231413a20676c6f62616c20696e646578206f7574206f6620626f7560008201527f6e64730000000000000000000000000000000000000000000000000000000000602082015250565b6000613a2d602383613059565b9150613a38826139d1565b604082019050919050565b60006020820190508181036000830152613a5c81613a20565b9050919050565b7f455243373231413a2062616c616e636520717565727920666f7220746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b6000613abf602b83613059565b9150613aca82613a63565b604082019050919050565b60006020820190508181036000830152613aee81613ab2565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613b2f82613100565b9150613b3a83613100565b9250828201905080821115613b5257613b51613af5565b5b92915050565b7f4e6f206d6f726520737570706c7920746f206265206d696e7465640000000000600082015250565b6000613b8e601b83613059565b9150613b9982613b58565b602082019050919050565b60006020820190508181036000830152613bbd81613b81565b9050919050565b7f526573657276656420537570706c79204d696e74656400000000000000000000600082015250565b6000613bfa601683613059565b9150613c0582613bc4565b602082019050919050565b60006020820190508181036000830152613c2981613bed565b9050919050565b6000613c3b82613100565b9150613c4683613100565b9250828203905081811115613c5e57613c5d613af5565b5b92915050565b7f6e6f74206c697665207965740000000000000000000000000000000000000000600082015250565b6000613c9a600c83613059565b9150613ca582613c64565b602082019050919050565b60006020820190508181036000830152613cc981613c8d565b9050919050565b6000613cdb82613100565b9150613ce683613100565b9250828202613cf481613100565b91508282048414831517613d0b57613d0a613af5565b5b5092915050565b7f45746820416d6f756e7420496e76616c69640000000000000000000000000000600082015250565b6000613d48601283613059565b9150613d5382613d12565b602082019050919050565b60006020820190508181036000830152613d7781613d3b565b9050919050565b7f4e6f206d6f726520737570706c79000000000000000000000000000000000000600082015250565b6000613db4600e83613059565b9150613dbf82613d7e565b602082019050919050565b60006020820190508181036000830152613de381613da7565b9050919050565b7f4d61782070657220545820726561636865642e00000000000000000000000000600082015250565b6000613e20601383613059565b9150613e2b82613dea565b602082019050919050565b60006020820190508181036000830152613e4f81613e13565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613eb87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613e7b565b613ec28683613e7b565b95508019841693508086168417925050509392505050565b6000613ef5613ef0613eeb84613100565b6132a8565b613100565b9050919050565b6000819050919050565b613f0f83613eda565b613f23613f1b82613efc565b848454613e88565b825550505050565b600090565b613f38613f2b565b613f43818484613f06565b505050565b5b81811015613f6757613f5c600082613f30565b600181019050613f49565b5050565b601f821115613fac57613f7d81613e56565b613f8684613e6b565b81016020851015613f95578190505b613fa9613fa185613e6b565b830182613f48565b50505b505050565b600082821c905092915050565b6000613fcf60001984600802613fb1565b1980831691505092915050565b6000613fe88383613fbe565b9150826002028217905092915050565b6140018261304e565b67ffffffffffffffff81111561401a57614019613359565b5b61402482546136cc565b61402f828285613f6b565b600060209050601f8311600181146140625760008415614050578287015190505b61405a8582613fdc565b8655506140c2565b601f19841661407086613e56565b60005b8281101561409857848901518255600182019150602085019450602081019050614073565b868310156140b557848901516140b1601f891682613fbe565b8355505b6001600288020188555050505b505050505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000614126602f83613059565b9150614131826140ca565b604082019050919050565b6000602082019050818103600083015261415581614119565b9050919050565b600081905092915050565b60006141728261304e565b61417c818561415c565b935061418c81856020860161306a565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b60006141ce60058361415c565b91506141d982614198565b600582019050919050565b60006141f08285614167565b91506141fc8284614167565b9150614207826141c1565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061426f602683613059565b915061427a82614213565b604082019050919050565b6000602082019050818103600083015261429e81614262565b9050919050565b60006040820190506142ba6000830185613195565b6142c76020830184613195565b9392505050565b6000815190506142dd816134cd565b92915050565b6000602082840312156142f9576142f8612f89565b5b6000614307848285016142ce565b91505092915050565b7f455243373231413a20617070726f76616c20746f2063757272656e74206f776e60008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b600061436c602283613059565b915061437782614310565b604082019050919050565b6000602082019050818103600083015261439b8161435f565b9050919050565b7f455243373231413a20617070726f76652063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f76656420666f7220616c6c00000000000000602082015250565b60006143fe603983613059565b9150614409826143a2565b604082019050919050565b6000602082019050818103600083015261442d816143f1565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061446a602083613059565b915061447582614434565b602082019050919050565b600060208201905081810360008301526144998161445d565b9050919050565b7f455243373231413a206f776e657220717565727920666f72206e6f6e6578697360008201527f74656e7420746f6b656e00000000000000000000000000000000000000000000602082015250565b60006144fc602a83613059565b9150614507826144a0565b604082019050919050565b6000602082019050818103600083015261452b816144ef565b9050919050565b7f455243373231413a20756e61626c6520746f2064657465726d696e652074686560008201527f206f776e6572206f6620746f6b656e0000000000000000000000000000000000602082015250565b600061458e602f83613059565b915061459982614532565b604082019050919050565b600060208201905081810360008301526145bd81614581565b9050919050565b7f455243373231413a20617070726f766520746f2063616c6c6572000000000000600082015250565b60006145fa601a83613059565b9150614605826145c4565b602082019050919050565b60006020820190508181036000830152614629816145ed565b9050919050565b7f455243373231413a207472616e7366657220746f206e6f6e204552433732315260008201527f6563656976657220696d706c656d656e74657200000000000000000000000000602082015250565b600061468c603383613059565b915061469782614630565b604082019050919050565b600060208201905081810360008301526146bb8161467f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f455243373231413a207472616e736665722063616c6c6572206973206e6f742060008201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000602082015250565b600061474d603283613059565b9150614758826146f1565b604082019050919050565b6000602082019050818103600083015261477c81614740565b9050919050565b7f455243373231413a207472616e736665722066726f6d20696e636f727265637460008201527f206f776e65720000000000000000000000000000000000000000000000000000602082015250565b60006147df602683613059565b91506147ea82614783565b604082019050919050565b6000602082019050818103600083015261480e816147d2565b9050919050565b7f455243373231413a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000614871602583613059565b915061487c82614815565b604082019050919050565b600060208201905081810360008301526148a081614864565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006148ce826148a7565b6148d881856148b2565b93506148e881856020860161306a565b6148f181613094565b840191505092915050565b60006080820190506149116000830187613195565b61491e6020830186613195565b61492b604083018561322b565b818103606083015261493d81846148c3565b905095945050505050565b60008151905061495781612fbf565b92915050565b60006020828403121561497357614972612f89565b5b600061498184828501614948565b91505092915050565b7f455243373231413a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b60006149e6602183613059565b91506149f18261498a565b604082019050919050565b60006020820190508181036000830152614a15816149d9565b9050919050565b7f455243373231413a207175616e74697479206d7573742062652067726561746560008201527f72207468616e2030000000000000000000000000000000000000000000000000602082015250565b6000614a78602883613059565b9150614a8382614a1c565b604082019050919050565b60006020820190508181036000830152614aa781614a6b565b905091905056fea264697066735822122064144292b69dd7a2dec2b80ff458380abed66226cde58328f59154a2084dac1564736f6c63430008130033
Deployed Bytecode
0x6080604052600436106102305760003560e01c80638c74bf0e1161012e578063b88d4fde116100ab578063e02a61421161006f578063e02a61421461081c578063e797ec1b14610859578063e8656fcc14610870578063e985e9c51461089b578063f2fde38b146108d857610230565b8063b88d4fde14610735578063b94116011461075e578063c87b56dd14610789578063d10a1a2b146107c6578063d5abeb01146107f157610230565b8063a0712d68116100f2578063a0712d6814610673578063a0bcfc7f1461068f578063a22cb465146106b8578063a7027357146106e1578063b0c2b5611461070c57610230565b80638c74bf0e146105a05780638da5cb5b146105c95780639254d4f4146105f457806395d89b411461061d578063a035b1fe1461064857610230565b806342842e0e116101bc5780636352211e116101805780636352211e146104b95780636bf67d71146104f657806370a0823114610521578063715018a61461055e5780637437681e1461057557610230565b806342842e0e146103d657806344a0d68a146103ff57806344d19d2b146104285780634f6ccce714610453578063536c35761461049057610230565b806318160ddd1161020357806318160ddd1461030357806323b872dd1461032e5780632f745c59146103575780633ccfd60b1461039457806341f43434146103ab57610230565b806301ffc9a71461023557806306fdde0314610272578063081812fc1461029d578063095ea7b3146102da575b600080fd5b34801561024157600080fd5b5061025c60048036038101906102579190612feb565b610901565b6040516102699190613033565b60405180910390f35b34801561027e57600080fd5b50610287610a4b565b60405161029491906130de565b60405180910390f35b3480156102a957600080fd5b506102c460048036038101906102bf9190613136565b610add565b6040516102d191906131a4565b60405180910390f35b3480156102e657600080fd5b5061030160048036038101906102fc91906131eb565b610b62565b005b34801561030f57600080fd5b50610318610b7b565b604051610325919061323a565b60405180910390f35b34801561033a57600080fd5b5061035560048036038101906103509190613255565b610b84565b005b34801561036357600080fd5b5061037e600480360381019061037991906131eb565b610bd3565b60405161038b919061323a565b60405180910390f35b3480156103a057600080fd5b506103a9610dc3565b005b3480156103b757600080fd5b506103c0610ecf565b6040516103cd9190613307565b60405180910390f35b3480156103e257600080fd5b506103fd60048036038101906103f89190613255565b610ee1565b005b34801561040b57600080fd5b5061042660048036038101906104219190613136565b610f30565b005b34801561043457600080fd5b5061043d610f42565b60405161044a919061323a565b60405180910390f35b34801561045f57600080fd5b5061047a60048036038101906104759190613136565b610f48565b604051610487919061323a565b60405180910390f35b34801561049c57600080fd5b506104b760048036038101906104b29190613136565b610f9b565b005b3480156104c557600080fd5b506104e060048036038101906104db9190613136565b610fad565b6040516104ed91906131a4565b60405180910390f35b34801561050257600080fd5b5061050b610fc3565b604051610518919061323a565b60405180910390f35b34801561052d57600080fd5b5061054860048036038101906105439190613322565b610fc9565b604051610555919061323a565b60405180910390f35b34801561056a57600080fd5b506105736110b1565b005b34801561058157600080fd5b5061058a6110c5565b604051610597919061323a565b60405180910390f35b3480156105ac57600080fd5b506105c760048036038101906105c29190613136565b6110cb565b005b3480156105d557600080fd5b506105de611194565b6040516105eb91906131a4565b60405180910390f35b34801561060057600080fd5b5061061b60048036038101906106169190613136565b6111be565b005b34801561062957600080fd5b506106326111d0565b60405161063f91906130de565b60405180910390f35b34801561065457600080fd5b5061065d611262565b60405161066a919061323a565b60405180910390f35b61068d60048036038101906106889190613136565b611268565b005b34801561069b57600080fd5b506106b660048036038101906106b19190613484565b6115b7565b005b3480156106c457600080fd5b506106df60048036038101906106da91906134f9565b6115d2565b005b3480156106ed57600080fd5b506106f66115eb565b604051610703919061323a565b60405180910390f35b34801561071857600080fd5b50610733600480360381019061072e9190613136565b6115f1565b005b34801561074157600080fd5b5061075c600480360381019061075791906135da565b611603565b005b34801561076a57600080fd5b50610773611654565b604051610780919061323a565b60405180910390f35b34801561079557600080fd5b506107b060048036038101906107ab9190613136565b61165e565b6040516107bd91906130de565b60405180910390f35b3480156107d257600080fd5b506107db611705565b6040516107e8919061323a565b60405180910390f35b3480156107fd57600080fd5b5061080661170b565b604051610813919061323a565b60405180910390f35b34801561082857600080fd5b50610843600480360381019061083e9190613322565b611711565b604051610850919061323a565b60405180910390f35b34801561086557600080fd5b5061086e611729565b005b34801561087c57600080fd5b5061088561175d565b6040516108929190613033565b60405180910390f35b3480156108a757600080fd5b506108c260048036038101906108bd919061365d565b611770565b6040516108cf9190613033565b60405180910390f35b3480156108e457600080fd5b506108ff60048036038101906108fa9190613322565b611804565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109cc57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a3457507f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a445750610a4382611887565b5b9050919050565b606060018054610a5a906136cc565b80601f0160208091040260200160405190810160405280929190818152602001828054610a86906136cc565b8015610ad35780601f10610aa857610100808354040283529160200191610ad3565b820191906000526020600020905b815481529060010190602001808311610ab657829003601f168201915b5050505050905090565b6000610ae8826118f1565b610b27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1e9061376f565b60405180910390fd5b6005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610b6c816118fe565b610b7683836119fb565b505050565b60008054905090565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610bc257610bc1336118fe565b5b610bcd848484611b52565b50505050565b6000610bde83610fc9565b8210610c1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1690613801565b60405180910390fd5b6000610c29610b7b565b905060008060005b83811015610d81576000600360008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614610d2357806000015192505b8773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610d7357868403610d6a578195505050505050610dbd565b83806001019450505b508080600101915050610c31565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db490613893565b60405180910390fd5b92915050565b610dcb611ba1565b600260085403610e10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e07906138ff565b60405180910390fd5b600260088190555060003373ffffffffffffffffffffffffffffffffffffffff1647604051610e3e90613950565b60006040518083038185875af1925050503d8060008114610e7b576040519150601f19603f3d011682016040523d82523d6000602084013e610e80565b606091505b5050905080610ec4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebb906139b1565b60405180910390fd5b506001600881905550565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f1f57610f1e336118fe565b5b610f2a848484611c1f565b50505050565b610f38611ba1565b80600b8190555050565b600e5481565b6000610f52610b7b565b8210610f93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8a90613a43565b60405180910390fd5b819050919050565b610fa3611ba1565b8060138190555050565b6000610fb882611c7e565b600001519050919050565b60135481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611039576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103090613ad5565b60405180910390fd5b600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff169050919050565b6110b9611ba1565b6110c36000611e18565b565b600c5481565b6110d3611ba1565b6000600e549050600d54826110e6610b7b565b6110f09190613b24565b1115611131576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112890613ba4565b60405180910390fd5b81811015611174576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116b90613c10565b60405180910390fd5b81816111809190613c30565b600e819055506111903383611ede565b5050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6111c6611ba1565b8060118190555050565b6060600280546111df906136cc565b80601f016020809104026020016040519081016040528092919081815260200182805461120b906136cc565b80156112585780601f1061122d57610100808354040283529160200191611258565b820191906000526020600020905b81548152906001019060200180831161123b57829003601f168201915b5050505050905090565b600b5481565b6013546012541080156112bb5750601154601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054105b1561146e57601060009054906101000a900460ff1661130f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130690613cb0565b60405180910390fd5b600b54600b54826113209190613cd0565b61132a9190613c30565b34101561136c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136390613d5e565b60405180910390fd5b600d5481611378610b7b565b6113829190613b24565b11156113c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ba90613dca565b60405180910390fd5b600c54811115611408576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ff90613e36565b60405180910390fd5b601154601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550601154601260008282546114629190613b24565b925050819055506115aa565b601060009054906101000a900460ff166114bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114b490613cb0565b60405180910390fd5b600b54816114cb9190613cd0565b34101561150d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161150490613d5e565b60405180910390fd5b600d5481611519610b7b565b6115239190613b24565b1115611564576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155b90613dca565b60405180910390fd5b600c548111156115a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115a090613e36565b60405180910390fd5b5b6115b43382611ede565b50565b6115bf611ba1565b80600f90816115ce9190613ff8565b5050565b816115dc816118fe565b6115e68383611efc565b505050565b60115481565b6115f9611ba1565b80600c8190555050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461164157611640336118fe565b5b61164d858585856120bb565b5050505050565b6000600b54905090565b6060611669826118f1565b6116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169f9061413c565b60405180910390fd5b60006116b2612156565b905060008151116116d257604051806020016040528060008152506116fd565b806116dc846121e8565b6040516020016116ed9291906141e4565b6040516020818303038152906040525b915050919050565b60125481565b600d5481565b60146020528060005260406000206000915090505481565b611731611ba1565b601060009054906101000a900460ff1615601060006101000a81548160ff021916908315150217905550565b601060009054906101000a900460ff1681565b6000600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61180c611ba1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361187b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187290614285565b60405180910390fd5b61188481611e18565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6000805482109050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156119f8576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016119759291906142a5565b602060405180830381865afa158015611992573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b691906142e3565b6119f757806040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016119ee91906131a4565b60405180910390fd5b5b50565b813373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611a3957611a38336118fe565b5b6000611a4483610fad565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611ab4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aab90614382565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16611ad36122b6565b73ffffffffffffffffffffffffffffffffffffffff161480611b025750611b0181611afc6122b6565b611770565b5b611b41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3890614414565b60405180910390fd5b611b4c8484836122be565b50505050565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611b9057611b8f336118fe565b5b611b9b848484612370565b50505050565b611ba96122b6565b73ffffffffffffffffffffffffffffffffffffffff16611bc7611194565b73ffffffffffffffffffffffffffffffffffffffff1614611c1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c1490614480565b60405180910390fd5b565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611c5d57611c5c336118fe565b5b611c7884848460405180602001604052806000815250611603565b50505050565b611c86612f45565b611c8f826118f1565b611cce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc590614512565b60405180910390fd5b60008290505b60008110611dd7576000600360008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614611dc8578092505050611e13565b50808060019003915050611cd4565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0a906145a4565b60405180910390fd5b919050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611ef88282604051806020016040528060008152506128ae565b5050565b813373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611f3a57611f39336118fe565b5b611f426122b6565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611faf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa690614610565b60405180910390fd5b8160066000611fbc6122b6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508273ffffffffffffffffffffffffffffffffffffffff166120696122b6565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31846040516120ae9190613033565b60405180910390a3505050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146120f9576120f8336118fe565b5b612104858585612370565b612110858585856128c0565b61214f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612146906146a2565b60405180910390fd5b5050505050565b6060600f8054612165906136cc565b80601f0160208091040260200160405190810160405280929190818152602001828054612191906136cc565b80156121de5780601f106121b3576101008083540402835291602001916121de565b820191906000526020600020905b8154815290600101906020018083116121c157829003601f168201915b5050505050905090565b6060600060016121f784612a47565b01905060008167ffffffffffffffff81111561221657612215613359565b5b6040519080825280601f01601f1916602001820160405280156122485781602001600182028036833780820191505090505b509050600082602001820190505b6001156122ab578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161229f5761229e6146c2565b5b04945060008503612256575b819350505050919050565b600033905090565b826005600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600061237b82611c7e565b90506000816000015173ffffffffffffffffffffffffffffffffffffffff166123a26122b6565b73ffffffffffffffffffffffffffffffffffffffff1614806123fe57506123c76122b6565b73ffffffffffffffffffffffffffffffffffffffff166123e684610add565b73ffffffffffffffffffffffffffffffffffffffff16145b8061241a575061241982600001516124146122b6565b611770565b5b90508061245c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161245390614763565b60405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16146124ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124c5906147f5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361253d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161253490614887565b60405180910390fd5b61254a8585856001612b9a565b61255a60008484600001516122be565b6001600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a90046fffffffffffffffffffffffffffffffff160392506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506001600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550836003600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426003600085815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600184019050600073ffffffffffffffffffffffffffffffffffffffff166003600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361283e5761279d816118f1565b1561283d5782600001516003600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082602001516003600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b50828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46128a78585856001612ba0565b5050505050565b6128bb8383836001612ba6565b505050565b60006128e18473ffffffffffffffffffffffffffffffffffffffff16612f22565b15612a3a578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261290a6122b6565b8786866040518563ffffffff1660e01b815260040161292c94939291906148fc565b6020604051808303816000875af192505050801561296857506040513d601f19601f82011682018060405250810190612965919061495d565b60015b6129ea573d8060008114612998576040519150601f19603f3d011682016040523d82523d6000602084013e61299d565b606091505b5060008151036129e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129d9906146a2565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612a3f565b600190505b949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612aa5577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612a9b57612a9a6146c2565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612ae2576d04ee2d6d415b85acef81000000008381612ad857612ad76146c2565b5b0492506020810190505b662386f26fc100008310612b1157662386f26fc100008381612b0757612b066146c2565b5b0492506010810190505b6305f5e1008310612b3a576305f5e1008381612b3057612b2f6146c2565b5b0492506008810190505b6127108310612b5f576127108381612b5557612b546146c2565b5b0492506004810190505b60648310612b825760648381612b7857612b776146c2565b5b0492506002810190505b600a8310612b91576001810190505b80915050919050565b50505050565b50505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612c1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c12906149fc565b60405180910390fd5b60008403612c5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c5590614a8e565b60405180910390fd5b612c6b6000868387612b9a565b83600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160108282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550846003600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426003600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600081905060005b85811015612f0557818773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48315612ef057612eb060008884886128c0565b612eef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ee6906146a2565b60405180910390fd5b5b81806001019250508080600101915050612e39565b508060008190555050612f1b6000868387612ba0565b5050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fc881612f93565b8114612fd357600080fd5b50565b600081359050612fe581612fbf565b92915050565b60006020828403121561300157613000612f89565b5b600061300f84828501612fd6565b91505092915050565b60008115159050919050565b61302d81613018565b82525050565b60006020820190506130486000830184613024565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561308857808201518184015260208101905061306d565b60008484015250505050565b6000601f19601f8301169050919050565b60006130b08261304e565b6130ba8185613059565b93506130ca81856020860161306a565b6130d381613094565b840191505092915050565b600060208201905081810360008301526130f881846130a5565b905092915050565b6000819050919050565b61311381613100565b811461311e57600080fd5b50565b6000813590506131308161310a565b92915050565b60006020828403121561314c5761314b612f89565b5b600061315a84828501613121565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061318e82613163565b9050919050565b61319e81613183565b82525050565b60006020820190506131b96000830184613195565b92915050565b6131c881613183565b81146131d357600080fd5b50565b6000813590506131e5816131bf565b92915050565b6000806040838503121561320257613201612f89565b5b6000613210858286016131d6565b925050602061322185828601613121565b9150509250929050565b61323481613100565b82525050565b600060208201905061324f600083018461322b565b92915050565b60008060006060848603121561326e5761326d612f89565b5b600061327c868287016131d6565b935050602061328d868287016131d6565b925050604061329e86828701613121565b9150509250925092565b6000819050919050565b60006132cd6132c86132c384613163565b6132a8565b613163565b9050919050565b60006132df826132b2565b9050919050565b60006132f1826132d4565b9050919050565b613301816132e6565b82525050565b600060208201905061331c60008301846132f8565b92915050565b60006020828403121561333857613337612f89565b5b6000613346848285016131d6565b91505092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61339182613094565b810181811067ffffffffffffffff821117156133b0576133af613359565b5b80604052505050565b60006133c3612f7f565b90506133cf8282613388565b919050565b600067ffffffffffffffff8211156133ef576133ee613359565b5b6133f882613094565b9050602081019050919050565b82818337600083830152505050565b6000613427613422846133d4565b6133b9565b90508281526020810184848401111561344357613442613354565b5b61344e848285613405565b509392505050565b600082601f83011261346b5761346a61334f565b5b813561347b848260208601613414565b91505092915050565b60006020828403121561349a57613499612f89565b5b600082013567ffffffffffffffff8111156134b8576134b7612f8e565b5b6134c484828501613456565b91505092915050565b6134d681613018565b81146134e157600080fd5b50565b6000813590506134f3816134cd565b92915050565b600080604083850312156135105761350f612f89565b5b600061351e858286016131d6565b925050602061352f858286016134e4565b9150509250929050565b600067ffffffffffffffff82111561355457613553613359565b5b61355d82613094565b9050602081019050919050565b600061357d61357884613539565b6133b9565b90508281526020810184848401111561359957613598613354565b5b6135a4848285613405565b509392505050565b600082601f8301126135c1576135c061334f565b5b81356135d184826020860161356a565b91505092915050565b600080600080608085870312156135f4576135f3612f89565b5b6000613602878288016131d6565b9450506020613613878288016131d6565b935050604061362487828801613121565b925050606085013567ffffffffffffffff81111561364557613644612f8e565b5b613651878288016135ac565b91505092959194509250565b6000806040838503121561367457613673612f89565b5b6000613682858286016131d6565b9250506020613693858286016131d6565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806136e457607f821691505b6020821081036136f7576136f661369d565b5b50919050565b7f455243373231413a20617070726f76656420717565727920666f72206e6f6e6560008201527f78697374656e7420746f6b656e00000000000000000000000000000000000000602082015250565b6000613759602d83613059565b9150613764826136fd565b604082019050919050565b600060208201905081810360008301526137888161374c565b9050919050565b7f455243373231413a206f776e657220696e646578206f7574206f6620626f756e60008201527f6473000000000000000000000000000000000000000000000000000000000000602082015250565b60006137eb602283613059565b91506137f68261378f565b604082019050919050565b6000602082019050818103600083015261381a816137de565b9050919050565b7f455243373231413a20756e61626c6520746f2067657420746f6b656e206f662060008201527f6f776e657220627920696e646578000000000000000000000000000000000000602082015250565b600061387d602e83613059565b915061388882613821565b604082019050919050565b600060208201905081810360008301526138ac81613870565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006138e9601f83613059565b91506138f4826138b3565b602082019050919050565b60006020820190508181036000830152613918816138dc565b9050919050565b600081905092915050565b50565b600061393a60008361391f565b91506139458261392a565b600082019050919050565b600061395b8261392d565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b600061399b601083613059565b91506139a682613965565b602082019050919050565b600060208201905081810360008301526139ca8161398e565b9050919050565b7f455243373231413a20676c6f62616c20696e646578206f7574206f6620626f7560008201527f6e64730000000000000000000000000000000000000000000000000000000000602082015250565b6000613a2d602383613059565b9150613a38826139d1565b604082019050919050565b60006020820190508181036000830152613a5c81613a20565b9050919050565b7f455243373231413a2062616c616e636520717565727920666f7220746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b6000613abf602b83613059565b9150613aca82613a63565b604082019050919050565b60006020820190508181036000830152613aee81613ab2565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613b2f82613100565b9150613b3a83613100565b9250828201905080821115613b5257613b51613af5565b5b92915050565b7f4e6f206d6f726520737570706c7920746f206265206d696e7465640000000000600082015250565b6000613b8e601b83613059565b9150613b9982613b58565b602082019050919050565b60006020820190508181036000830152613bbd81613b81565b9050919050565b7f526573657276656420537570706c79204d696e74656400000000000000000000600082015250565b6000613bfa601683613059565b9150613c0582613bc4565b602082019050919050565b60006020820190508181036000830152613c2981613bed565b9050919050565b6000613c3b82613100565b9150613c4683613100565b9250828203905081811115613c5e57613c5d613af5565b5b92915050565b7f6e6f74206c697665207965740000000000000000000000000000000000000000600082015250565b6000613c9a600c83613059565b9150613ca582613c64565b602082019050919050565b60006020820190508181036000830152613cc981613c8d565b9050919050565b6000613cdb82613100565b9150613ce683613100565b9250828202613cf481613100565b91508282048414831517613d0b57613d0a613af5565b5b5092915050565b7f45746820416d6f756e7420496e76616c69640000000000000000000000000000600082015250565b6000613d48601283613059565b9150613d5382613d12565b602082019050919050565b60006020820190508181036000830152613d7781613d3b565b9050919050565b7f4e6f206d6f726520737570706c79000000000000000000000000000000000000600082015250565b6000613db4600e83613059565b9150613dbf82613d7e565b602082019050919050565b60006020820190508181036000830152613de381613da7565b9050919050565b7f4d61782070657220545820726561636865642e00000000000000000000000000600082015250565b6000613e20601383613059565b9150613e2b82613dea565b602082019050919050565b60006020820190508181036000830152613e4f81613e13565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613eb87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613e7b565b613ec28683613e7b565b95508019841693508086168417925050509392505050565b6000613ef5613ef0613eeb84613100565b6132a8565b613100565b9050919050565b6000819050919050565b613f0f83613eda565b613f23613f1b82613efc565b848454613e88565b825550505050565b600090565b613f38613f2b565b613f43818484613f06565b505050565b5b81811015613f6757613f5c600082613f30565b600181019050613f49565b5050565b601f821115613fac57613f7d81613e56565b613f8684613e6b565b81016020851015613f95578190505b613fa9613fa185613e6b565b830182613f48565b50505b505050565b600082821c905092915050565b6000613fcf60001984600802613fb1565b1980831691505092915050565b6000613fe88383613fbe565b9150826002028217905092915050565b6140018261304e565b67ffffffffffffffff81111561401a57614019613359565b5b61402482546136cc565b61402f828285613f6b565b600060209050601f8311600181146140625760008415614050578287015190505b61405a8582613fdc565b8655506140c2565b601f19841661407086613e56565b60005b8281101561409857848901518255600182019150602085019450602081019050614073565b868310156140b557848901516140b1601f891682613fbe565b8355505b6001600288020188555050505b505050505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000614126602f83613059565b9150614131826140ca565b604082019050919050565b6000602082019050818103600083015261415581614119565b9050919050565b600081905092915050565b60006141728261304e565b61417c818561415c565b935061418c81856020860161306a565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b60006141ce60058361415c565b91506141d982614198565b600582019050919050565b60006141f08285614167565b91506141fc8284614167565b9150614207826141c1565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061426f602683613059565b915061427a82614213565b604082019050919050565b6000602082019050818103600083015261429e81614262565b9050919050565b60006040820190506142ba6000830185613195565b6142c76020830184613195565b9392505050565b6000815190506142dd816134cd565b92915050565b6000602082840312156142f9576142f8612f89565b5b6000614307848285016142ce565b91505092915050565b7f455243373231413a20617070726f76616c20746f2063757272656e74206f776e60008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b600061436c602283613059565b915061437782614310565b604082019050919050565b6000602082019050818103600083015261439b8161435f565b9050919050565b7f455243373231413a20617070726f76652063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f76656420666f7220616c6c00000000000000602082015250565b60006143fe603983613059565b9150614409826143a2565b604082019050919050565b6000602082019050818103600083015261442d816143f1565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061446a602083613059565b915061447582614434565b602082019050919050565b600060208201905081810360008301526144998161445d565b9050919050565b7f455243373231413a206f776e657220717565727920666f72206e6f6e6578697360008201527f74656e7420746f6b656e00000000000000000000000000000000000000000000602082015250565b60006144fc602a83613059565b9150614507826144a0565b604082019050919050565b6000602082019050818103600083015261452b816144ef565b9050919050565b7f455243373231413a20756e61626c6520746f2064657465726d696e652074686560008201527f206f776e6572206f6620746f6b656e0000000000000000000000000000000000602082015250565b600061458e602f83613059565b915061459982614532565b604082019050919050565b600060208201905081810360008301526145bd81614581565b9050919050565b7f455243373231413a20617070726f766520746f2063616c6c6572000000000000600082015250565b60006145fa601a83613059565b9150614605826145c4565b602082019050919050565b60006020820190508181036000830152614629816145ed565b9050919050565b7f455243373231413a207472616e7366657220746f206e6f6e204552433732315260008201527f6563656976657220696d706c656d656e74657200000000000000000000000000602082015250565b600061468c603383613059565b915061469782614630565b604082019050919050565b600060208201905081810360008301526146bb8161467f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f455243373231413a207472616e736665722063616c6c6572206973206e6f742060008201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000602082015250565b600061474d603283613059565b9150614758826146f1565b604082019050919050565b6000602082019050818103600083015261477c81614740565b9050919050565b7f455243373231413a207472616e736665722066726f6d20696e636f727265637460008201527f206f776e65720000000000000000000000000000000000000000000000000000602082015250565b60006147df602683613059565b91506147ea82614783565b604082019050919050565b6000602082019050818103600083015261480e816147d2565b9050919050565b7f455243373231413a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000614871602583613059565b915061487c82614815565b604082019050919050565b600060208201905081810360008301526148a081614864565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006148ce826148a7565b6148d881856148b2565b93506148e881856020860161306a565b6148f181613094565b840191505092915050565b60006080820190506149116000830187613195565b61491e6020830186613195565b61492b604083018561322b565b818103606083015261493d81846148c3565b905095945050505050565b60008151905061495781612fbf565b92915050565b60006020828403121561497357614972612f89565b5b600061498184828501614948565b91505092915050565b7f455243373231413a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b60006149e6602183613059565b91506149f18261498a565b604082019050919050565b60006020820190508181036000830152614a15816149d9565b9050919050565b7f455243373231413a207175616e74697479206d7573742062652067726561746560008201527f72207468616e2030000000000000000000000000000000000000000000000000602082015250565b6000614a78602883613059565b9150614a8382614a1c565b604082019050919050565b60006020820190508181036000830152614aa781614a6b565b905091905056fea264697066735822122064144292b69dd7a2dec2b80ff458380abed66226cde58328f59154a2084dac1564736f6c63430008130033
Deployed Bytecode Sourcemap
100822:4309:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80500:372;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82023:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83143:214;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104191:157;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;79301:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104356:163;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;79604:886;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104942:186;;;;;;;;;;;;;:::i;:::-;;40348:143;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104527:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103452:85;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101128:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;79409:187;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103732:129;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81891:124;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101312:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80880:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90948:103;;;;;;;;;;;;;:::i;:::-;;101042:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102890:360;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;90300:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103869:130;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82131:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100990:45;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101992:890;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103346:98;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;104007:176;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101229:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103638:86;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;104706:228;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103545:84;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101473:395;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101277:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101082:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101364:52;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103258:81;;;;;;;;;;;;;:::i;:::-;;101198:22;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83699:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91206:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80500:372;80602:4;80654:25;80639:40;;;:11;:40;;;;:105;;;;80711:33;80696:48;;;:11;:48;;;;80639:105;:172;;;;80776:35;80761:50;;;:11;:50;;;;80639:172;:225;;;;80828:36;80852:11;80828:23;:36::i;:::-;80639:225;80619:245;;80500:372;;;:::o;82023:100::-;82077:13;82110:5;82103:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82023:100;:::o;83143:214::-;83211:7;83239:16;83247:7;83239;:16::i;:::-;83231:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;83325:15;:24;83341:7;83325:24;;;;;;;;;;;;;;;;;;;;;83318:31;;83143:214;;;:::o;104191:157::-;104287:8;41869:30;41890:8;41869:20;:30::i;:::-;104308:32:::1;104322:8;104332:7;104308:13;:32::i;:::-;104191:157:::0;;;:::o;79301:100::-;79354:7;79381:12;;79374:19;;79301:100;:::o;104356:163::-;104457:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;104474:37:::1;104493:4;104499:2;104503:7;104474:18;:37::i;:::-;104356:163:::0;;;;:::o;79604:886::-;79693:7;79729:16;79739:5;79729:9;:16::i;:::-;79721:5;:24;79713:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;79795:22;79820:13;:11;:13::i;:::-;79795:38;;79844:19;79874:25;79942:9;79937:466;79957:14;79953:1;:18;79937:466;;;79997:31;80031:11;:14;80043:1;80031:14;;;;;;;;;;;79997:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80094:1;80068:28;;:9;:14;;;:28;;;80064:111;;80141:9;:14;;;80121:34;;80064:111;80218:5;80197:26;;:17;:26;;;80193:195;;80267:5;80252:11;:20;80248:85;;80308:1;80301:8;;;;;;;;;80248:85;80355:13;;;;;;;80193:195;79978:425;79973:3;;;;;;;79937:466;;;;80426:56;;;;;;;;;;:::i;:::-;;;;;;;;79604:886;;;;;:::o;104942:186::-;90186:13;:11;:13::i;:::-;76983:1:::1;77133:7;;:19:::0;77125:63:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;76983:1;77201:7;:18;;;;105006:12:::2;105024:10;:15;;105047:21;105024:49;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105005:68;;;105092:7;105084:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;104994:134;76939:1:::1;77246:7;:22;;;;104942:186::o:0;40348:143::-;40448:42;40348:143;:::o;104527:171::-;104632:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;104649:41:::1;104672:4;104678:2;104682:7;104649:22;:41::i;:::-;104527:171:::0;;;;:::o;103452:85::-;90186:13;:11;:13::i;:::-;103523:6:::1;103515:5;:14;;;;103452:85:::0;:::o;101128:34::-;;;;:::o;79409:187::-;79476:7;79512:13;:11;:13::i;:::-;79504:5;:21;79496:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;79583:5;79576:12;;79409:187;;;:::o;103732:129::-;90186:13;:11;:13::i;:::-;103840::::1;103819:18;:34;;;;103732:129:::0;:::o;81891:124::-;81955:7;81982:20;81994:7;81982:11;:20::i;:::-;:25;;;81975:32;;81891:124;;;:::o;101312:39::-;;;;:::o;80880:221::-;80944:7;80989:1;80972:19;;:5;:19;;;80964:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;81065:12;:19;81078:5;81065:19;;;;;;;;;;;;;;;:27;;;;;;;;;;;;81057:36;;81050:43;;80880:221;;;:::o;90948:103::-;90186:13;:11;:13::i;:::-;91013:30:::1;91040:1;91013:18;:30::i;:::-;90948:103::o:0;101042:33::-;;;;:::o;102890:360::-;90186:13;:11;:13::i;:::-;102963:17:::1;102983:14;;102963:34;;103044:9;;103034:6;103018:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;103010:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;103117:6;103104:9;:19;;103096:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;103196:6;103184:9;:18;;;;:::i;:::-;103167:14;:35;;;;103213:29;103223:10;103235:6;103213:9;:29::i;:::-;102952:298;102890:360:::0;:::o;90300:87::-;90346:7;90373:6;;;;;;;;;;;90366:13;;90300:87;:::o;103869:130::-;90186:13;:11;:13::i;:::-;103974:17:::1;103955:16;:36;;;;103869:130:::0;:::o;82131:104::-;82187:13;82220:7;82213:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82131:104;:::o;100990:45::-;;;;:::o;101992:890::-;102078:18;;102065:10;;:31;102064:87;;;;;102134:16;;102102:17;:29;102120:10;102102:29;;;;;;;;;;;;;;;;:48;102064:87;102060:773;;;102177:8;;;;;;;;;;;102169:33;;;;;;;;;;;;:::i;:::-;;;;;;;;;102257:5;;102248;;102239:6;:14;;;;:::i;:::-;102238:24;;;;:::i;:::-;102225:9;:37;;102217:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;102334:9;;102324:6;102308:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;102300:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;102395:5;;102385:6;:15;;102377:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;102471:16;;102439:17;:29;102457:10;102439:29;;;;;;;;;;;;;;;:48;;;;102516:16;;102502:10;;:30;;;;;;;:::i;:::-;;;;;;;;102060:773;;;102584:8;;;;;;;;;;;102576:33;;;;;;;;;;;;:::i;:::-;;;;;;;;;102654:5;;102645:6;:14;;;;:::i;:::-;102632:9;:27;;102624:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;102731:9;;102721:6;102705:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;102697:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;102792:5;;102782:6;:15;;102774:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;102060:773;102845:29;102855:10;102867:6;102845:9;:29::i;:::-;101992:890;:::o;103346:98::-;90186:13;:11;:13::i;:::-;103428:8:::1;103418:7;:18;;;;;;:::i;:::-;;103346:98:::0;:::o;104007:176::-;104111:8;41869:30;41890:8;41869:20;:30::i;:::-;104132:43:::1;104156:8;104166;104132:23;:43::i;:::-;104007:176:::0;;;:::o;101229:41::-;;;;:::o;103638:86::-;90186:13;:11;:13::i;:::-;103710:6:::1;103702:5;:14;;;;103638:86:::0;:::o;104706:228::-;104857:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;104879:47:::1;104902:4;104908:2;104912:7;104921:4;104879:22;:47::i;:::-;104706:228:::0;;;;;:::o;103545:84::-;103589:7;103616:5;;103609:12;;103545:84;:::o;101473:395::-;101547:13;101581:17;101589:8;101581:7;:17::i;:::-;101573:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;101660:28;101691:10;:8;:10::i;:::-;101660:41;;101750:1;101725:14;101719:28;:32;:141;;;;;;;;;;;;;;;;;101791:14;101806:26;101823:8;101806:16;:26::i;:::-;101774:67;;;;;;;;;:::i;:::-;;;;;;;;;;;;;101719:141;101712:148;;;101473:395;;;:::o;101277:28::-;;;;:::o;101082:39::-;;;;:::o;101364:52::-;;;;;;;;;;;;;;;;;:::o;103258:81::-;90186:13;:11;:13::i;:::-;103323:8:::1;;;;;;;;;;;103322:9;103311:8;;:20;;;;;;;;;;;;;;;;;;103258:81::o:0;101198:22::-;;;;;;;;;;;;;:::o;83699:164::-;83796:4;83820:18;:25;83839:5;83820:25;;;;;;;;;;;;;;;:35;83846:8;83820:35;;;;;;;;;;;;;;;;;;;;;;;;;83813:42;;83699:164;;;;:::o;91206:201::-;90186:13;:11;:13::i;:::-;91315:1:::1;91295:22;;:8;:22;;::::0;91287:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;91371:28;91390:8;91371:18;:28::i;:::-;91206:201:::0;:::o;70370:157::-;70455:4;70494:25;70479:40;;;:11;:40;;;;70472:47;;70370:157;;;:::o;84689:111::-;84746:4;84780:12;;84770:7;:22;84763:29;;84689:111;;;:::o;41927:419::-;42166:1;40448:42;42118:45;;;:49;42114:225;;;40448:42;42189;;;42240:4;42247:8;42189:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42184:144;;42303:8;42284:28;;;;;;;;;;;:::i;:::-;;;;;;;;42184:144;42114:225;41927:419;:::o;82690:445::-;82780:2;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;82795:13:::1;82811:24;82827:7;82811:15;:24::i;:::-;82795:40;;82860:5;82854:11;;:2;:11;;::::0;82846:58:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;82955:5;82939:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;82964:37;82981:5;82988:12;:10;:12::i;:::-;82964:16;:37::i;:::-;82939:62;82917:169;;;;;;;;;;;;:::i;:::-;;;;;;;;;83099:28;83108:2;83112:7;83121:5;83099:8;:28::i;:::-;82784:351;82690:445:::0;;;:::o;83871:195::-;84014:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;84030:28:::1;84040:4;84046:2;84050:7;84030:9;:28::i;:::-;83871:195:::0;;;;:::o;90465:132::-;90540:12;:10;:12::i;:::-;90529:23;;:7;:5;:7::i;:::-;:23;;;90521:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;90465:132::o;84074:211::-;84221:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;84238:39:::1;84255:4;84261:2;84265:7;84238:39;;;;;;;;;;;::::0;:16:::1;:39::i;:::-;84074:211:::0;;;;:::o;81346:537::-;81407:21;;:::i;:::-;81449:16;81457:7;81449;:16::i;:::-;81441:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;81555:12;81570:7;81555:22;;81550:245;81587:1;81579:4;:9;81550:245;;81617:31;81651:11;:17;81663:4;81651:17;;;;;;;;;;;81617:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81717:1;81691:28;;:9;:14;;;:28;;;81687:93;;81751:9;81744:16;;;;;;81687:93;81598:197;81590:6;;;;;;;;81550:245;;;;81818:57;;;;;;;;;;:::i;:::-;;;;;;;;81346:537;;;;:::o;91567:191::-;91641:16;91660:6;;;;;;;;;;;91641:25;;91686:8;91677:6;;:17;;;;;;;;;;;;;;;;;;91741:8;91710:40;;91731:8;91710:40;;;;;;;;;;;;91630:128;91567:191;:::o;84808:104::-;84877:27;84887:2;84891:8;84877:27;;;;;;;;;;;;:9;:27::i;:::-;84808:104;;:::o;83365:326::-;83469:8;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;83510:12:::1;:10;:12::i;:::-;83498:24;;:8;:24;;::::0;83490:63:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;83611:8;83566:18;:32;83585:12;:10;:12::i;:::-;83566:32;;;;;;;;;;;;;;;:42;83599:8;83566:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;83664:8;83635:48;;83650:12;:10;:12::i;:::-;83635:48;;;83674:8;83635:48;;;;;;:::i;:::-;;;;;;;;83365:326:::0;;;:::o;84293:388::-;84469:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;84485:28:::1;84495:4;84501:2;84505:7;84485:9;:28::i;:::-;84546:48;84569:4;84575:2;84579:7;84588:5;84546:22;:48::i;:::-;84524:149;;;;;;;;;;;;:::i;:::-;;;;;;;;;84293:388:::0;;;;;:::o;101876:108::-;101936:13;101969:7;101962:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101876:108;:::o;56132:716::-;56188:13;56239:14;56276:1;56256:17;56267:5;56256:10;:17::i;:::-;:21;56239:38;;56292:20;56326:6;56315:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56292:41;;56348:11;56477:6;56473:2;56469:15;56461:6;56457:28;56450:35;;56514:288;56521:4;56514:288;;;56546:5;;;;;;;;56688:8;56683:2;56676:5;56672:14;56667:30;56662:3;56654:44;56744:2;56735:11;;;;;;:::i;:::-;;;;;56778:1;56769:5;:10;56514:288;56765:21;56514:288;56823:6;56816:13;;;;;56132:716;;;:::o;77908:98::-;77961:7;77988:10;77981:17;;77908:98;:::o;87873:196::-;88015:2;87988:15;:24;88004:7;87988:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;88053:7;88049:2;88033:28;;88042:5;88033:28;;;;;;;;;;;;87873:196;;;:::o;86398:1467::-;86513:35;86551:20;86563:7;86551:11;:20::i;:::-;86513:58;;86584:22;86626:13;:18;;;86610:34;;:12;:10;:12::i;:::-;:34;;;:87;;;;86685:12;:10;:12::i;:::-;86661:36;;:20;86673:7;86661:11;:20::i;:::-;:36;;;86610:87;:154;;;;86714:50;86731:13;:18;;;86751:12;:10;:12::i;:::-;86714:16;:50::i;:::-;86610:154;86584:181;;86786:17;86778:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;86901:4;86879:26;;:13;:18;;;:26;;;86871:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;86981:1;86967:16;;:2;:16;;;86959:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;87038:43;87060:4;87066:2;87070:7;87079:1;87038:21;:43::i;:::-;87094:49;87111:1;87115:7;87124:13;:18;;;87094:8;:49::i;:::-;87221:1;87191:12;:18;87204:4;87191:18;;;;;;;;;;;;;;;:26;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87265:1;87237:12;:16;87250:2;87237:16;;;;;;;;;;;;;;;:24;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87311:2;87283:11;:20;87295:7;87283:20;;;;;;;;;;;:25;;;:30;;;;;;;;;;;;;;;;;;87373:15;87328:11;:20;87340:7;87328:20;;;;;;;;;;;:35;;;:61;;;;;;;;;;;;;;;;;;87406:19;87438:1;87428:7;:11;87406:33;;87499:1;87458:43;;:11;:24;87470:11;87458:24;;;;;;;;;;;:29;;;;;;;;;;;;:43;;;87454:295;;87526:20;87534:11;87526:7;:20::i;:::-;87522:212;;;87603:13;:18;;;87571:11;:24;87583:11;87571:24;;;;;;;;;;;:29;;;:50;;;;;;;;;;;;;;;;;;87686:13;:28;;;87644:11;:24;87656:11;87644:24;;;;;;;;;;;:39;;;:70;;;;;;;;;;;;;;;;;;87522:212;87454:295;87166:594;87796:7;87792:2;87777:27;;87786:4;87777:27;;;;;;;;;;;;87815:42;87836:4;87842:2;87846:7;87855:1;87815:20;:42::i;:::-;86502:1363;;86398:1467;;;:::o;84920:163::-;85043:32;85049:2;85053:8;85063:5;85070:4;85043:5;:32::i;:::-;84920:163;;;:::o;88077:804::-;88232:4;88253:15;:2;:13;;;:15::i;:::-;88249:625;;;88305:2;88289:36;;;88326:12;:10;:12::i;:::-;88340:4;88346:7;88355:5;88289:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;88285:534;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88552:1;88535:6;:13;:18;88531:273;;88578:61;;;;;;;;;;:::i;:::-;;;;;;;;88531:273;88754:6;88748:13;88739:6;88735:2;88731:15;88724:38;88285:534;88422:45;;;88412:55;;;:6;:55;;;;88405:62;;;;;88249:625;88858:4;88851:11;;88077:804;;;;;;;:::o;52998:922::-;53051:7;53071:14;53088:1;53071:18;;53138:6;53129:5;:15;53125:102;;53174:6;53165:15;;;;;;:::i;:::-;;;;;53209:2;53199:12;;;;53125:102;53254:6;53245:5;:15;53241:102;;53290:6;53281:15;;;;;;:::i;:::-;;;;;53325:2;53315:12;;;;53241:102;53370:6;53361:5;:15;53357:102;;53406:6;53397:15;;;;;;:::i;:::-;;;;;53441:2;53431:12;;;;53357:102;53486:5;53477;:14;53473:99;;53521:5;53512:14;;;;;;:::i;:::-;;;;;53555:1;53545:11;;;;53473:99;53599:5;53590;:14;53586:99;;53634:5;53625:14;;;;;;:::i;:::-;;;;;53668:1;53658:11;;;;53586:99;53712:5;53703;:14;53699:99;;53747:5;53738:14;;;;;;:::i;:::-;;;;;53781:1;53771:11;;;;53699:99;53825:5;53816;:14;53812:66;;53861:1;53851:11;;;;53812:66;53906:6;53899:13;;;52998:922;;;:::o;88889:159::-;;;;;:::o;89056:158::-;;;;;:::o;85091:1298::-;85230:20;85253:12;;85230:35;;85298:1;85284:16;;:2;:16;;;85276:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;85369:1;85357:8;:13;85349:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;85428:61;85458:1;85462:2;85466:12;85480:8;85428:21;:61::i;:::-;85563:8;85527:12;:16;85540:2;85527:16;;;;;;;;;;;;;;;:24;;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85628:8;85587:12;:16;85600:2;85587:16;;;;;;;;;;;;;;;:29;;;:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85687:2;85654:11;:25;85666:12;85654:25;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;85754:15;85704:11;:25;85716:12;85704:25;;;;;;;;;;;:40;;;:66;;;;;;;;;;;;;;;;;;85787:20;85810:12;85787:35;;85844:9;85839:415;85859:8;85855:1;:12;85839:415;;;85923:12;85919:2;85898:38;;85915:1;85898:38;;;;;;;;;;;;85959:4;85955:249;;;86022:59;86053:1;86057:2;86061:12;86075:5;86022:22;:59::i;:::-;85988:196;;;;;;;;;;;;:::i;:::-;;;;;;;;;85955:249;86224:14;;;;;;;85869:3;;;;;;;85839:415;;;;86285:12;86270;:27;;;;85502:807;86321:60;86350:1;86354:2;86358:12;86372:8;86321:20;:60::i;:::-;85219:1170;85091:1298;;;;:::o;59259:326::-;59319:4;59576:1;59554:7;:19;;;:23;59547:30;;59259:326;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:118::-;4977:24;4995:5;4977:24;:::i;:::-;4972:3;4965:37;4890:118;;:::o;5014:222::-;5107:4;5145:2;5134:9;5130:18;5122:26;;5158:71;5226:1;5215:9;5211:17;5202:6;5158:71;:::i;:::-;5014:222;;;;:::o;5242:619::-;5319:6;5327;5335;5384:2;5372:9;5363:7;5359:23;5355:32;5352:119;;;5390:79;;:::i;:::-;5352:119;5510:1;5535:53;5580:7;5571:6;5560:9;5556:22;5535:53;:::i;:::-;5525:63;;5481:117;5637:2;5663:53;5708:7;5699:6;5688:9;5684:22;5663:53;:::i;:::-;5653:63;;5608:118;5765:2;5791:53;5836:7;5827:6;5816:9;5812:22;5791:53;:::i;:::-;5781:63;;5736:118;5242:619;;;;;:::o;5867:60::-;5895:3;5916:5;5909:12;;5867:60;;;:::o;5933:142::-;5983:9;6016:53;6034:34;6043:24;6061:5;6043:24;:::i;:::-;6034:34;:::i;:::-;6016:53;:::i;:::-;6003:66;;5933:142;;;:::o;6081:126::-;6131:9;6164:37;6195:5;6164:37;:::i;:::-;6151:50;;6081:126;;;:::o;6213:157::-;6294:9;6327:37;6358:5;6327:37;:::i;:::-;6314:50;;6213:157;;;:::o;6376:193::-;6494:68;6556:5;6494:68;:::i;:::-;6489:3;6482:81;6376:193;;:::o;6575:284::-;6699:4;6737:2;6726:9;6722:18;6714:26;;6750:102;6849:1;6838:9;6834:17;6825:6;6750:102;:::i;:::-;6575:284;;;;:::o;6865:329::-;6924:6;6973:2;6961:9;6952:7;6948:23;6944:32;6941:119;;;6979:79;;:::i;:::-;6941:119;7099:1;7124:53;7169:7;7160:6;7149:9;7145:22;7124:53;:::i;:::-;7114:63;;7070:117;6865:329;;;;:::o;7200:117::-;7309:1;7306;7299:12;7323:117;7432:1;7429;7422:12;7446:180;7494:77;7491:1;7484:88;7591:4;7588:1;7581:15;7615:4;7612:1;7605:15;7632:281;7715:27;7737:4;7715:27;:::i;:::-;7707:6;7703:40;7845:6;7833:10;7830:22;7809:18;7797:10;7794:34;7791:62;7788:88;;;7856:18;;:::i;:::-;7788:88;7896:10;7892:2;7885:22;7675:238;7632:281;;:::o;7919:129::-;7953:6;7980:20;;:::i;:::-;7970:30;;8009:33;8037:4;8029:6;8009:33;:::i;:::-;7919:129;;;:::o;8054:308::-;8116:4;8206:18;8198:6;8195:30;8192:56;;;8228:18;;:::i;:::-;8192:56;8266:29;8288:6;8266:29;:::i;:::-;8258:37;;8350:4;8344;8340:15;8332:23;;8054:308;;;:::o;8368:146::-;8465:6;8460:3;8455;8442:30;8506:1;8497:6;8492:3;8488:16;8481:27;8368:146;;;:::o;8520:425::-;8598:5;8623:66;8639:49;8681:6;8639:49;:::i;:::-;8623:66;:::i;:::-;8614:75;;8712:6;8705:5;8698:21;8750:4;8743:5;8739:16;8788:3;8779:6;8774:3;8770:16;8767:25;8764:112;;;8795:79;;:::i;:::-;8764:112;8885:54;8932:6;8927:3;8922;8885:54;:::i;:::-;8604:341;8520:425;;;;;:::o;8965:340::-;9021:5;9070:3;9063:4;9055:6;9051:17;9047:27;9037:122;;9078:79;;:::i;:::-;9037:122;9195:6;9182:20;9220:79;9295:3;9287:6;9280:4;9272:6;9268:17;9220:79;:::i;:::-;9211:88;;9027:278;8965:340;;;;:::o;9311:509::-;9380:6;9429:2;9417:9;9408:7;9404:23;9400:32;9397:119;;;9435:79;;:::i;:::-;9397:119;9583:1;9572:9;9568:17;9555:31;9613:18;9605:6;9602:30;9599:117;;;9635:79;;:::i;:::-;9599:117;9740:63;9795:7;9786:6;9775:9;9771:22;9740:63;:::i;:::-;9730:73;;9526:287;9311:509;;;;:::o;9826:116::-;9896:21;9911:5;9896:21;:::i;:::-;9889:5;9886:32;9876:60;;9932:1;9929;9922:12;9876:60;9826:116;:::o;9948:133::-;9991:5;10029:6;10016:20;10007:29;;10045:30;10069:5;10045:30;:::i;:::-;9948:133;;;;:::o;10087:468::-;10152:6;10160;10209:2;10197:9;10188:7;10184:23;10180:32;10177:119;;;10215:79;;:::i;:::-;10177:119;10335:1;10360:53;10405:7;10396:6;10385:9;10381:22;10360:53;:::i;:::-;10350:63;;10306:117;10462:2;10488:50;10530:7;10521:6;10510:9;10506:22;10488:50;:::i;:::-;10478:60;;10433:115;10087:468;;;;;:::o;10561:307::-;10622:4;10712:18;10704:6;10701:30;10698:56;;;10734:18;;:::i;:::-;10698:56;10772:29;10794:6;10772:29;:::i;:::-;10764:37;;10856:4;10850;10846:15;10838:23;;10561:307;;;:::o;10874:423::-;10951:5;10976:65;10992:48;11033:6;10992:48;:::i;:::-;10976:65;:::i;:::-;10967:74;;11064:6;11057:5;11050:21;11102:4;11095:5;11091:16;11140:3;11131:6;11126:3;11122:16;11119:25;11116:112;;;11147:79;;:::i;:::-;11116:112;11237:54;11284:6;11279:3;11274;11237:54;:::i;:::-;10957:340;10874:423;;;;;:::o;11316:338::-;11371:5;11420:3;11413:4;11405:6;11401:17;11397:27;11387:122;;11428:79;;:::i;:::-;11387:122;11545:6;11532:20;11570:78;11644:3;11636:6;11629:4;11621:6;11617:17;11570:78;:::i;:::-;11561:87;;11377:277;11316:338;;;;:::o;11660:943::-;11755:6;11763;11771;11779;11828:3;11816:9;11807:7;11803:23;11799:33;11796:120;;;11835:79;;:::i;:::-;11796:120;11955:1;11980:53;12025:7;12016:6;12005:9;12001:22;11980:53;:::i;:::-;11970:63;;11926:117;12082:2;12108:53;12153:7;12144:6;12133:9;12129:22;12108:53;:::i;:::-;12098:63;;12053:118;12210:2;12236:53;12281:7;12272:6;12261:9;12257:22;12236:53;:::i;:::-;12226:63;;12181:118;12366:2;12355:9;12351:18;12338:32;12397:18;12389:6;12386:30;12383:117;;;12419:79;;:::i;:::-;12383:117;12524:62;12578:7;12569:6;12558:9;12554:22;12524:62;:::i;:::-;12514:72;;12309:287;11660:943;;;;;;;:::o;12609:474::-;12677:6;12685;12734:2;12722:9;12713:7;12709:23;12705:32;12702:119;;;12740:79;;:::i;:::-;12702:119;12860:1;12885:53;12930:7;12921:6;12910:9;12906:22;12885:53;:::i;:::-;12875:63;;12831:117;12987:2;13013:53;13058:7;13049:6;13038:9;13034:22;13013:53;:::i;:::-;13003:63;;12958:118;12609:474;;;;;:::o;13089:180::-;13137:77;13134:1;13127:88;13234:4;13231:1;13224:15;13258:4;13255:1;13248:15;13275:320;13319:6;13356:1;13350:4;13346:12;13336:22;;13403:1;13397:4;13393:12;13424:18;13414:81;;13480:4;13472:6;13468:17;13458:27;;13414:81;13542:2;13534:6;13531:14;13511:18;13508:38;13505:84;;13561:18;;:::i;:::-;13505:84;13326:269;13275:320;;;:::o;13601:232::-;13741:34;13737:1;13729:6;13725:14;13718:58;13810:15;13805:2;13797:6;13793:15;13786:40;13601:232;:::o;13839:366::-;13981:3;14002:67;14066:2;14061:3;14002:67;:::i;:::-;13995:74;;14078:93;14167:3;14078:93;:::i;:::-;14196:2;14191:3;14187:12;14180:19;;13839:366;;;:::o;14211:419::-;14377:4;14415:2;14404:9;14400:18;14392:26;;14464:9;14458:4;14454:20;14450:1;14439:9;14435:17;14428:47;14492:131;14618:4;14492:131;:::i;:::-;14484:139;;14211:419;;;:::o;14636:221::-;14776:34;14772:1;14764:6;14760:14;14753:58;14845:4;14840:2;14832:6;14828:15;14821:29;14636:221;:::o;14863:366::-;15005:3;15026:67;15090:2;15085:3;15026:67;:::i;:::-;15019:74;;15102:93;15191:3;15102:93;:::i;:::-;15220:2;15215:3;15211:12;15204:19;;14863:366;;;:::o;15235:419::-;15401:4;15439:2;15428:9;15424:18;15416:26;;15488:9;15482:4;15478:20;15474:1;15463:9;15459:17;15452:47;15516:131;15642:4;15516:131;:::i;:::-;15508:139;;15235:419;;;:::o;15660:233::-;15800:34;15796:1;15788:6;15784:14;15777:58;15869:16;15864:2;15856:6;15852:15;15845:41;15660:233;:::o;15899:366::-;16041:3;16062:67;16126:2;16121:3;16062:67;:::i;:::-;16055:74;;16138:93;16227:3;16138:93;:::i;:::-;16256:2;16251:3;16247:12;16240:19;;15899:366;;;:::o;16271:419::-;16437:4;16475:2;16464:9;16460:18;16452:26;;16524:9;16518:4;16514:20;16510:1;16499:9;16495:17;16488:47;16552:131;16678:4;16552:131;:::i;:::-;16544:139;;16271:419;;;:::o;16696:181::-;16836:33;16832:1;16824:6;16820:14;16813:57;16696:181;:::o;16883:366::-;17025:3;17046:67;17110:2;17105:3;17046:67;:::i;:::-;17039:74;;17122:93;17211:3;17122:93;:::i;:::-;17240:2;17235:3;17231:12;17224:19;;16883:366;;;:::o;17255:419::-;17421:4;17459:2;17448:9;17444:18;17436:26;;17508:9;17502:4;17498:20;17494:1;17483:9;17479:17;17472:47;17536:131;17662:4;17536:131;:::i;:::-;17528:139;;17255:419;;;:::o;17680:147::-;17781:11;17818:3;17803:18;;17680:147;;;;:::o;17833:114::-;;:::o;17953:398::-;18112:3;18133:83;18214:1;18209:3;18133:83;:::i;:::-;18126:90;;18225:93;18314:3;18225:93;:::i;:::-;18343:1;18338:3;18334:11;18327:18;;17953:398;;;:::o;18357:379::-;18541:3;18563:147;18706:3;18563:147;:::i;:::-;18556:154;;18727:3;18720:10;;18357:379;;;:::o;18742:166::-;18882:18;18878:1;18870:6;18866:14;18859:42;18742:166;:::o;18914:366::-;19056:3;19077:67;19141:2;19136:3;19077:67;:::i;:::-;19070:74;;19153:93;19242:3;19153:93;:::i;:::-;19271:2;19266:3;19262:12;19255:19;;18914:366;;;:::o;19286:419::-;19452:4;19490:2;19479:9;19475:18;19467:26;;19539:9;19533:4;19529:20;19525:1;19514:9;19510:17;19503:47;19567:131;19693:4;19567:131;:::i;:::-;19559:139;;19286:419;;;:::o;19711:222::-;19851:34;19847:1;19839:6;19835:14;19828:58;19920:5;19915:2;19907:6;19903:15;19896:30;19711:222;:::o;19939:366::-;20081:3;20102:67;20166:2;20161:3;20102:67;:::i;:::-;20095:74;;20178:93;20267:3;20178:93;:::i;:::-;20296:2;20291:3;20287:12;20280:19;;19939:366;;;:::o;20311:419::-;20477:4;20515:2;20504:9;20500:18;20492:26;;20564:9;20558:4;20554:20;20550:1;20539:9;20535:17;20528:47;20592:131;20718:4;20592:131;:::i;:::-;20584:139;;20311:419;;;:::o;20736:230::-;20876:34;20872:1;20864:6;20860:14;20853:58;20945:13;20940:2;20932:6;20928:15;20921:38;20736:230;:::o;20972:366::-;21114:3;21135:67;21199:2;21194:3;21135:67;:::i;:::-;21128:74;;21211:93;21300:3;21211:93;:::i;:::-;21329:2;21324:3;21320:12;21313:19;;20972:366;;;:::o;21344:419::-;21510:4;21548:2;21537:9;21533:18;21525:26;;21597:9;21591:4;21587:20;21583:1;21572:9;21568:17;21561:47;21625:131;21751:4;21625:131;:::i;:::-;21617:139;;21344:419;;;:::o;21769:180::-;21817:77;21814:1;21807:88;21914:4;21911:1;21904:15;21938:4;21935:1;21928:15;21955:191;21995:3;22014:20;22032:1;22014:20;:::i;:::-;22009:25;;22048:20;22066:1;22048:20;:::i;:::-;22043:25;;22091:1;22088;22084:9;22077:16;;22112:3;22109:1;22106:10;22103:36;;;22119:18;;:::i;:::-;22103:36;21955:191;;;;:::o;22152:177::-;22292:29;22288:1;22280:6;22276:14;22269:53;22152:177;:::o;22335:366::-;22477:3;22498:67;22562:2;22557:3;22498:67;:::i;:::-;22491:74;;22574:93;22663:3;22574:93;:::i;:::-;22692:2;22687:3;22683:12;22676:19;;22335:366;;;:::o;22707:419::-;22873:4;22911:2;22900:9;22896:18;22888:26;;22960:9;22954:4;22950:20;22946:1;22935:9;22931:17;22924:47;22988:131;23114:4;22988:131;:::i;:::-;22980:139;;22707:419;;;:::o;23132:172::-;23272:24;23268:1;23260:6;23256:14;23249:48;23132:172;:::o;23310:366::-;23452:3;23473:67;23537:2;23532:3;23473:67;:::i;:::-;23466:74;;23549:93;23638:3;23549:93;:::i;:::-;23667:2;23662:3;23658:12;23651:19;;23310:366;;;:::o;23682:419::-;23848:4;23886:2;23875:9;23871:18;23863:26;;23935:9;23929:4;23925:20;23921:1;23910:9;23906:17;23899:47;23963:131;24089:4;23963:131;:::i;:::-;23955:139;;23682:419;;;:::o;24107:194::-;24147:4;24167:20;24185:1;24167:20;:::i;:::-;24162:25;;24201:20;24219:1;24201:20;:::i;:::-;24196:25;;24245:1;24242;24238:9;24230:17;;24269:1;24263:4;24260:11;24257:37;;;24274:18;;:::i;:::-;24257:37;24107:194;;;;:::o;24307:162::-;24447:14;24443:1;24435:6;24431:14;24424:38;24307:162;:::o;24475:366::-;24617:3;24638:67;24702:2;24697:3;24638:67;:::i;:::-;24631:74;;24714:93;24803:3;24714:93;:::i;:::-;24832:2;24827:3;24823:12;24816:19;;24475:366;;;:::o;24847:419::-;25013:4;25051:2;25040:9;25036:18;25028:26;;25100:9;25094:4;25090:20;25086:1;25075:9;25071:17;25064:47;25128:131;25254:4;25128:131;:::i;:::-;25120:139;;24847:419;;;:::o;25272:410::-;25312:7;25335:20;25353:1;25335:20;:::i;:::-;25330:25;;25369:20;25387:1;25369:20;:::i;:::-;25364:25;;25424:1;25421;25417:9;25446:30;25464:11;25446:30;:::i;:::-;25435:41;;25625:1;25616:7;25612:15;25609:1;25606:22;25586:1;25579:9;25559:83;25536:139;;25655:18;;:::i;:::-;25536:139;25320:362;25272:410;;;;:::o;25688:168::-;25828:20;25824:1;25816:6;25812:14;25805:44;25688:168;:::o;25862:366::-;26004:3;26025:67;26089:2;26084:3;26025:67;:::i;:::-;26018:74;;26101:93;26190:3;26101:93;:::i;:::-;26219:2;26214:3;26210:12;26203:19;;25862:366;;;:::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:164::-;26799:16;26795:1;26787:6;26783:14;26776:40;26659:164;:::o;26829:366::-;26971:3;26992:67;27056:2;27051:3;26992:67;:::i;:::-;26985:74;;27068:93;27157:3;27068:93;:::i;:::-;27186:2;27181:3;27177:12;27170:19;;26829:366;;;:::o;27201:419::-;27367:4;27405:2;27394:9;27390:18;27382:26;;27454:9;27448:4;27444:20;27440:1;27429:9;27425:17;27418:47;27482:131;27608:4;27482:131;:::i;:::-;27474:139;;27201:419;;;:::o;27626:169::-;27766:21;27762:1;27754:6;27750:14;27743:45;27626:169;:::o;27801:366::-;27943:3;27964:67;28028:2;28023:3;27964:67;:::i;:::-;27957:74;;28040:93;28129:3;28040:93;:::i;:::-;28158:2;28153:3;28149:12;28142:19;;27801:366;;;:::o;28173:419::-;28339:4;28377:2;28366:9;28362:18;28354:26;;28426:9;28420:4;28416:20;28412:1;28401:9;28397:17;28390:47;28454:131;28580:4;28454:131;:::i;:::-;28446:139;;28173:419;;;:::o;28598:141::-;28647:4;28670:3;28662:11;;28693:3;28690:1;28683:14;28727:4;28724:1;28714:18;28706:26;;28598:141;;;:::o;28745:93::-;28782:6;28829:2;28824;28817:5;28813:14;28809:23;28799:33;;28745:93;;;:::o;28844:107::-;28888:8;28938:5;28932:4;28928:16;28907:37;;28844:107;;;;:::o;28957:393::-;29026:6;29076:1;29064:10;29060:18;29099:97;29129:66;29118:9;29099:97;:::i;:::-;29217:39;29247:8;29236:9;29217:39;:::i;:::-;29205:51;;29289:4;29285:9;29278:5;29274:21;29265:30;;29338:4;29328:8;29324:19;29317:5;29314:30;29304:40;;29033:317;;28957:393;;;;;:::o;29356:142::-;29406:9;29439:53;29457:34;29466:24;29484:5;29466:24;:::i;:::-;29457:34;:::i;:::-;29439:53;:::i;:::-;29426:66;;29356:142;;;:::o;29504:75::-;29547:3;29568:5;29561:12;;29504:75;;;:::o;29585:269::-;29695:39;29726:7;29695:39;:::i;:::-;29756:91;29805:41;29829:16;29805:41;:::i;:::-;29797:6;29790:4;29784:11;29756:91;:::i;:::-;29750:4;29743:105;29661:193;29585:269;;;:::o;29860:73::-;29905:3;29860:73;:::o;29939:189::-;30016:32;;:::i;:::-;30057:65;30115:6;30107;30101:4;30057:65;:::i;:::-;29992:136;29939:189;;:::o;30134:186::-;30194:120;30211:3;30204:5;30201:14;30194:120;;;30265:39;30302:1;30295:5;30265:39;:::i;:::-;30238:1;30231:5;30227:13;30218:22;;30194:120;;;30134:186;;:::o;30326:543::-;30427:2;30422:3;30419:11;30416:446;;;30461:38;30493:5;30461:38;:::i;:::-;30545:29;30563:10;30545:29;:::i;:::-;30535:8;30531:44;30728:2;30716:10;30713:18;30710:49;;;30749:8;30734:23;;30710:49;30772:80;30828:22;30846:3;30828:22;:::i;:::-;30818:8;30814:37;30801:11;30772:80;:::i;:::-;30431:431;;30416:446;30326:543;;;:::o;30875:117::-;30929:8;30979:5;30973:4;30969:16;30948:37;;30875:117;;;;:::o;30998:169::-;31042:6;31075:51;31123:1;31119:6;31111:5;31108:1;31104:13;31075:51;:::i;:::-;31071:56;31156:4;31150;31146:15;31136:25;;31049:118;30998:169;;;;:::o;31172:295::-;31248:4;31394:29;31419:3;31413:4;31394:29;:::i;:::-;31386:37;;31456:3;31453:1;31449:11;31443:4;31440:21;31432:29;;31172:295;;;;:::o;31472:1395::-;31589:37;31622:3;31589:37;:::i;:::-;31691:18;31683:6;31680:30;31677:56;;;31713:18;;:::i;:::-;31677:56;31757:38;31789:4;31783:11;31757:38;:::i;:::-;31842:67;31902:6;31894;31888:4;31842:67;:::i;:::-;31936:1;31960:4;31947:17;;31992:2;31984:6;31981:14;32009:1;32004:618;;;;32666:1;32683:6;32680:77;;;32732:9;32727:3;32723:19;32717:26;32708:35;;32680:77;32783:67;32843:6;32836:5;32783:67;:::i;:::-;32777:4;32770:81;32639:222;31974:887;;32004:618;32056:4;32052:9;32044:6;32040:22;32090:37;32122:4;32090:37;:::i;:::-;32149:1;32163:208;32177:7;32174:1;32171:14;32163:208;;;32256:9;32251:3;32247:19;32241:26;32233:6;32226:42;32307:1;32299:6;32295:14;32285:24;;32354:2;32343:9;32339:18;32326:31;;32200:4;32197:1;32193:12;32188:17;;32163:208;;;32399:6;32390:7;32387:19;32384:179;;;32457:9;32452:3;32448:19;32442:26;32500:48;32542:4;32534:6;32530:17;32519:9;32500:48;:::i;:::-;32492:6;32485:64;32407:156;32384:179;32609:1;32605;32597:6;32593:14;32589:22;32583:4;32576:36;32011:611;;;31974:887;;31564:1303;;;31472:1395;;:::o;32873:234::-;33013:34;33009:1;33001:6;32997:14;32990:58;33082:17;33077:2;33069:6;33065:15;33058:42;32873:234;:::o;33113:366::-;33255:3;33276:67;33340:2;33335:3;33276:67;:::i;:::-;33269:74;;33352:93;33441:3;33352:93;:::i;:::-;33470:2;33465:3;33461:12;33454:19;;33113:366;;;:::o;33485:419::-;33651:4;33689:2;33678:9;33674:18;33666:26;;33738:9;33732:4;33728:20;33724:1;33713:9;33709:17;33702:47;33766:131;33892:4;33766:131;:::i;:::-;33758:139;;33485:419;;;:::o;33910:148::-;34012:11;34049:3;34034:18;;33910:148;;;;:::o;34064:390::-;34170:3;34198:39;34231:5;34198:39;:::i;:::-;34253:89;34335:6;34330:3;34253:89;:::i;:::-;34246:96;;34351:65;34409:6;34404:3;34397:4;34390:5;34386:16;34351:65;:::i;:::-;34441:6;34436:3;34432:16;34425:23;;34174:280;34064:390;;;;:::o;34460:155::-;34600:7;34596:1;34588:6;34584:14;34577:31;34460:155;:::o;34621:400::-;34781:3;34802:84;34884:1;34879:3;34802:84;:::i;:::-;34795:91;;34895:93;34984:3;34895:93;:::i;:::-;35013:1;35008:3;35004:11;34997:18;;34621:400;;;:::o;35027:701::-;35308:3;35330:95;35421:3;35412:6;35330:95;:::i;:::-;35323:102;;35442:95;35533:3;35524:6;35442:95;:::i;:::-;35435:102;;35554:148;35698:3;35554:148;:::i;:::-;35547:155;;35719:3;35712:10;;35027:701;;;;;:::o;35734:225::-;35874:34;35870:1;35862:6;35858:14;35851:58;35943:8;35938:2;35930:6;35926:15;35919:33;35734:225;:::o;35965:366::-;36107:3;36128:67;36192:2;36187:3;36128:67;:::i;:::-;36121:74;;36204:93;36293:3;36204:93;:::i;:::-;36322:2;36317:3;36313:12;36306:19;;35965:366;;;:::o;36337:419::-;36503:4;36541:2;36530:9;36526:18;36518:26;;36590:9;36584:4;36580:20;36576:1;36565:9;36561:17;36554:47;36618:131;36744:4;36618:131;:::i;:::-;36610:139;;36337:419;;;:::o;36762:332::-;36883:4;36921:2;36910:9;36906:18;36898:26;;36934:71;37002:1;36991:9;36987:17;36978:6;36934:71;:::i;:::-;37015:72;37083:2;37072:9;37068:18;37059:6;37015:72;:::i;:::-;36762:332;;;;;:::o;37100:137::-;37154:5;37185:6;37179:13;37170:22;;37201:30;37225:5;37201:30;:::i;:::-;37100:137;;;;:::o;37243:345::-;37310:6;37359:2;37347:9;37338:7;37334:23;37330:32;37327:119;;;37365:79;;:::i;:::-;37327:119;37485:1;37510:61;37563:7;37554:6;37543:9;37539:22;37510:61;:::i;:::-;37500:71;;37456:125;37243:345;;;;:::o;37594:221::-;37734:34;37730:1;37722:6;37718:14;37711:58;37803:4;37798:2;37790:6;37786:15;37779:29;37594:221;:::o;37821:366::-;37963:3;37984:67;38048:2;38043:3;37984:67;:::i;:::-;37977:74;;38060:93;38149:3;38060:93;:::i;:::-;38178:2;38173:3;38169:12;38162:19;;37821:366;;;:::o;38193:419::-;38359:4;38397:2;38386:9;38382:18;38374:26;;38446:9;38440:4;38436:20;38432:1;38421:9;38417:17;38410:47;38474:131;38600:4;38474:131;:::i;:::-;38466:139;;38193:419;;;:::o;38618:244::-;38758:34;38754:1;38746:6;38742:14;38735:58;38827:27;38822:2;38814:6;38810:15;38803:52;38618:244;:::o;38868:366::-;39010:3;39031:67;39095:2;39090:3;39031:67;:::i;:::-;39024:74;;39107:93;39196:3;39107:93;:::i;:::-;39225:2;39220:3;39216:12;39209:19;;38868:366;;;:::o;39240:419::-;39406:4;39444:2;39433:9;39429:18;39421:26;;39493:9;39487:4;39483:20;39479:1;39468:9;39464:17;39457:47;39521:131;39647:4;39521:131;:::i;:::-;39513:139;;39240:419;;;:::o;39665:182::-;39805:34;39801:1;39793:6;39789:14;39782:58;39665:182;:::o;39853:366::-;39995:3;40016:67;40080:2;40075:3;40016:67;:::i;:::-;40009:74;;40092:93;40181:3;40092:93;:::i;:::-;40210:2;40205:3;40201:12;40194:19;;39853:366;;;:::o;40225:419::-;40391:4;40429:2;40418:9;40414:18;40406:26;;40478:9;40472:4;40468:20;40464:1;40453:9;40449:17;40442:47;40506:131;40632:4;40506:131;:::i;:::-;40498:139;;40225:419;;;:::o;40650:229::-;40790:34;40786:1;40778:6;40774:14;40767:58;40859:12;40854:2;40846:6;40842:15;40835:37;40650:229;:::o;40885:366::-;41027:3;41048:67;41112:2;41107:3;41048:67;:::i;:::-;41041:74;;41124:93;41213:3;41124:93;:::i;:::-;41242:2;41237:3;41233:12;41226:19;;40885:366;;;:::o;41257:419::-;41423:4;41461:2;41450:9;41446:18;41438:26;;41510:9;41504:4;41500:20;41496:1;41485:9;41481:17;41474:47;41538:131;41664:4;41538:131;:::i;:::-;41530:139;;41257:419;;;:::o;41682:234::-;41822:34;41818:1;41810:6;41806:14;41799:58;41891:17;41886:2;41878:6;41874:15;41867:42;41682:234;:::o;41922:366::-;42064:3;42085:67;42149:2;42144:3;42085:67;:::i;:::-;42078:74;;42161:93;42250:3;42161:93;:::i;:::-;42279:2;42274:3;42270:12;42263:19;;41922:366;;;:::o;42294:419::-;42460:4;42498:2;42487:9;42483:18;42475:26;;42547:9;42541:4;42537:20;42533:1;42522:9;42518:17;42511:47;42575:131;42701:4;42575:131;:::i;:::-;42567:139;;42294:419;;;:::o;42719:176::-;42859:28;42855:1;42847:6;42843:14;42836:52;42719:176;:::o;42901:366::-;43043:3;43064:67;43128:2;43123:3;43064:67;:::i;:::-;43057:74;;43140:93;43229:3;43140:93;:::i;:::-;43258:2;43253:3;43249:12;43242:19;;42901:366;;;:::o;43273:419::-;43439:4;43477:2;43466:9;43462:18;43454:26;;43526:9;43520:4;43516:20;43512:1;43501:9;43497:17;43490:47;43554:131;43680:4;43554:131;:::i;:::-;43546:139;;43273:419;;;:::o;43698:238::-;43838:34;43834:1;43826:6;43822:14;43815:58;43907:21;43902:2;43894:6;43890:15;43883:46;43698:238;:::o;43942:366::-;44084:3;44105:67;44169:2;44164:3;44105:67;:::i;:::-;44098:74;;44181:93;44270:3;44181:93;:::i;:::-;44299:2;44294:3;44290:12;44283:19;;43942:366;;;:::o;44314:419::-;44480:4;44518:2;44507:9;44503:18;44495:26;;44567:9;44561:4;44557:20;44553:1;44542:9;44538:17;44531:47;44595:131;44721:4;44595:131;:::i;:::-;44587:139;;44314:419;;;:::o;44739:180::-;44787:77;44784:1;44777:88;44884:4;44881:1;44874:15;44908:4;44905:1;44898:15;44925:237;45065:34;45061:1;45053:6;45049:14;45042:58;45134:20;45129:2;45121:6;45117:15;45110:45;44925:237;:::o;45168:366::-;45310:3;45331:67;45395:2;45390:3;45331:67;:::i;:::-;45324:74;;45407:93;45496:3;45407:93;:::i;:::-;45525:2;45520:3;45516:12;45509:19;;45168:366;;;:::o;45540:419::-;45706:4;45744:2;45733:9;45729:18;45721:26;;45793:9;45787:4;45783:20;45779:1;45768:9;45764:17;45757:47;45821:131;45947:4;45821:131;:::i;:::-;45813:139;;45540:419;;;:::o;45965:225::-;46105:34;46101:1;46093:6;46089:14;46082:58;46174:8;46169:2;46161:6;46157:15;46150:33;45965:225;:::o;46196:366::-;46338:3;46359:67;46423:2;46418:3;46359:67;:::i;:::-;46352:74;;46435:93;46524:3;46435:93;:::i;:::-;46553:2;46548:3;46544:12;46537:19;;46196:366;;;:::o;46568:419::-;46734:4;46772:2;46761:9;46757:18;46749:26;;46821:9;46815:4;46811:20;46807:1;46796:9;46792:17;46785:47;46849:131;46975:4;46849:131;:::i;:::-;46841:139;;46568:419;;;:::o;46993:224::-;47133:34;47129:1;47121:6;47117:14;47110:58;47202:7;47197:2;47189:6;47185:15;47178:32;46993:224;:::o;47223:366::-;47365:3;47386:67;47450:2;47445:3;47386:67;:::i;:::-;47379:74;;47462:93;47551:3;47462:93;:::i;:::-;47580:2;47575:3;47571:12;47564:19;;47223:366;;;:::o;47595:419::-;47761:4;47799:2;47788:9;47784:18;47776:26;;47848:9;47842:4;47838:20;47834:1;47823:9;47819:17;47812:47;47876:131;48002:4;47876:131;:::i;:::-;47868:139;;47595:419;;;:::o;48020:98::-;48071:6;48105:5;48099:12;48089:22;;48020:98;;;:::o;48124:168::-;48207:11;48241:6;48236:3;48229:19;48281:4;48276:3;48272:14;48257:29;;48124:168;;;;:::o;48298:373::-;48384:3;48412:38;48444:5;48412:38;:::i;:::-;48466:70;48529:6;48524:3;48466:70;:::i;:::-;48459:77;;48545:65;48603:6;48598:3;48591:4;48584:5;48580:16;48545:65;:::i;:::-;48635:29;48657:6;48635:29;:::i;:::-;48630:3;48626:39;48619:46;;48388:283;48298:373;;;;:::o;48677:640::-;48872:4;48910:3;48899:9;48895:19;48887:27;;48924:71;48992:1;48981:9;48977:17;48968:6;48924:71;:::i;:::-;49005:72;49073:2;49062:9;49058:18;49049:6;49005:72;:::i;:::-;49087;49155:2;49144:9;49140:18;49131:6;49087:72;:::i;:::-;49206:9;49200:4;49196:20;49191:2;49180:9;49176:18;49169:48;49234:76;49305:4;49296:6;49234:76;:::i;:::-;49226:84;;48677:640;;;;;;;:::o;49323:141::-;49379:5;49410:6;49404:13;49395:22;;49426:32;49452:5;49426:32;:::i;:::-;49323:141;;;;:::o;49470:349::-;49539:6;49588:2;49576:9;49567:7;49563:23;49559:32;49556:119;;;49594:79;;:::i;:::-;49556:119;49714:1;49739:63;49794:7;49785:6;49774:9;49770:22;49739:63;:::i;:::-;49729:73;;49685:127;49470:349;;;;:::o;49825:220::-;49965:34;49961:1;49953:6;49949:14;49942:58;50034:3;50029:2;50021:6;50017:15;50010:28;49825:220;:::o;50051:366::-;50193:3;50214:67;50278:2;50273:3;50214:67;:::i;:::-;50207:74;;50290:93;50379:3;50290:93;:::i;:::-;50408:2;50403:3;50399:12;50392:19;;50051:366;;;:::o;50423:419::-;50589:4;50627:2;50616:9;50612:18;50604:26;;50676:9;50670:4;50666:20;50662:1;50651:9;50647:17;50640:47;50704:131;50830:4;50704:131;:::i;:::-;50696:139;;50423:419;;;:::o;50848:227::-;50988:34;50984:1;50976:6;50972:14;50965:58;51057:10;51052:2;51044:6;51040:15;51033:35;50848:227;:::o;51081:366::-;51223:3;51244:67;51308:2;51303:3;51244:67;:::i;:::-;51237:74;;51320:93;51409:3;51320:93;:::i;:::-;51438:2;51433:3;51429:12;51422:19;;51081:366;;;:::o;51453:419::-;51619:4;51657:2;51646:9;51642:18;51634:26;;51706:9;51700:4;51696:20;51692:1;51681:9;51677:17;51670:47;51734:131;51860:4;51734:131;:::i;:::-;51726:139;;51453:419;;;:::o
Swarm Source
ipfs://64144292b69dd7a2dec2b80ff458380abed66226cde58328f59154a2084dac15
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.